立體包裝器 wrapper
可以讓元素有酷酷的 3D 偏轉效果。ˋ( ° ▽、° )
使用範例
基本用法
可以隨手關閉,不過沒辦法省電。乁( ◔ ௰◔)「
安安
漂起來惹
酷酷的漂浮
安安
查看範例原始碼
vue
<template>
<div class="w-full flex flex-col gap-4 border border-gray-300 p-6">
<div class="flex gap-4 border rounded p-4">
<base-checkbox
v-model="enable"
label="懸浮開關"
class="w-full"
/>
</div>
<div class="flex flex-col items-start gap-4">
<wrapper-stereoscopic :enable="enable">
<div class="h-80 w-80 flex-center rounded bg-gray-300">
<div class="h-40 w-40 flex-center rounded bg-gray-100">
<div class="text-xl text-gray-600 font-bold">
安安
</div>
</div>
</div>
</wrapper-stereoscopic>
<div class="flex flex-col items-start justify-start gap-4">
<wrapper-stereoscopic :enable="enable">
<div class="border rounded-full p-4 text-xl text-gray-600 font-bold">
漂起來惹
</div>
</wrapper-stereoscopic>
<wrapper-stereoscopic :enable="enable">
<div class="border rounded-full p-4 text-xl text-gray-600 font-bold">
酷酷的漂浮
</div>
</wrapper-stereoscopic>
<wrapper-stereoscopic :enable="enable">
<div class="border rounded-full p-4 text-xl text-gray-600 font-bold">
安安
</div>
</wrapper-stereoscopic>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import BaseCheckbox from '../../base-checkbox.vue'
import WrapperStereoscopic from '../wrapper-stereoscopic.vue'
const enable = ref(true)
</script>
<style lang="sass" scoped>
.flex-center
display: flex
justify-content: center
align-items: center
</style>
多層視差
多層 layer 可以產生多層立體效果
安安
查看範例原始碼
vue
<template>
<div class="w-full flex flex-col gap-4 border border-gray-300 p-6">
<div class="content flex items-start gap-4">
<wrapper-stereoscopic v-slot="wrapper">
<div
class="h-80 w-80 flex-center rounded bg-gray-300"
:style="wrapper.style"
>
<wrapper-stereoscopic-layer v-slot="layer01">
<div
class="h-40 w-40 flex-center rounded bg-gray-200"
:style="layer01.style"
>
<wrapper-stereoscopic-layer v-slot="layer02">
<div
class="rounded bg-gray-100 p-4 text-xl font-bold"
:style="layer02.style"
>
安安
</div>
</wrapper-stereoscopic-layer>
</div>
</wrapper-stereoscopic-layer>
</div>
</wrapper-stereoscopic>
</div>
</div>
</template>
<script setup lang="ts">
import WrapperStereoscopic from '../wrapper-stereoscopic.vue'
import WrapperStereoscopicLayer from '../wrapper-stereoscopic-layer.vue'
</script>
<style lang="sass" scoped>
.content
perspective: 2000px
.flex-center
display: flex
justify-content: center
align-items: center
</style>
最大偏轉角
可以設定最大偏轉角度
( •̀ ω •́ )✧
查看範例原始碼
vue
<template>
<div class="w-full flex flex-col gap-4 border border-gray-300 p-6">
<div class="flex gap-4 border rounded p-4">
<base-input
v-model="x"
type="range"
:label="`X 最大角度: ${x} 度`"
class="w-full"
:min="0"
:max="90"
/>
<base-input
v-model="y"
type="range"
:label="`Y 軸最大角度: ${y} 度`"
class="w-full"
:min="0"
:max="90"
/>
</div>
<div class="content flex items-start gap-4">
<wrapper-stereoscopic
:x-max-angle="x"
:y-max-angle="y"
>
<div class="border rounded-full p-4 text-xl text-gray-600 font-bold">
( •̀ ω •́ )✧
</div>
</wrapper-stereoscopic>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import BaseInput from '../../base-input.vue'
import WrapperStereoscopic from '../wrapper-stereoscopic.vue'
const x = ref(15)
const y = ref(15)
</script>
<style lang="sass" scoped>
.content
perspective: 2000px
.flex-center
display: flex
justify-content: center
align-items: center
</style>
漂浮距離
可以設定每層之間的漂浮距離,想躺平就躺平。_(:3」ㄥ)_
安安
查看範例原始碼
vue
<template>
<div class="w-full flex flex-col gap-4 border border-gray-300 p-6">
<div class="flex gap-4 border rounded p-4">
<base-input
v-model="zOffset"
type="range"
:label="`懸浮距離: ${zOffset} px`"
class="w-full"
:min="0"
:max="200"
/>
</div>
<div class="content flex items-start gap-4">
<wrapper-stereoscopic
v-slot="wrapper"
:z-offset="zOffset"
>
<div
class="h-80 w-80 flex-center rounded bg-gray-300"
:style="wrapper.style"
>
<wrapper-stereoscopic-layer v-slot="layer01">
<div
class="h-40 w-40 flex-center rounded bg-gray-200"
:style="layer01.style"
>
<wrapper-stereoscopic-layer v-slot="layer02">
<div
class="rounded bg-gray-100 p-4 text-xl font-bold"
:style="layer02.style"
>
安安
</div>
</wrapper-stereoscopic-layer>
</div>
</wrapper-stereoscopic-layer>
</div>
</wrapper-stereoscopic>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import BaseInput from '../../base-input.vue'
import WrapperStereoscopic from '../wrapper-stereoscopic.vue'
import WrapperStereoscopicLayer from '../wrapper-stereoscopic-layer.vue'
const zOffset = ref(100)
</script>
<style lang="sass" scoped>
.content
perspective: 2000px
.flex-center
display: flex
justify-content: center
align-items: center
</style>
原理
利用 CSS 的 perspective 與 transform3d,產生 3D 旋轉與透視變形效果。
其中 perspective 尤為重要,此屬性負責讓物體產生透視變形效果。
沒設定的話,物體看起來像莫名其妙扁掉。...('◉◞⊖◟◉` )
知道如何偏轉後,剩下的部分就簡單惹。( •̀ ω •́ )✧
計算從物體中心到滑鼠位置的向量,分別將向量的 x、y 分量映射到設定的角度範圍,最後套用到 transform 上即可。
不過這裡有個小技巧,我們不把「目前角度」直接設為「目標角度」,而是逐漸趨近「目標角度」。
這樣無論「目標角度」怎麼亂跳,都可以保證偏轉效果都有動畫呈現,看起來更自然、舒服。◝(≧∀≦)◟
原始碼
API
Props
interface Props {
/** 是否開啟 */
enable?: boolean;
/** x 最大偏轉角度 */
xMaxAngle?: number;
/** y 最大偏轉角度 */
yMaxAngle?: number;
/** 懸浮高度 */
zOffset?: number;
}