fix: font

This commit is contained in:
zzc
2026-02-01 17:20:13 +08:00
parent 6bc0a2b85f
commit 08befebe42

View File

@@ -37,10 +37,10 @@
class="selected-title-img" class="selected-title-img"
:src="currentTitle.imageUrl" :src="currentTitle.imageUrl"
mode="widthFix" mode="widthFix"
:style="{ :style="titleStyle"
transform: `translate(${titleOffsetX}rpx, ${titleOffsetY}rpx) scale(${titleScale})`, @touchstart.stop="handleTitleTouchStart"
top: '40rpx' @touchmove.stop="handleTitleTouchMove"
}" @touchend.stop="handleTitleTouchEnd"
/> />
<view <view
class="bubble" class="bubble"
@@ -421,9 +421,100 @@ const currentTitle = ref(null);
const titlePage = ref(1); const titlePage = ref(1);
const loadingTitles = ref(false); const loadingTitles = ref(false);
const hasMoreTitles = ref(true); const hasMoreTitles = ref(true);
const titleOffsetX = ref(0); const titleState = ref({
const titleOffsetY = ref(0); offsetX: 0,
const titleScale = ref(1); offsetY: 0,
scale: 1,
rotate: 0,
});
const titleStyle = computed(() => {
return {
transform: `translate(${titleState.value.offsetX}rpx, ${titleState.value.offsetY}rpx) scale(${titleState.value.scale}) rotate(${titleState.value.rotate}deg)`,
top: '40rpx',
pointerEvents: 'auto',
transition: 'none'
};
});
// 缓存比例转换
const sysInfo = uni.getSystemInfoSync();
const pxToRpx = 750 / sysInfo.windowWidth;
// 标题触摸交互相关
let startTouches = [];
let initialTitleState = {
offsetX: 0,
offsetY: 0,
scale: 1,
rotate: 0,
};
const getDistance = (p1, p2) => {
const x = p2.clientX - p1.clientX;
const y = p2.clientY - p1.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 handleTitleTouchStart = (e) => {
if (!currentTitle.value) return;
startTouches = e.touches;
initialTitleState = { ...titleState.value };
};
const handleTitleTouchEnd = () => {
startTouches = [];
};
const handleTitleTouchMove = (e) => {
if (!currentTitle.value || !startTouches.length) return;
if (e.touches.length === 1 && startTouches.length === 1) {
// 单指拖拽
const moveX = e.touches[0].clientX - startTouches[0].clientX;
const moveY = e.touches[0].clientY - startTouches[0].clientY;
titleState.value.offsetX = initialTitleState.offsetX + moveX * pxToRpx;
titleState.value.offsetY = initialTitleState.offsetY + moveY * pxToRpx;
} 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);
if (startDist > 0) {
const scale = initialTitleState.scale * (currentDist / startDist);
titleState.value.scale = Math.min(Math.max(scale, 0.2), 3.0);
}
// 旋转
const currentAngle = getAngle(p1, p2);
const startAngle = getAngle(startP1, startP2);
titleState.value.rotate = initialTitleState.rotate + (currentAngle - startAngle);
// 平移
const currentCenterX = (p1.clientX + p2.clientX) / 2;
const currentCenterY = (p1.clientY + p2.clientY) / 2;
const startCenterX = (startP1.clientX + startP2.clientX) / 2;
const startCenterY = (startP1.clientY + startP2.clientY) / 2;
const moveX = currentCenterX - startCenterX;
const moveY = currentCenterY - startCenterY;
titleState.value.offsetX = initialTitleState.offsetX + moveX * pxToRpx;
titleState.value.offsetY = initialTitleState.offsetY + moveY * pxToRpx;
}
};
const targetName = ref("祝您"); const targetName = ref("祝您");
const signatureName = ref(userStore?.userInfo?.nickName || "xxx"); const signatureName = ref(userStore?.userInfo?.nickName || "xxx");
@@ -750,6 +841,13 @@ const selectTitle = (title) => {
currentTitle.value = null; currentTitle.value = null;
} else { } else {
currentTitle.value = title; currentTitle.value = title;
// 切换标题时重置位置和缩放
titleState.value = {
offsetX: 0,
offsetY: 0,
scale: 1,
rotate: 0,
};
closePanel(); closePanel();
} }
}; };
@@ -884,12 +982,26 @@ const saveByCanvas = async (save = true) => {
// 3⃣ 标题图片 // 3⃣ 标题图片
if (titleImg) { if (titleImg) {
const previewBaseWidth = 400; // rpx const previewBaseWidth = 400; // rpx
const drawWidth = r2p(previewBaseWidth) * titleScale.value; const drawWidth = r2p(previewBaseWidth) * titleState.value.scale;
const drawHeight = (titleImg.height / titleImg.width) * drawWidth; const drawHeight = (titleImg.height / titleImg.width) * drawWidth;
// 预览中是 translate(offsetX, offsetY)top: 40rpx
const titleX = (W - drawWidth) / 2 + r2p(titleOffsetX.value); ctx.save();
const titleY = r2p(40 + titleOffsetY.value); // 计算中心点:容器中点 + 偏移量
ctx.drawImage(titleImg, titleX, titleY, drawWidth, drawHeight); const centerX = W / 2 + r2p(titleState.value.offsetX);
const centerY = r2p(40) + drawHeight / 2 + r2p(titleState.value.offsetY);
ctx.translate(centerX, centerY);
ctx.rotate((titleState.value.rotate * Math.PI) / 180);
// 绘制图片,使图片中心位于 translate 后的 (0,0)
ctx.drawImage(
titleImg,
-drawWidth / 2,
-drawHeight / 2,
drawWidth,
drawHeight
);
ctx.restore();
} }
// 4⃣ 祝福语气泡 // 4⃣ 祝福语气泡
@@ -1428,7 +1540,8 @@ function drawRoundRect(ctx, x, y, w, h, r, color) {
position: absolute; position: absolute;
width: 400rpx; width: 400rpx;
z-index: 2; z-index: 2;
transition: transform 0.1s; /* 移除 transition,防止拖拽抖动 */
transition: none;
} }
.tpl-card.selected { .tpl-card.selected {
outline: 4rpx solid #ff3b30; outline: 4rpx solid #ff3b30;