動態畫廊 util
自由變換排版的畫廊。
使用範例
基本用法
切換 type 時,動態變更圖片排版
努力讀取中
查看範例原始碼
vue
<template>
<div class="mt-4 w-full flex flex-col gap-4">
<util-motion-gallery
v-slot="{ isLoading }"
class="h-full"
:image-list
:layout
>
<transition name="opacity">
<div
v-if="isLoading"
class="absolute h-full w-full flex-center bg-black/50"
>
<div class="flex flex-col items-center gap-4">
<div class="h-10 w-10 animate-spin border-4 border-white border-t-transparent rounded-full" />
<span class="text-2xl text-white tracking-widest">
努力讀取中</span>
</div>
</div>
</transition>
</util-motion-gallery>
<select-stepper
v-model="type"
:options
class="w-full text-center"
/>
</div>
</template>
<script setup lang="ts">
import type { ExtractComponentProps } from '../../../types'
import { computed, ref } from 'vue'
import SelectStepper from '../../select-stepper.vue'
import UtilMotionGallery from '../util-motion-gallery.vue'
type Props = ExtractComponentProps<typeof UtilMotionGallery>
type LayoutType = NonNullable<Props['layout']>['type']
const imageList: [string, ...string[]] = [
'/low/painting-codfish-bakery.webp',
'/low/painting-codfish-rain.webp',
'/low/photography-fireworks.webp',
'/low/photography-morning-light-of-rice.webp',
'/low/photography-big-stupid-bird.webp',
'/low/photography-ears-of-rice.webp',
'/low/photography-gaomei-windmill.webp',
'/low/photography-spider-at-night.webp',
'/low/photography-street-cat.webp',
'/low/photography-afternoon-cicada-chirping.webp',
'/low/photography-whispers-of-the-setting-sun.webp',
'/low/photography-city-of-lights-from-the-mountainside.webp',
]
const type = ref<LayoutType>('grid')
const layout = computed(() => ({
type: type.value,
}))
const options: LayoutType[] = [
'grid',
'wheel',
'tunnel',
'ball',
]
</script>
<style scoped lang="sass">
.opacity-enter-active, .opacity-leave-active
transition-duration: 0.4s
.opacity-enter-from, .opacity-leave-to
opacity: 0 !important
</style>
原理
基於 babylon.js 實現 3D 物件的旋轉、縮放、平移等等變換,利用 anime.js 實現動畫效果。
轉啊轉啊轉
在 3D 空間中旋轉的物體需考慮每個軸的旋轉順序,會影響最終的旋轉結果。
也就是說同樣是每個軸各轉 90 度,但 XYZ、 ZYX、YZX 這三種順序的結果會不一樣呦!( ゚ ∀。)
詳細說明可見 Sequencing Rotations
常常轉到腦袋打結 ~( ゚ ∀。)~
原始碼
API
Props
type Layout = {
type: 'grid';
gap?: number;
} | {
type: 'wheel';
radius?: number;
} | {
type: 'tunnel';
radius?: number;
depthGap?: number;
} | {
type: 'ball';
radius?: number;
}
interface Props {
layout?: Layout;
/** 不足 30 張會自動重複填充至 30 張 */
imageList: [string, ...string[]];
fpsVisible?: boolean;
/** 背景色。無限遠處的顏色 */
clearColor?: Color4;
/** 霧化色。足夠遠處的照片會被此顏色籠罩 */
fogColor?: Color3;
}
Emits
interface Emits { }