I'm using ngx-slick-carousel to display youtube videos in my project, the first problem is that the carousel is not infinite, when the last video appears, the first one is not next to it, there are just white spaces, when the carousel gets the final video to the end it goes back to the first slide, I want the carousel to display the first slide next to the final so it doesn't make the animation to go back to the first slide.
The second problem is the responsive display, I put the responsive code in my TS file but seems that the youtube video is not responding to this, also i tried to use bootstrap grid to achieve this but didnt work, any advice on this problems?
HTML file
<div class="row">
<div class="col-lg-9">
<div class="slick-wrapper">
<ngx-slick-carousel class="carousel" #slickModal="slick-carousel" [config] = "slideConfig" (init)="slickInit($event)" (breakpoint)="breakpoint($event)">
<div ngxSlickItem *ngFor="let slide of slides" class="slide">
<div class="col-md-4">
<youtube-player
videoId= {{slide.videoId}}
suggestedQuality="default"
[height]=""
[width]=""
[startSeconds]="0"
[endSeconds]="">
</youtube-player>
</div>
</div>
</ngx-slick-carousel>
</div>
</div>
</div>
TS file
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-videos',
templateUrl: './videos.component.html',
styleUrls: ['./videos.component.css']
})
export class VideosComponent implements OnInit {
constructor() { }
ngOnInit(): void {
const tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
document.body.appendChild(tag);
}
slides = [
{videoId: "rf8vM_X1g9U"},
{videoId: "3xq7z7WBOGU"},
{videoId: "9PBeqHEopLs"},
{videoId: "1jeHyrRskdk"},
{videoId: "KauOtgNuzQQ"}
];
slideConfig = {
"slidesToShow": 3,
"slidesToScroll": 1,
"autoplay": true,
"autoplaySpeed": 3000,
"infinite": true,
"responsive": [
{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 1,
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 2,
slidesToScroll: 1
}
},
{
breakpoint: 480,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
]
};
slickInit(e: any) {
console.log('slick initialized');
}
breakpoint(e: any) {
console.log('breakpoint');
}
}
I only have this in my css
.slick-prev:before, .slick-next:before {
color: black!important;
}
I'm using youTube-player Module to display the youTube videos and using the *ngFor to get the videos ID
I endup using another carousel, I'll leave the code in this other question
It seems that the infinite loop is a bug, theres an issue of this in github
Related
I am using the react multi carousel library to display some divs. The code seems to be working in theory as you see below:
import * as React from "react";
import "../styles/Home.css";
import Carousel from "react-multi-carousel";
import "react-multi-carousel/lib/styles.css";
const responsive = {
superLargeDesktop: {
// the naming can be any, depends on you.
breakpoint: { max: 4000, min: 3000 },
items: 5
},
desktop: {
breakpoint: { max: 3000, min: 1024 },
items: 5
},
tablet: {
breakpoint: { max: 1024, min: 464 },
items: 5
},
mobile: {
breakpoint: { max: 464, min: 0 },
items: 5
}
};
const IndicatorCarousel = () => {
return (
<div className="IndicatorCarousel">
<div className="IndicatorCarouselText">
Select your preferred stock indicators
</div>
<br></br>
<Carousel
swipeable={false}
draggable={false}
showDots={true}
responsive={responsive}
ssr={true} // means to render carousel on server-side.
infinite={true}
autoPlaySpeed={1000}
keyBoardControl={true}
customTransition="all .5"
transitionDuration={500}
containerClass="carousel-container"
removeArrowOnDeviceType={["tablet", "mobile"]}
dotListClass="custom-dot-list-style"
itemClass="carousel-item-padding-40-px"
>
<div className="IndicatorCarouselCard">
Test
</div>
<div className="IndicatorCarouselCard">
Test2
</div>
<div className="IndicatorCarouselCard">
test3
</div>
<div className="IndicatorCarouselCard">
test4
</div>
<div className="IndicatorCarouselCard">
test5
</div>
</Carousel>
</div>
);
};
export default IndicatorCarousel;
However, when I render the carousel in my browser, it only shows three sections with a singular div in each section and is able to be navigated using the dots and arrows. Instead, I would like to display all three sections at the same time and move along the carousel using the arrows.
Does anybody see something wrong in my code?
Let me know.
Current situation:
Try setting the centerMode property to true on the Carousel component.
<Carousel
...
centerMode={true}
...
>
Alternatively you could try setting partialVisible to true
How to cancel the click of the next button in swiper base on my logic?
I use swiperjs in vue base on swiperjs, and I want to prevent the from the user to swipe or click on the button to go the next slide base on the results from my logic function.
I try this - not works.
swiper.on('init', async () => {
swiper.navigation.$nextEl.on('click', (e) => {
if (true /* mylogic() */) { e.preventDefault(); }
});
...
});
and this:
<div #click="onNext" slot="button-next"></div>
...
function onNext(e) {
if (true /* mylogic() */) { e.preventDefault(); }
}
Nothing works - the swiper is still move to the next slide.
How to prevent the click to move to the next slide?
Code on Codesandbox.io
By configuring the swiper options to use .swiper-button-prev to trigger the next swipe, it is taking place before your on-click function onNext().
Essentially you need to prevent swiper firing on the next arrow click, and then implement it yourself with the swiper.slideNext() method.
So. Add a ref to the swiper element, remove the swiper-button-prev class, move you onNext() method to the methods object (where it should be, right?), call the swiper.slideNext() method in your function, if someCondition is true.
codesandbox...
<template>
<div id="app">
<h2>1</h2>
<swiper ref="mySwiper" :options="swiperOption1">
<swiper-slide v-for="(game, index) in jackpotGames" v-bind:key="index">
<div class="game-item game-item__1">
game_id: {{game.game_id}},
<br>
provider: {{game.provider}},
<br>
img: {{game.img}}
</div>
</swiper-slide>
<div class="swiper-button-prev" slot="button-prev">←</div>
<div #click="onNext" class="" slot="button-next">→</div>
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
</div>
</template>
<script>
import { swiper, swiperSlide } from "vue-awesome-swiper";
export default {
name: "App",
components: {
swiper,
swiperSlide
},
data() {
return {
swiperOption1: {
slidesPerView: 4,
slidesPerColumn: 1,
spaceBetween: 16,
freeMode: true,
pagination: {
el: ".swiper-pagination",
type: "progressbar"
},
navigation: {
// nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev"
},
breakpoints: {
640: {
slidesPerView: 2,
spaceBetween: 8,
pagination: {
el: ".swiper-pagination",
type: "bullets"
},
navigation: {}
}
}
},
jackpotGames: [
// Removed to save space in this answer.
]
};
},
methods: {
onNext(e) {
let someCondition = true;
if (someCondition) {
this.swiper.slideNext();
}
}
},
computed: {
swiper() {
return this.$refs.mySwiper.swiper
}
},
mounted() {
console.log('swiper', this.swiper);
}
};
</script>
Tryin to build a simple custom image slide and mostly make it work except one thing. When :src data changes, I want to add a transition like opacity:0 ~ 1 but couldn't achieve that part. Here is the slide.
template
<img class="slide-image" :src="getImgUrl(images[0])">
script
data(){
return {
images: [
"/images/home/home-slide1.png",
"/images/home/home-slide2.png",
"/images/home/home-slide3.png",
"/images/home/home-slide4.png",
"/images/home/home-slide5.png",
]
};
},
watch: {
getImgUrl(){
}
},
mounted(){
window.setInterval(()=>{
this.slide();
}, 5000);
},
methods: {
getImgUrl(im) {
return require('../assets' + im)
},
slide(){
let first = this.images.shift();
this.images = this.images.concat(first);
},
},
what is best and simple possible way to add a transition when :src changes every 5s, appreciate if anyone can guide about this.
<script>
export default {
name: "Slider",
data() {
return {
images: [
"/images/home/home-slide1.png",
"/images/home/home-slide2.png",
"/images/home/home-slide3.png",
"/images/home/home-slide4.png",
"/images/home/home-slide5.png",
],
timer: null,
currentIndex: 0
};
},
mounted: function() {
this.startSlide();
},
methods: {
startSlide: function() {
this.timer = setInterval(this.next, 5000);
},
next: function() {
this.currentIndex += 1;
},
prev: function() {
this.currentIndex -= 1;
}
},
computed: {
currentImg: function() {
return this.images[Math.abs(this.currentIndex) % this.images.length];
}
}
};
</script>
Let’s look what we did here:
We got an array of image URLs.
Set timer to null and set currentIndex to 0 for showing the first image.
Created startSlide function for sliding images every 4 seconds.
Created next and prev functions for sliding to the previous or the next image. According to the last currentImg function it detects which image must show at that time based on the index.
HTML:
<template>
<div>
<transition-group name="fade" tag="div">
<div v-for="i in [currentIndex]" :key="i">
<img :src="currentImg" />
</div>
</transition-group>
<a class="prev" #click="prev" href="#">❮ Previous</a>
<a class="next" #click="next" href="#">❯ Next</a>
</div>
</template>
Here we take advantage of the built-in transtion-group component that comes with Vue.js, then iterate images and add the functions we created earlier.
More details here: https://alligator.io/vuejs/create-image-slider/
You can try the Vue-transition
Wrap your transition section with transition tag like this
<transition name="slider">
<img class="slide-image" :src="getImgUrl(images[0])">
</transition>
It will add classes when the elements enter and leave. So you can add styles accordingly.
Please refer this link : https://v2.vuejs.org/v2/guide/transitions.html#Transitioning-Single-Elements-Components
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.
for some reason the swiper does not show the pagination for the image casousel that i crated.
It shows up in the dom but with the height of 0. Changing it manually did not do anything. Any ideas?
import Swiper from '../../vendor/swiper.min.js';
export default {
name: 'ImageCarouselBlock',
components: {
MediaImage,
},
props: {
cmsData: {
type: Object,
default: () => {
return {};
},
},
},
mounted() {
let carouselConfig = {};
if (this.cmsData.auto){
carouselConfig = {
spaceBetween: 30,
centeredSlide: true,
autoplay: {
delay: 2000,
disableOnInteraction: false,
},
};
}
else {
carouselConfig = {
spaceBetween: 30,
loop: true,
pagination: {
el: '.swiper-pagination',
},
};
}
const mySwiper = new Swiper('.swiper-container', carouselConfig);
},
computed: {
images() {
return this.cmsData.images.map( image => {
return {
// TODO maybe get something from amplicence that tells how big they want the carousel to be?
imageData : getMediaAndSources(image.name, '1500'),
};
});
},
},
};
And this is the corresponding template. I tried changing the position of where i put the pagination element but nothing worked. I am out of ideas here and i need some help.
<div class="image-carousel-block">
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="image in images">
<media-image preload="true" :sources="image.imageData.sources" :media="image.imageData.media" />
</div>
</div>
<div class="swiper-pagination"></div>
</div>
</div>
The culprit was in my vue file.
<template src="./template.html"></template>
<script src="./script.js"></script>
<style lang="stylus" scoped> -- wrong here
#import '../../vendor/swiper.styl'
#import './style.styl'
</style>
Removing "scoped" did the trick for me.