I am using this plugin https://github.com/akiran/react-slick for image slider but for some reason i am unable to achieve what I want.
Here is a sample code:
import React, { Component } from "react";
import Slider from "../src/slider";
import { baseUrl } from "./config";
export default class CenterMode extends Component {
render() {
const settings = {
customPaging: function(i) {
return (
<a>
<img src={`${baseUrl}/abstract0${i + 1}.jpg`} />
</a>
);
},
dots: true,
dotsClass: "slick-dots slick-thumb",
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1
};
return (
<div>
<h2>Custom Paging</h2>
<Slider {...settings}>
<div>
<img src={baseUrl + "/abstract01.jpg"} />
</div>
<div>
<img src={baseUrl + "/abstract02.jpg"} />
</div>
<div>
<img src={baseUrl + "/abstract03.jpg"} />
</div>
<div>
<img src={baseUrl + "/abstract04.jpg"} />
</div>
</Slider>
</div>
);
}
}
This works perfectly fine unless the image file names are like abstract01, abstract02, in my case image file name is random it can be anything, thus the thumbnail part does not work for me. Are there any option that I can pass some other argument on the customPaging so that i can receive src attr and can get the file name from there.
Any idea would be much appreciated here.
Note: the images in my case are coming from amazon s3, so I have no control over them at all!
I believe you can do something like this:
const images = [
{ src: baseUrl + "/abstract01.jpg" },
{ src: baseUrl + "/abstract02.jpg" },
{ src: baseUrl + "/abstract03.jpg" },
{ src: baseUrl + "/abstract04.jpg" },
];
export default class App extends Component {
render() {
const settings = {
customPaging: function (i) {
return (
<a>
<img src={images[i].src} />
</a>
);
},
dots: true,
dotsClass: "slick-dots slick-thumb",
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1
};
return (
<div>
<h2>Custom Paging</h2>
<Slider {...settings}>
{images.map((img) => (
<div>
<img src={img.src} />
</div>
))}
</Slider>
</div>
);
}
}
Basically you can create the image array (because you already know the images) and then map through it to get the slides and use the iterator in custom paging to get the image by index from your array.
Related
I implemented react slick slider and I am getting the images by applying map on array of imageArray data. From the key I get , I have to call url as image src to get the image. I am getting images but the carousel is not obeying rules defined in settings due to dynamic fetching of images.
import Slider from "react-slick";
...
let settings = {
accessibility: false,
slidesToShow: 4.25,
slidesToScroll: 1,
arrows: true,
rows: 2,
lazyLoad: true,
dots: false,
variableWidth: true,
adaptiveHeight: false,
infinite: false,
}
...
<Slider {...settings}>
{imageArray.map(individualImage => {
if (individualImage.DESCRIPTION.toLowerCase().includes(selectedDescription.toLowerCase())) {
return <img title={individualImage.DESCRIPTION} alt={individualImage.DESCRIPTION + ' image'} className={individualImage.KEY === imageSelected ? borderColor : 'image-default-border'} onClick={() => imgClick(field, individualImage.KEY, individualImage.DESCRIPTION)} src={`www/url.com/key=${individualImage.KEY}`} />
}
return true
})}
{imageArray.map(individualImage => {
if (individualImage.DESCRIPTION1.toLowerCase().includes(selectedDescription?.toLowerCase())) {
return <img title={individualImage.DESCRIPTION1} alt={individualImage.DESCRIPTION1 + ' image'} className={individualImage.KEY1 === imageSelected ? borderColor : 'image-default-border'} onClick={() => imgClick(field, individualImage.KEY1, individualImage.DESCRIPTION1)} src={`www/url.com/key=${individualImage.KEY1}`} />
}
return true
})}
</Slider>
I want to make image zoom in when hover and using this plugin react-image-magnifiers usually it's fine when i make without next.js but when i using next.js just showing image and when i try to hover my mouse to the image, and then zoom in not working, maybe there is any mistake in my next.config.js ?
This is my next.config.js
const withPlugins = require('next-compose-plugins');
const withCss = require('#zeit/next-css');
const withSass = require('#zeit/next-sass');
const withImages = require('next-images');
const nextSettings = {
exportTrailingSlash: true,
exportPathMap: function() {
return {
'/': { page: '/' },
};
},
};
module.exports = withPlugins([[withSass(withCss({
webpack: function (config) {
config.module.rules.push({
test: /\.(eot|woff|woff2|ttf|svg|png|jpg|gif)$/,
use: {
loader: 'url-loader',
options: {
limit: 100000,
name: '[name].[ext]'
}
}
})
return config
}
})), withImages()]]);
And this is my Gallery.jsx
import React from "react";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import { SideBySideMagnifier } from "react-image-magnifiers";
export default function GallerySide (props) {
const dataImage = props.product;
const [state, setState] = React.useState({
alwaysInPlace: false,
overlayOpacity: 0.6,
switchSides: false,
fillAvailableSpace: false,
fillAlignTop: false,
fillGapLeft: 0,
fillGapRight: 10,
fillGapTop: 10,
fillGapBottom: 10,
largeImage: dataImage[0].largeImage,
});
const {
alwaysInPlace,
overlayOpacity,
switchSides,
fillAvailableSpace,
fillAlignTop,
fillGapLeft,
fillGapRight,
fillGapTop,
fillGapBottom,
largeImage
} = state;
const ArrowLeft = (props) => (
<a href="#disabled" {...props} className="grist-prev">
<i className="fas fa-chevron-left"></i>
</a>
);
const ArrowRight = (props) => (
<a href="#disabled" {...props} className="grist-next">
<i className="fas fa-chevron-right"></i>
</a>
);
const settings = {
dots: false,
infinite: true,
speed: 500,
slidesToShow: 4,
slidesToScroll: 1,
prevArrow: <ArrowLeft />,
nextArrow: <ArrowRight />,
};
const ChangeSlider = (event) => {
setState({
alwaysInPlace: false,
overlayOpacity: 0.6,
switchSides: false,
fillAvailableSpace: false,
fillAlignTop: false,
fillGapLeft: 0,
fillGapRight: 10,
fillGapTop: 10,
fillGapBottom: 10,
largeImage: event,
});
}
return (
<>
<SideBySideMagnifier
className="grist-input-position"
style={{ order: switchSides ? "1" : "0" }}
imageSrc={largeImage}
largeImageSrc={largeImage}
alwaysInPlace={alwaysInPlace}
overlayOpacity={overlayOpacity}
switchSides={switchSides}
zoomPosition="left"
inPlaceMinBreakpoint={641}
fillAvailableSpace={fillAvailableSpace}
fillAlignTop={fillAlignTop}
fillGapTop={fillGapTop}
fillGapRight={fillGapRight}
fillGapBottom={fillGapBottom}
fillGapLeft={fillGapLeft}
zoomContainerBorder="1px solid #ccc"
cursorStyle="zoom-in"
/>
<div className="col-12 mt-2">
<div className="col-11 mx-auto">
<Slider {...settings}>
{dataImage.map((data, index) =>
<a href="#disabled" key={index} onClick={() => ChangeSlider(data.largeImage)}>
<div className="card m-2">
<div className="card-body p-0">
<img src={data.thumbImage} width="100%" alt="Grist" />
</div>
</div>
</a>
)}
</Slider>
</div>
</div>
</>
);
}
I hope there is a solution for this or another way to make like this.
UPDATE :
i solved the problem, it because i have scss call "typhography.scss" and make tag "img" max-width: 100%, because of that my image always set 100% of width, by disable or remove this line
img {
max-width: 100%;
}
it's work perfectly, thanks.
i solved the problem, it because i have scss call "typhography.scss" and make tag "img" max-width: 100%, because of that my image always set 100% of width, by disable or remove this line
img {
max-width: 100%;
}
it's work perfectly.
The right answer is the one marked as correct.
To disable in a general way use this css rule:
img {
max-width: unset !important;
}
I am in the process of making a recipe app and currently, I am building a component that displays a number of recipes (depending on how much I determine via API call) within a carousel slideshow which showcases the image of recipe, title, and other info. I tried using a Link tag for a recipe to go to its own unique route (/recipe/:id) but every time it goes to that route, it never passes in the current recipe's ID that's being displayed currently in the carousel. Thank you. Edit: upon closer examination, it seems like it's only getting the ID of the last recipe object within the recipes array of objects. Any help or ideas?
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css';
import Slider from 'react-slick';
import { faClock, faUser, faGlobe, faUtensils } from '#fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { Route, NavLink, Link } from 'react-router-dom';
import RecipeInfo from '../RecipeInfo';
const Slideshow = () => {
const settings = {
dots: true,
fade: true,
infinite: true,
slidesToShow: 1,
arrows: true,
slidesToScroll: 1,
className: 'slides',
autoplay: true,
speed: 2000,
autoplaySpeed: 3300,
centerPadding: '60px'
};
const [ recipes, setRecipes ] = useState([]);
const diets = [ 'Asian', 'Greek', 'American', 'Chinese' ];
const diet = diets[Math.floor(Math.random() * diets.length)];
useEffect(() => {
axios
.get(
'https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/search?number=20&offset=0&type=main%20course',
{
headers: {
'x-rapidapi-host': 'spoonacular-recipe-food-nutrition-v1.p.rapidapi.com',
'x-rapidapi-key': 'e7bb7cb790mshb2eb009f0d98772p1ec6e5jsnc524d12e4092'
},
params: {
diet: `${diet}`
}
}
)
.then((res) => {
setRecipes(res.data.results);
console.log(res.data.results);
})
.catch((err) => {
console.log(err);
});
}, []);
return (
<div>
<Slider {...settings}>
{recipes ? (
recipes.map((recipe) => {
return (
<div key={recipe.id}>
<div className="slides-container">
<img
className="recipe-image"
width="35%"
alt={recipe.title}
src={`https://spoonacular.com/recipeImages/${recipe.id}-636x393.jpg`}
/>
<div className="card-info">
{' '}
<Link to={`/recipe/${recipe.id}`} key={recipe.id}>
<h1>
{' '}
<FontAwesomeIcon icon={faUtensils} /> {recipe.title}
</h1>
</Link>
<p>Recipe Id: {recipe.id}</p>
<br />
<h3>
<FontAwesomeIcon icon={faClock} /> Ready In: {recipe.readyInMinutes} Minutes
</h3>
<br />
<h4>
<FontAwesomeIcon icon={faUser} /> Servings: {recipe.servings}
</h4>
<br />
<br />
<a href={recipe.sourceUrl} target="_blank" rel="noopener noreferrer">
<h5>
<FontAwesomeIcon icon={faGlobe} /> Recipe Link
</h5>
{/* {recipe.sourceUrl} */}
</a>
</div>
</div>
</div>
);
})
) : (
<p>Loading Recipes</p>
)}
</Slider>
</div>
);
};
export default Slideshow;
I'm getting data from the state. Now I want to make a carousel slider using react-multi-carousel
I am trying to implement https://www.npmjs.com/package/react-multi-carousel for a news card component that has data coming from the API. So far my code is as follows, but the carousel does not seem to be implementing?
Child Component
import Carousel from 'react-multi-carousel';
import 'react-multi-carousel/lib/styles.css'
const responsive = {
superLargeDesktop: {
breakpoint: { max: 4000, min: 3000 },
items: 5
},
desktop: {
breakpoint: { max: 3000, min: 1024 },
items: 3
},
tablet: {
breakpoint: { max: 1024, min: 464 },
items: 2
},
mobile: {
breakpoint: { max: 464, min: 0 },
items: 1
}
};
const size = 15;
const Itemlist = props.data.slice(0, size).map((item,id) => {
return(
<div className="item px-2 col-md-3" key={item.title}>
<div className="alith_latest_trading_img_position_relative">
<figure className="alith_post_thumb">
<Link
to={{
pathname : `/details/${id}`,
}}
>
<img
alt=""
src={item.multimedia ? item.multimedia[0].url : image}
className="w-100 thumbnail"
/>
</Link>
</figure>
<div className="alith_post_title_small">
<Link
to={{
pathname : `/details/${id}`,
}}
><strong>{item.title.length > 30 ? item.title.substring(0,30) + ".." : item.title}</strong>
</Link>
<p className="meta">
<span>{`${moment(item.published_date).fromNow()}`}</span>
</p>
</div>
</div>
</div>
)
})
return (
<React.Fragment>
<Carousel responsive={responsive}>
{Itemlist}
</Carousel>
</React.Fragment>
);
};
Parent Component
state = {
items : []
}
fetchLatestNews = () => {
api.getRealFeed()
.then(response=>{
this.setState({
items : response.data.results
});
})
}
componentDidMount = () => {
this.fetchLatestNews();
}
render(){
return(
<React.Fragment>
<Item data={this.state.items}/>
</React.Fragment>
)}};
I had the same issue,
Take a look at the specific props. You can add a class to the container, slide or item for adding your css rules. In my case, I had to define a width to the containerClass.
<Carousel
containerClass="carousel-container"
itemClass="carousel-item"
>
... // Your carousel here
And in your css file:
.carousel-container {
width: 100%;
...
}
I'm not sure if this will help, but I had an issue where the carousel becomes empty when I set the prop infinity to true.
Turns out it was because the website I'm working on uses bootstrap rtl.
To fix the issue I just changed the direction of the carousel container to be ltr.
Something like this:
[dir="rtl"] .carousel-container{
direction: ltr;
}
i fix it by adding width properties to the container class
if you using tailwind u need to can set the containerClass width
<Carousel
containerClass={`w-full`}
>
{item}
</Carousel>
I believe you should add import 'react-multi-carousel/lib/styles.css' to your top-level file NOT in the child component file. E.g: _app.tsx for NextJS. It took me about 30m to find out that.
This worked fine for me in functional component: I'm late but it can be usefull to anyone in future.
https://www.npmjs.com/package/react-multi-carousel
import React, { useState } from 'react';
import Carousel from "react-multi-carousel";
import "react-multi-carousel/lib/styles.css";
const SampleCode = props => {
const [maindata, setMaindata] = useState([{'name':"one"},
{'name':"two"}]);
const responsive = {
desktop: {
breakpoint: { max: 3000, min: 1024 },
items: 3,
slidesToSlide: 3 // optional, default to 1.
},
tablet: {
breakpoint: { max: 1024, min: 464 },
items: 2,
slidesToSlide: 2 // optional, default to 1.
},
mobile: {
breakpoint: { max: 464, min: 0 },
items: 1,
slidesToSlide: 1 // optional, default to 1.
}
};
return (
<div>
<Carousel
swipeable={false}
draggable={false}
showDots={true}
responsive={responsive}
ssr={false} // means to render carousel on server-side.
infinite={true}
autoPlay={false}
autoPlaySpeed={1000}
keyBoardControl={true}
customTransition="all .5"
transitionDuration={500}
containerClass="carousel-container"
// removeArrowOnDeviceType={["tablet", "mobile"]}
//deviceType={true}//{this.props.deviceType}
dotListClass="custom-dot-list-style"
itemClass="carousel-item-padding-40-px"
className='location-jobs '
>
{
maindata.map((each) => {
return (
<div className='item p-3 mx-3 d-flex'>
{each.name}
</div>
)
})
}
</Carousel>
</div>
);
}
export default SampleCode;
It is having width issues like I was too using in my project, I have to set the width by using media queries. I don't know why the developer hasn't fixed the issue, but you can try giving a default width in inspect section and then setting up the width by using media queries.
I'm trying to make a carousel with 'react-id-swiper' component with thumbs, but it seems that there is no connection between the main carousel and the carousel with thumbs.
I searched out all over the internet with no luck. Also scanned the documentation of "react-id-swiper" and all the reported issues at this component's github.
import React from "react";
import styles from "./Gallery.css";
import Swiper from "react-id-swiper";
import("react-id-swiper/src/styles/css/swiper.css");
import { Navigation } from "swiper/dist/js/swiper.esm";
import "../styles.css";
export default class Gallery extends React.Component {
constructor(props) {
super(props);
this.state = {
gallerySwiper: null,
thumbnailSwiper: null
};
}
componentWillUpdate(nextProps, nextState) {
if (nextState.gallerySwiper && nextState.thumbnailSwiper) {
const { gallerySwiper, thumbnailSwiper } = nextState;
gallerySwiper.controller.control = thumbnailSwiper;
thumbnailSwiper.controller.control = gallerySwiper;
}
}
galleryRef = ref => {
if (ref) this.setState({ gallerySwiper: ref.swiper });
};
thumbRef = ref => {
if (ref) this.setState({ thumbnailSwiper: ref.swiper });
};
render() {
const thumbnailSwiperParams = {
paceBetween: 10,
centeredSlides: true,
slidesPerView: "auto",
touchRatio: 0.2,
slideToClickedSlide: true,
onInit: swiper => {
this.swiper2 = swiper;
}
};
const params = {
modules: [Navigation],
slidesPerView: 1,
zoom: {
maxRatio: 5
},
spaceBetween: 30,
loop: true,
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev"
},
onInit: swiper => {
this.swiper1 = swiper;
}
};
return (
<React.Fragment>
<div className="gallery-wrapper">
<Swiper {...params} ref={this.galleryRef}>
<div className="swiper-slide">
<img src="http://lorempixel.com/800/800/sports/1/" />
</div>
<div className="swiper-slide">
<img src="http://lorempixel.com/800/400/sports/2/" />
</div>
<div className="swiper-slide">
<img src="http://lorempixel.com/400/800/sports/3/" />
</div>
</Swiper>
</div>
<div className="thumbs-container">
<Swiper {...thumbnailSwiperParams} ref={this.thumbRef}>
<div className="swiper-slide1">
<img src="http://lorempixel.com/100/100/sports/1/" />
</div>
<div className="swiper-slide1">
<img src="http://lorempixel.com/100/100/sports/2/" />
</div>
<div className="swiper-slide1">
<img src="http://lorempixel.com/100/100/sports/3/" />
</div>
</Swiper>
</div>
</React.Fragment>
);
}
}
Also you can see a demo: https://codesandbox.io/s/74mz4jz646
This is the official code examples: http://kidjp85.github.io/react-id-swiper/ ("Thumbs Gallery With Two-way Control")
UPD: ok guys, Swiper is not really 100% good for thumbnails. So I just decided to use react-slick with build-in thumbs functionality. You can find example in the react-slick docs.
For someone with this issue when you use custom build you have to import the modules manually, but in the examples they use the library that imports everything
To solve this issue just add into module imports:
// For version <=2.3.2
import { Swiper, Controller } from 'swiper/dist/js/swiper.esm';
// For version >=2.4.0
import { Swiper, Controller } from 'swiper/js/swiper.esm';
And inside the slider settings
const gallerySwiperParams = {
Swiper,
modules: [Controller],
getSwiper: getGallerySwiper,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
spaceBetween: 10,
};
modules: [Controller], this makes the magic
It could also be some bug in react. Removing "strict mode" worked for me
Replacing this:
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
rootElement
);
with this
ReactDOM.render(
<App />,
rootElement
);
and everything worked