hookehuyr

feat(PosterBuilder): 添加海报图片cover/contain适配模式支持

补充Image类型的mode属性定义,重构图片绘制的尺寸计算逻辑以适配两种缩放模式;同时更新签到详情页的活动logo配置,使用contain模式并调整其位置与尺寸参数
......@@ -48,6 +48,7 @@ export interface Image {
url: string;
width: number;
height: number;
mode?: 'cover' | 'contain';
borderRadius?: number;
borderRadiusGroup?: number[];
borderWidth?: number;
......
......@@ -251,7 +251,7 @@ export const batchGetImageInfo = (images) => {
*/
export const getImageInfo = (item, index) =>
new Promise((resolve, reject) => {
const { x, y, width, height, url, zIndex } = item;
const { x, y, width, height, url, zIndex, mode = 'cover' } = item;
// 预先计算一些固定值,避免重复计算
const borderRadius = item.borderRadius || 0;
......@@ -265,21 +265,36 @@ export const getImageInfo = (item, index) =>
Taro.getImageInfo({ src: imgPath })
.then((imgInfo) => {
// 获取图片信息
// 根据画布的宽高计算出图片绘制的大小,这里会保证图片绘制不变形, 即宽高比不变,截取再拉伸
// 根据画布的宽高计算出图片绘制的大小
const imgWidth = toRpx(imgInfo.width); // 图片真实宽度 单位 px
const imgHeight = toRpx(imgInfo.height); // 图片真实高度 单位 px
// 优化计算逻辑,减少重复计算
const aspectRatio = imgWidth / imgHeight;
const targetRatio = width / height;
let sx, sy; // 截图的起点坐标
if (aspectRatio <= targetRatio) {
sx = 0;
let sx = 0;
let sy = 0;
let sw = imgWidth;
let sh = imgHeight;
let drawX = x;
let drawY = y;
let drawW = width;
let drawH = height;
if (mode === 'contain') {
if (aspectRatio > targetRatio) {
drawH = width / aspectRatio;
drawY = y + (height - drawH) / 2;
} else {
drawW = height * aspectRatio;
drawX = x + (width - drawW) / 2;
}
} else if (aspectRatio <= targetRatio) {
sy = (imgHeight - (imgWidth / width) * height) / 2;
sh = imgHeight - sy * 2;
} else {
sy = 0;
sx = (imgWidth - (imgHeight / height) * width) / 2;
sw = imgWidth - sx * 2;
}
// 给 canvas 画图准备参数,详见 ./draw.ts-drawImage
......@@ -291,14 +306,15 @@ export const getImageInfo = (item, index) =>
borderRadiusGroup,
zIndex: itemZIndex,
imgPath: imgPath, // 使用下载后的临时文件路径
mode,
sx,
sy,
sw: imgWidth - sx * 2,
sh: imgHeight - sy * 2,
x,
y,
w: width,
h: height
sw,
sh,
x: drawX,
y: drawY,
w: drawW,
h: drawH
};
resolve(result);
})
......
......@@ -448,11 +448,12 @@ const posterConfig = computed(() => {
},
// 活动logo
{
x: 360, // 按比例调整 (450 * 0.8 = 360)
y: 32, // 按比例调整 (40 * 0.8 = 32)
width: 200, // 按比例调整 (250 * 0.8 = 200)
height: 64, // 按比例调整 (80 * 0.8 = 64)
x: 328,
y: 24,
width: 240,
height: 88,
url: currentMockData.value.activity.logo,
mode: 'contain',
zIndex: 2,
},
// 关卡徽章
......