Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues after latest updates #440

Merged
merged 9 commits into from
Dec 7, 2024
68 changes: 43 additions & 25 deletions playground/App.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
<script setup lang="ts">
import '@/theme.css'
import {
Carousel as VueCarousel,
Slide as CarouselSlide,
Pagination as CarouselPagination,
Navigation as CarouselNavigation,
} from '@/index'
import { ref } from 'vue'

import { DIR_MAP, SNAP_ALIGN_OPTIONS } from '@/shared/constants'

const carouselWrapper = ref<HTMLDivElement | null>(null)
const currentSlide = ref(0)
const snapAlign = ref('center')
const itemsToScroll = ref(1)
const itemsToShow = ref(1)
const autoplay = ref()
const wrapAround = ref(true)
const height = ref('200')
const dir = ref('left-to-right')

const handleRestartAnimation = () => {
if (!carouselWrapper.value) return

carouselWrapper.value.classList.remove('pop-in')
void carouselWrapper.value.offsetWidth
carouselWrapper.value.classList.add('pop-in')
}

const handelButtonClick = () => {
alert('Button clicked')
}
</script>

<template>
<div>
<fieldset>
Expand Down Expand Up @@ -26,8 +61,11 @@
/></label>
<label><input type="checkbox" v-model="wrapAround" />Wrap Around</label>
<label>Current slide: <input type="number" v-model="currentSlide" /></label>

<button @click="handleRestartAnimation">Restart animation</button>
</fieldset>
<div class="carousel-wrapper">

<div class="carousel-wrapper pop-in" ref="carouselWrapper">
<VueCarousel
v-model="currentSlide"
:items-to-show="itemsToShow"
Expand All @@ -41,7 +79,9 @@
:snap-align="snapAlign"
>
<CarouselSlide v-for="i in 10" :key="i" v-slot="{ isActive, isClone }">
<div class="carousel__item">{{ i }}<button>This is a button</button></div>
<div class="carousel__item">
{{ i }}<button @click="handelButtonClick">This is a button</button>
</div>
</CarouselSlide>
<template #addons>
<CarouselPagination />
Expand All @@ -52,28 +92,6 @@
</div>
</template>

<script setup lang="ts">
import '@/theme.css'
import {
Carousel as VueCarousel,
Slide as CarouselSlide,
Pagination as CarouselPagination,
Navigation as CarouselNavigation,
} from '@/index'
import { ref } from 'vue'

import { DIR_MAP, SNAP_ALIGN_OPTIONS } from '@/shared/constants'

const currentSlide = ref(0)
const snapAlign = ref('center')
const itemsToScroll = ref(1)
const itemsToShow = ref(1)
const autoplay = ref()
const wrapAround = ref(true)
const height = ref('200')
const dir = ref('left-to-right')
</script>

<style lang="css">
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
Expand Down Expand Up @@ -105,7 +123,7 @@ fieldset {
}
}

.carousel-wrapper {
.pop-in {
animation: pop-in 3s;
}

Expand Down
2 changes: 1 addition & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import typescript from '@rollup/plugin-typescript'
import css from 'rollup-plugin-css-only'
import del from 'rollup-plugin-delete'
import dts from 'rollup-plugin-dts'

Check warning on line 5 in rollup.config.js

View workflow job for this annotation

GitHub Actions / build

Using exported name 'dts' as identifier for default import
import { typescriptPaths } from 'rollup-plugin-typescript-paths'

import pkg from './package.json' with { type: 'json' }
import pkg from './package.json' assert { type: 'json' }
ismail9k marked this conversation as resolved.
Show resolved Hide resolved

const banner = `/**
* Vue 3 Carousel ${pkg.version}
Expand Down
47 changes: 12 additions & 35 deletions src/components/Carousel/Carousel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
getMinSlideIndex,
mapNumberToRange,
getScrolledIndex,
getTransformValues,
} from '@/utils'

import {
Expand Down Expand Up @@ -146,53 +147,32 @@ export const Carousel = defineComponent({
updateSlideSize()
})

function parseTransform(el: HTMLElement) {
const transform = window.getComputedStyle(el).transform

//add sanity check
return transform
.split(/[(,)]/)
.slice(1, -1)
.map(function (v) {
return parseFloat(v)
})
}

const totalGap = computed(() => (config.itemsToShow - 1) * config.gap)
const transformElements = shallowReactive<Array<HTMLElement>>([])
const transformElements = shallowReactive<Set<HTMLElement>>(new Set())

/**
* Setup functions
*/
function updateSlideSize(): void {
if (!viewport.value) return
let multiplierWidth = 1
let multiplierHeight = 1
transformElements.forEach((el) => {
const transformArr = parseTransform(el)
const transformArr = getTransformValues(el)

if (transformArr.length == 6) {
if (transformArr.length === 6) {
multiplierWidth *= transformArr[0]
multiplierHeight *= transformArr[3]
}
})

// Calculate size based on orientation

if (isVertical.value) {
if (config.height !== 'auto') {
let height
if (typeof config.height === 'string') {
height =
parseInt(config.height).toString() !== config.height
const height =
typeof config.height === 'string' && isNaN(parseInt(config.height))
? viewport.value.getBoundingClientRect().height
: parseInt(config.height)
} else {
height = config.height
}
: parseInt(config.height as string)

slideSize.value =
(height / multiplierHeight - totalGap.value) / config.itemsToShow
slideSize.value = (height - totalGap.value) / config.itemsToShow
}
} else {
const width = viewport.value.getBoundingClientRect().width
Expand Down Expand Up @@ -221,8 +201,8 @@ export const Carousel = defineComponent({

const setAnimationInterval = (event: AnimationEvent | TransitionEvent) => {
const target = event.target as HTMLElement
if (target && !transformElements.includes(target)) {
transformElements.push(target)
if (target) {
transformElements.add(target)
}
if (!animationInterval) {
const stepAnimation = () => {
Expand All @@ -237,12 +217,9 @@ export const Carousel = defineComponent({
const finishAnimation = (event: AnimationEvent | TransitionEvent) => {
const target = event.target as HTMLElement
if (target) {
const found = transformElements.indexOf(target)
if (found >= 0) {
transformElements.splice(found, 1)
}
transformElements.delete(target)
}
if (animationInterval && transformElements.length === 0) {
if (animationInterval && transformElements.size === 0) {
cancelAnimationFrame(animationInterval)
updateSlideSize()
}
Expand Down
9 changes: 9 additions & 0 deletions src/utils/getTransformValues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export function getTransformValues(el: HTMLElement) {
const { transform } = window.getComputedStyle(el)

//add sanity check
return transform
.split(/[(,)]/)
.slice(1, -1)
.map((v) => parseFloat(v))
}
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './getNumberInRange'
export * from './mapNumberToRange'
export * from './i18nFormatter'
export * from './throttle'
export * from './getTransformValues'
Loading