feat: hoverTilt 的效果添加

This commit is contained in:
aoshisen 2026-01-29 22:03:12 +08:00
parent 4146933039
commit 43a8ce7936
6 changed files with 187 additions and 38 deletions

View File

@ -1,7 +1,8 @@
<script setup lang="ts">
import { useEditorStore } from '@/stores/editor';
import { useHoverTiltStore } from '@/stores/hoverTilt';
const store = useEditorStore();
const tilt_store = useHoverTiltStore();
</script>
<style scoped>
@ -11,10 +12,7 @@ img {
}
</style>
<template>
<hover-tilt>
<img
src="https://images.pokemontcg.io/swsh4/25_hires.png"
:style="store.imageStyle"
/>
<hover-tilt v-bind="tilt_store.tiltProps">
<img src="https://images.pokemontcg.io/swsh4/25_hires.png" :style="store.imageStyle" />
</hover-tilt>
</template>

View File

@ -1,39 +1,45 @@
<script lang="ts" setup>
import { folders } from "@/const/editor"
import { EditorFolder } from "@/const/editor"
import { TiltFolder } from "@/const/hoverTilt"
import { useEditorStore } from "@/stores/editor"
import { onMounted, ref } from 'vue'
import { Pane } from 'tweakpane'
import { useHoverTiltStore } from "@/stores/hoverTilt"
const editorStore = useEditorStore()
const hoverTiltStore = useHoverTiltStore()
const paneContainer = ref<HTMLDivElement | null>(null)
// tweakpane
function createPane(container: HTMLDivElement) {
if (!paneContainer.value) return
// pane
const pane = new Pane({ container })
// folders
folders.forEach(folder => {
if (folder.type === 'folder' && folder.children) {
const f = pane.addFolder({
title: folder.label,
expanded: true
})
folder.children.forEach((item: any) => {
f.addBinding(editorStore.formData, item.label, item.params)
})
} else {
pane.addBinding(editorStore.formData, folder.label, folder.params)
}
const editorFolderInstance = pane.addFolder({
title: EditorFolder.label,
expanded: true
})
const hoverTiltFolderInstance = pane.addFolder({
title: TiltFolder.label,
expanded: true
})
EditorFolder.children.forEach((item: any) => {
editorFolderInstance.addBinding(editorStore.formData, item.label, item.params)
})
TiltFolder.children.forEach((item: any) => {
hoverTiltFolderInstance.addBinding(hoverTiltStore.formData, item.label, item.params)
})
}
onMounted(() => {
editorStore.initializeFormData()
hoverTiltStore.initializeFormData()
createPane(paneContainer.value as HTMLDivElement)
})
</script>

View File

@ -1,7 +1,7 @@
const editorConfig = [
{
label: "border-radius",
value: 50,
value: 0,
params: {
min: 0,
step: 1,
@ -10,7 +10,7 @@ const editorConfig = [
},
{
label: "width",
value: 200,
value: 350,
params: {
min: 100,
max: 500,
@ -24,15 +24,8 @@ const editorConfig = [
}
].map((i, index) => ({ ...i, id: index }));
const BasicFolder = editorConfig.filter((i, j) => j <= 2)
const OtherFolder = editorConfig.filter((i, j) => j > 2)
export const folders = [{
export const EditorFolder = {
type: 'folder',
label: 'Basic',
children: BasicFolder
}, {
type: 'folder',
label: 'Other',
children: OtherFolder
}]
label: 'Image',
children: editorConfig
}

115
src/const/hoverTilt.ts Normal file
View File

@ -0,0 +1,115 @@
export const hoverTiltConfig = [
{
label: "tilt-factor",
value: 1,
params: {
min: 0,
max: 2,
step: 0.1
}
},
// {
// label: "tilt-factor-y",
// value: 1,
// params: {
// min: 0,
// max: 2,
// step: 0.1
// }
// },
{
label: "scale-factor",
value: 1,
params: {
min: 0.8,
max: 1.2,
step: 0.05
}
},
//TODO:springOptions @see https://hover-tilt.simey.me/options/props/#springoptions
//TODO:tiltSpringOptions @see https://hover-tilt.simey.me/options/props/#tiltspringoptions
{
label: "enter-delay",
value: 0,
params: {
min: 0,
max: 500,
step: 50
}
},
{
label: "exit-delay",
value: 200,
params: {
min: 0,
max: 1000,
step: 50
}
},
//TODO:shadow @see https://hover-tilt.simey.me/options/props/#shadow
{
label: "shadow-blur",
value: 12,
params: {
min: 0,
max: 50,
step: 1
}
},
{
label: "blend-mode",
value: "overlay",
params: {
options: {
"overlay": "overlay",
"screen": "screen",
"multiply": "multiply",
'plus-lighter': 'plus-lighter',
}
}
},
{
label: "glare-intensity",
value: 1,
params: {
min: 0,
max: 4,
step: 0.1
}
},
{
label: "glare-hue",
value: 270,
params: {
min: 0,
max: 360,
step: 10
}
},
//@see https://hover-tilt.simey.me/options/props/#glaremask
// {
// label: "glare-mask",
// value: undefined,
// },
//@see https://hover-tilt.simey.me/options/props/#glaremaskmode
{
label: "glare-mask-mode",
value: "outside",
params: {
// 'match-source' | 'luminance' | 'alpha' | 'none' | undefined
options: {
"match-source": "match-source",
"luminance": "luminance",
"alpha": "alpha",
"none": "none",
// "undefined": undefined
}
}
}
].map((i, index) => ({ ...i, id: index }));
export const TiltFolder = {
type: 'folder',
label: 'Tilt',
children: hoverTiltConfig
}

View File

@ -1,6 +1,6 @@
import { defineStore } from 'pinia'
import { reactive, computed } from 'vue'
import { folders } from '@/const/editor'
import { EditorFolder } from '@/const/editor'
// 定义哪些属性需要添加 px 单位
const PX_PROPERTIES = ['width', 'border-radius']
@ -11,7 +11,7 @@ export const useEditorStore = defineStore('editor', () => {
// 初始化表单数据
function initializeFormData() {
folders.flatMap(f => f.type === 'folder' ? f.children : []).forEach((item: any) => {
EditorFolder.children.forEach((item: any) => {
if (!(item.label in formData)) {
formData[item.label] = item.value
}

37
src/stores/hoverTilt.ts Normal file
View File

@ -0,0 +1,37 @@
import { defineStore } from 'pinia'
import { reactive, computed } from 'vue'
import { TiltFolder } from '@/const/hoverTilt'
export const useHoverTiltStore = defineStore('hoverTilt', () => {
// 存储 hover-tilt 配置数据
const formData = reactive<Record<string, any>>({})
// 初始化表单数据
function initializeFormData() {
TiltFolder.children.forEach((item: any) => {
if (!(item.label in formData)) {
formData[item.label] = item.value
}
})
}
// 获取转换后的 props 对象,将驼峰命名转换为连字符命名
const tiltProps = computed(() => {
const props: Record<string, any> = {}
Object.entries(formData).forEach(([key, value]) => {
if (value !== undefined) {
props[key] = value
}
})
return props
})
return {
formData,
tiltProps,
initializeFormData,
}
}, {
persist: false
})