效果圖

使用示例
<script lang="ts" setup>
import FerrisWheel from "**/FerrisWheel.vue";
import { ref } from "vue";
const defaultUrls = [
"https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel1.jpeg",
"https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel2.jpeg",
"https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel3.jpeg",
"https://naive-ui.oss-cn-beijing.aliyuncs.com/carousel-img/carousel4.jpeg",
];
const urls = ref([...defaultUrls]);
function add() {
const index = Math.floor(Math.random() * defaultUrls.length);
urls.value.push(defaultUrls[index]);
}
function remove() {
urls.value.pop();
}
</script>
<template>
<FerrisWheel :value="urls">
<template #default="{ data }">
<img :src="data" />
</template>
</FerrisWheel>
<n-button @click="remove">-</n-button>
<n-button @click="add">+</n-button>
</template>
<style scoped lang="scss">
.ferris-wheel {
margin: 100px;
}
img {
width: 100px;
height: 100px;
}
</style>
FerrisWheel.vue
<script lang="ts" setup>
import { _Math_Degree, _Utility_GenerateUUID } from "nhanh-pure-function";
import { computed } from "vue";
interface Props {
value?: any[];
radius?: number;
}
const props = withDefaults(defineProps<Props>(), {
value: () => [],
radius: 150,
});
const list = computed(() => {
const { value, radius } = props;
const angle = 360 / value.length;
return value.map((data, index) => {
const rotate = index * angle;
const x = (_Math_Degree.sin(rotate) * radius).toFixed(0);
const y = (_Math_Degree.cos(rotate) * radius).toFixed(0);
const style = {
transform: `translate3d(${x}px, ${y}px, 0px) rotate(calc(var(--angle-value) * -1deg))`,
};
const id = _Utility_GenerateUUID();
return { data, style, id };
});
});
</script>
<template>
<div class="ferris-wheel" :style="{ '--radius': radius }">
<div v-for="item in list" :key="item.id" class="item" :style="item.style">
<slot :data="item.data" />
</div>
</div>
</template>
<style scoped lang="scss">
@property --angle-value {
syntax: "<number>";
initial-value: 0;
inherits: true;
}
@keyframes custom-rotate {
from {
--angle-value: 0;
}
to {
--angle-value: 360;
}
}
.ferris-wheel {
animation: custom-rotate 10s linear infinite;
transform: rotate(calc(var(--angle-value) * 1deg));
position: relative;
width: calc(var(--radius) * 2px);
height: calc(var(--radius) * 2px);
display: flex;
justify-content: center;
align-items: center;
> .item {
position: absolute;
}
}
</style>