diff --git a/components/DongzhimenScene.vue b/components/DongzhimenScene.vue
index 5aa807b..07a07e3 100644
--- a/components/DongzhimenScene.vue
+++ b/components/DongzhimenScene.vue
@@ -39,6 +39,124 @@ const handleFuClick = () => {
emit('collect-seal')
}
+// 拖拽状态
+const isDragging = ref(false)
+const showDuck = ref(false)
+const deskImage = ref('/static/dzm/img_desk1.png')
+const showGuideElements = ref(true)
+
+// 鸭子元素引用
+const duckElement = ref(null)
+
+// 鸭子当前位置(使用普通变量,避免响应式带来的性能开销)
+let duckX = 0
+let duckY = 0
+
+// 拖拽开始区域 (540, 1781, 100, 100) 的中心点
+const dragStartArea = { x: 590, y: 1831 }
+
+// 目标区域 (餐桌区域: 13, 1665, 441, 382)
+const targetArea = { x: 100, y: 1750, width: 300, height: 200 }
+
+// 开始拖拽
+const startDrag = (e) => {
+ e.preventDefault()
+
+ // 如果已经在拖拽中,先结束之前的
+ if (isDragging.value) {
+ endDrag()
+ }
+
+ isDragging.value = true
+ showDuck.value = true
+
+ // 获取触摸或鼠标位置
+ const clientX = e.touches ? e.touches[0].clientX : e.clientX
+ const clientY = e.touches ? e.touches[0].clientY : e.clientY
+
+ // 设置鸭子初始位置
+ updateDuckPosition(clientX, clientY)
+
+ // 先移除可能存在的旧监听器,防止重复绑定
+ document.removeEventListener('mousemove', onDrag)
+ document.removeEventListener('mouseup', endDrag)
+ document.removeEventListener('touchmove', onDrag)
+ document.removeEventListener('touchend', endDrag)
+
+ // 添加全局事件监听
+ document.addEventListener('mousemove', onDrag)
+ document.addEventListener('mouseup', endDrag)
+ document.addEventListener('touchmove', onDrag, { passive: false })
+ document.addEventListener('touchend', endDrag)
+}
+
+// 拖拽中
+const onDrag = (e) => {
+ if (!isDragging.value) return
+ e.preventDefault()
+
+ const clientX = e.touches ? e.touches[0].clientX : e.clientX
+ const clientY = e.touches ? e.touches[0].clientY : e.clientY
+
+ updateDuckPosition(clientX, clientY)
+}
+
+// 更新鸭子位置 - 直接操作 DOM 实现硬件加速
+const updateDuckPosition = (clientX, clientY) => {
+ duckX = clientX
+ duckY = clientY
+
+ if (duckElement.value) {
+ // 使用 transform3d 启用 GPU 加速
+ duckElement.value.style.transform = `translate3d(${clientX}px, ${clientY}px, 0) translate(-50%, -50%) scale(1.2)`
+ }
+}
+
+// 结束拖拽
+const endDrag = () => {
+ if (!isDragging.value) return
+
+ // 获取容器在视口中的位置
+ const container = document.querySelector('.dongzhimen-scene-container')
+ if (container) {
+ const rect = container.getBoundingClientRect()
+ // 鸭子相对于容器的位置
+ const duckRelX = duckX - rect.left
+ const duckRelY = duckY - rect.top
+
+ // 将 rpx 转换为 px (假设设计稿宽度 750rpx,实际宽度通过 rect.width 计算)
+ const rpxToPx = rect.width / 750
+ const targetX = targetArea.x * rpxToPx
+ const targetY = targetArea.y * rpxToPx
+ const targetW = targetArea.width * rpxToPx
+ const targetH = targetArea.height * rpxToPx
+
+ const inTargetArea = (
+ duckRelX >= targetX &&
+ duckRelX <= targetX + targetW &&
+ duckRelY >= targetY &&
+ duckRelY <= targetY + targetH
+ )
+
+ if (inTargetArea) {
+ // 更换餐桌图片
+ deskImage.value = '/static/dzm/img_desk2.png'
+ // 隐藏引导元素
+ showGuideElements.value = false
+ }
+ }
+
+ // 隐藏鸭子
+ showDuck.value = false
+ isDragging.value = false
+
+ // 移除全局事件监听
+ document.removeEventListener('mousemove', onDrag)
+ document.removeEventListener('mouseup', endDrag)
+ document.removeEventListener('touchmove', onDrag)
+ document.removeEventListener('touchend', endDrag)
+}
+
// 页面挂载时的初始化
onMounted(() => {
// 添加动画类,触发入场动画
@@ -75,6 +193,29 @@ onMounted(() => {
alt="新春祝福"
class="sq-image"
/>
+
+
+
+
+
+
+
+
+
@@ -319,6 +460,82 @@ onMounted(() => {
animation: fadeIn 0.5s ease;
}
+/* 装饰图片 */
+.deco-img {
+ position: absolute;
+ z-index: 25;
+}
+
+.desk-img {
+ left: 13rpx;
+ top: 1665rpx;
+ width: 441rpx;
+ height: 382rpx;
+}
+
+.stove-img {
+ left: 492rpx;
+ top: 1711rpx;
+ width: 241rpx;
+ height: 363rpx;
+}
+
+.line-img {
+ left: 250rpx;
+ top: 1842rpx;
+ width: 360rpx;
+ height: 80rpx;
+}
+
+.hand-img {
+ left: 440rpx;
+ top: 1900rpx;
+ width: 38rpx;
+ height: 40rpx;
+ animation: arcSlideLeft 1.2s ease-in-out infinite;
+}
+
+/* 向左弧形滑动动效 */
+@keyframes arcSlideLeft {
+ 0% {
+ transform: translateX(0) translateY(0);
+ opacity: 1;
+ }
+
+ 100% {
+ transform: translateX(-80rpx) translateY(3rpx);
+ opacity: 1;
+ }
+}
+
+/* 拖拽触发区域 */
+.drag-trigger-area {
+ position: absolute;
+ left: 540rpx;
+ top: 1781rpx;
+ width: 100rpx;
+ height: 100rpx;
+ cursor: grab;
+ z-index: 30;
+}
+
+.drag-trigger-area:active {
+ cursor: grabbing;
+}
+
+/* 跟随拖拽的鸭子图片 */
+.drag-duck {
+ position: fixed;
+ left: 0;
+ top: 0;
+ width: 54rpx;
+ height: 105rpx;
+ opacity: 0.8;
+ pointer-events: none;
+ z-index: 1000;
+ will-change: transform;
+}
+
/* 响应式设计 */
@media (max-width: 640px) {
.fu-word {
diff --git a/components/ImageGalleryModal.vue b/components/ImageGalleryModal.vue
new file mode 100644
index 0000000..fe6ae07
--- /dev/null
+++ b/components/ImageGalleryModal.vue
@@ -0,0 +1,208 @@
+
+
+
+
+