From accbc888bc1065b355b4fe85951ca78d28a814d3 Mon Sep 17 00:00:00 2001 From: zzc <1761997216@qq.com> Date: Fri, 23 Jan 2026 09:44:42 +0800 Subject: [PATCH] fix: avator ,pve --- pages/avatar/index.vue | 101 +++++++++++++++++++++++++++++++++++++++-- pages/index/index.vue | 29 +++++++++++- 2 files changed, 124 insertions(+), 6 deletions(-) diff --git a/pages/avatar/index.vue b/pages/avatar/index.vue index a285748..fe64483 100644 --- a/pages/avatar/index.vue +++ b/pages/avatar/index.vue @@ -18,6 +18,10 @@ class="decor-img" :src="selectedDecor" mode="aspectFit" + :style="decorStyle" + @touchstart.stop="onTouchStart" + @touchmove.stop="onTouchMove" + @touchend.stop="onTouchEnd" /> 实时预览效果 @@ -135,6 +139,81 @@ const selectedFrame = ref(""); const selectedDecor = ref(""); const activeTab = ref("frame"); +// 挂饰状态 +const decorState = ref({ + x: 300, // 初始中心 X (rpx) + y: 80, // 初始中心 Y (rpx) + scale: 1, + rotate: 0, +}); + +const decorStyle = computed(() => { + return { + transform: `translate(${decorState.value.x - 120}rpx, ${ + decorState.value.y - 120 + }rpx) rotate(${decorState.value.rotate}deg) scale(${ + decorState.value.scale + })`, + }; +}); + +// 触摸状态 +let startTouches = []; +let initialDecorState = {}; + +const getDistance = (p1, p2) => { + const x = p1.clientX - p2.clientX; + const y = p1.clientY - p2.clientY; + return Math.sqrt(x * x + y * y); +}; + +const getAngle = (p1, p2) => { + const x = p1.clientX - p2.clientX; + const y = p1.clientY - p2.clientY; + return (Math.atan2(y, x) * 180) / Math.PI; +}; + +const onTouchStart = (e) => { + startTouches = e.touches; + initialDecorState = { ...decorState.value }; +}; + +const onTouchMove = (e) => { + if (e.touches.length === 1 && startTouches.length === 1) { + // 单指移动 + const dx = e.touches[0].clientX - startTouches[0].clientX; + const dy = e.touches[0].clientY - startTouches[0].clientY; + + // px 转 rpx + const systemInfo = uni.getSystemInfoSync(); + const ratio = 750 / systemInfo.windowWidth; + + decorState.value.x = initialDecorState.x + dx * ratio; + decorState.value.y = initialDecorState.y + dy * ratio; + } else if (e.touches.length === 2 && startTouches.length === 2) { + // 双指缩放/旋转 + const p1 = e.touches[0]; + const p2 = e.touches[1]; + const startP1 = startTouches[0]; + const startP2 = startTouches[1]; + + const currentDist = getDistance(p1, p2); + const startDist = getDistance(startP1, startP2); + + const currentAngle = getAngle(p1, p2); + const startAngle = getAngle(startP1, startP2); + + decorState.value.scale = + initialDecorState.scale * (currentDist / startDist); + decorState.value.rotate = + initialDecorState.rotate + (currentAngle - startAngle); + } +}; + +const onTouchEnd = () => { + // 可以在这里做边界检查等 +}; + const handleLogind = async () => { // Logic after successful login if needed }; @@ -163,7 +242,21 @@ const saveAndUse = async () => { } if (selectedDecor.value) { const decorPath = await loadImage(selectedDecor.value); - ctx.drawImage(decorPath, 0, 0, size, size); + ctx.save(); + // 映射 rpx 坐标到 Canvas 坐标 (假设 1rpx = 1 unit for 600x600 canvas logic) + // Canvas size is 600, Preview is 600rpx. Ratio is 1:1 in logical space. + ctx.translate(decorState.value.x, decorState.value.y); + ctx.rotate((decorState.value.rotate * Math.PI) / 180); + const scale = decorState.value.scale; + // 绘制图片,宽高 240 + ctx.drawImage( + decorPath, + -120 * scale, + -120 * scale, + 240 * scale, + 240 * scale, + ); + ctx.restore(); } ctx.draw(false, () => { uni.canvasToTempFilePath({ @@ -245,11 +338,11 @@ const loadImage = (url) => { } .decor-img { position: absolute; - top: -40rpx; - left: 50%; - transform: translateX(-50%); + top: 0; + left: 0; width: 240rpx; height: 240rpx; + /* 移除原有的 transform 和 center positioning,改为由 inline style 控制 */ } .preview-tip { display: block; diff --git a/pages/index/index.vue b/pages/index/index.vue index 894906f..6c7ccc6 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -139,9 +139,25 @@ const updateCountdown = () => { }; const todayDate = ref(""); -const dailyGreeting = ref( +const dailyGreeting = ref(""); + +const inspirationList = [ "岁岁常欢愉,年年皆胜意。愿你新的一年,多喜乐,长安宁。", -); + "新的一年,愿日子如熹光,温柔又安详。你我赤诚且勇敢,欣喜也在望。", + "祝你:百事无忌,平安喜乐。万事胜意,得偿所愿。", + "凡是过往,皆为序章。愿2026年,烟火向星辰,所愿皆成真。", + "愿新的一年,仍有阳光满路,温暖如初。", + "辞暮尔尔,烟火年年。朝朝暮暮,岁岁平安。", + "愿你即使单枪匹马,也能勇敢无畏。新的一年,万事尽可期待。", + "所求皆如愿,所行化坦途。多喜乐,长安宁。", + "愿你手握山河,且行且歌。新年快乐,万事大吉。", + "长路浩浩荡荡,万物尽可期待。祝你新年好运。", + "何其有幸,年岁并进。新的一年,愿你快乐,不止新年。", + "愿新年,胜旧年。无病无灾,岁岁平安。", + "烟火起,照人间,举杯敬此年。烟花落,看人间,家家户户皆团圆。", + "家人闲坐,灯火可亲。新年伊始,喜乐安宁。", + "愿今年所有的遗憾,都是明年惊喜的铺垫。", +]; const copyGreeting = () => { uni.setClipboardData({ @@ -163,6 +179,15 @@ onMounted(() => { updateCountdown(); const date = new Date(); todayDate.value = `${date.getMonth() + 1}月${date.getDate()}日`; + + // Daily Inspiration Logic + const startOfYear = new Date(date.getFullYear(), 0, 0); + const diff = date - startOfYear; + const oneDay = 1000 * 60 * 60 * 24; + const dayOfYear = Math.floor(diff / oneDay); + + const index = dayOfYear % inspirationList.length; + dailyGreeting.value = inspirationList[index]; }); const features = ref([