封装分享卡片方法
This commit is contained in:
@@ -14,7 +14,7 @@ export interface ShareCardData {
|
||||
gameDate: string // 日期,如"6月20日(周五)"
|
||||
gameTime: string // 时间,如"下午5点 2小时"
|
||||
venueName: string // 场地名称,如"因乐驰网球俱乐部(嘉定江桥万达店)"
|
||||
venueImage: string // 场地图片URL
|
||||
venueImages: string[] // 场地图片URL
|
||||
|
||||
// 可选信息
|
||||
playerImage?: string // 球员图片URL
|
||||
@@ -44,6 +44,11 @@ const ShareCardCanvas: React.FC<ShareCardCanvasProps> = ({
|
||||
// 获取屏幕宽度,如果没有传入width则使用屏幕宽度
|
||||
const windowWidth = Taro.getSystemInfoSync().windowWidth
|
||||
|
||||
// 获取 DPR - 使用系统像素比确保高清显示
|
||||
// const systemDpr = Taro.getSystemInfoSync().pixelRatio
|
||||
const dpr = 1
|
||||
// Math.min(systemDpr, 3) // 限制最大dpr为3,避免过度放大
|
||||
|
||||
// 2. 计算缩放比例(设备宽度 / 设计稿宽度)
|
||||
const scale = windowWidth / designWidth
|
||||
|
||||
@@ -222,13 +227,201 @@ const ShareCardCanvas: React.FC<ShareCardCanvasProps> = ({
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
// 获取 DPR - 使用系统像素比确保高清显示
|
||||
// const systemDpr = Taro.getSystemInfoSync().pixelRatio
|
||||
const dpr = 1
|
||||
// Math.min(systemDpr, 3) // 限制最大dpr为3,避免过度放大
|
||||
// 绘制右上角场地图片
|
||||
const drawVenueImages = async (ctx: any, venueImageConfig: any) => {
|
||||
// 如果只有一张图
|
||||
const playerImgX = venueImageConfig.venueImgX
|
||||
const playerImgY = venueImageConfig.venueImgY
|
||||
const playerImgSize = venueImageConfig.venueImgSize
|
||||
const borderRadius = venueImageConfig.borderRadius
|
||||
const padding = venueImageConfig.padding
|
||||
const rotation = venueImageConfig.rotation // 旋转-8度
|
||||
const venueImage = venueImageConfig.venueImage
|
||||
|
||||
try {
|
||||
const playerImgPath = await loadImage(venueImage)
|
||||
ctx.save()
|
||||
|
||||
// 移动到旋转中心点
|
||||
const centerX = playerImgX + playerImgSize / 2
|
||||
const centerY = playerImgY + playerImgSize / 2
|
||||
ctx.translate(centerX, centerY)
|
||||
|
||||
// 旋转-8度
|
||||
ctx.rotate((rotation * Math.PI) / 180)
|
||||
|
||||
// 1. 先绘制白色圆角矩形背景
|
||||
ctx.setFillStyle('#FFFFFF')
|
||||
ctx.beginPath()
|
||||
|
||||
// 使用更精确的圆角矩形绘制
|
||||
const rectX = -playerImgSize / 2
|
||||
const rectY = -playerImgSize / 2
|
||||
const rectWidth = playerImgSize
|
||||
const rectHeight = playerImgSize
|
||||
|
||||
// 从左上角开始,顺时针绘制
|
||||
// 左上角圆角
|
||||
ctx.moveTo(rectX + borderRadius, rectY)
|
||||
ctx.quadraticCurveTo(rectX, rectY, rectX, rectY + borderRadius)
|
||||
|
||||
// 左边
|
||||
ctx.lineTo(rectX, rectY + rectHeight - borderRadius)
|
||||
|
||||
// 左下角圆角
|
||||
ctx.quadraticCurveTo(rectX, rectY + rectHeight, rectX + borderRadius, rectY + rectHeight)
|
||||
|
||||
// 下边
|
||||
ctx.lineTo(rectX + rectWidth - borderRadius, rectY + rectHeight)
|
||||
|
||||
// 右下角圆角
|
||||
ctx.quadraticCurveTo(rectX + rectWidth, rectY + rectHeight, rectX + rectWidth, rectY + rectHeight - borderRadius)
|
||||
|
||||
// 右边
|
||||
ctx.lineTo(rectX + rectWidth, rectY + borderRadius)
|
||||
|
||||
// 右上角圆角
|
||||
ctx.quadraticCurveTo(rectX + rectWidth, rectY, rectX + rectWidth - borderRadius, rectY)
|
||||
|
||||
// 上边
|
||||
ctx.lineTo(rectX + borderRadius, rectY)
|
||||
|
||||
ctx.closePath()
|
||||
ctx.fill()
|
||||
|
||||
// 2. 绘制图片(带4px内边距)
|
||||
const imgX = -playerImgSize / 2 + padding
|
||||
const imgY = -playerImgSize / 2 + padding
|
||||
const imgSize = playerImgSize - padding * 2
|
||||
|
||||
// 设置圆角裁剪区域
|
||||
ctx.beginPath()
|
||||
const imgRadius = borderRadius - padding
|
||||
|
||||
// 从左上角开始,顺时针绘制
|
||||
// 左上角圆角
|
||||
ctx.moveTo(imgX + imgRadius, imgY)
|
||||
ctx.quadraticCurveTo(imgX, imgY, imgX, imgY + imgRadius)
|
||||
|
||||
// 左边
|
||||
ctx.lineTo(imgX, imgY + imgSize - imgRadius)
|
||||
|
||||
// 左下角圆角
|
||||
ctx.quadraticCurveTo(imgX, imgY + imgSize, imgX + imgRadius, imgY + imgSize)
|
||||
|
||||
// 下边
|
||||
ctx.lineTo(imgX + imgSize - imgRadius, imgY + imgSize)
|
||||
|
||||
// 右下角圆角
|
||||
ctx.quadraticCurveTo(imgX + imgSize, imgY + imgSize, imgX + imgSize, imgY + imgSize - imgRadius)
|
||||
|
||||
// 右边
|
||||
ctx.lineTo(imgX + imgSize, imgY + imgRadius)
|
||||
|
||||
// 右上角圆角
|
||||
ctx.quadraticCurveTo(imgX + imgSize, imgY, imgX + imgSize - imgRadius, imgY)
|
||||
|
||||
// 上边
|
||||
ctx.lineTo(imgX + imgRadius, imgY)
|
||||
|
||||
ctx.closePath()
|
||||
ctx.clip()
|
||||
|
||||
// 绘制图片
|
||||
ctx.drawImage(playerImgPath, imgX, imgY, imgSize, imgSize)
|
||||
|
||||
ctx.restore()
|
||||
} catch (error) {
|
||||
// 如果图片加载失败,绘制占位符
|
||||
ctx.save()
|
||||
const centerX = playerImgX + playerImgSize / 2
|
||||
const centerY = playerImgY + playerImgSize / 2
|
||||
ctx.translate(centerX, centerY)
|
||||
ctx.rotate((rotation * Math.PI) / 180)
|
||||
|
||||
// 绘制白色圆角矩形背景
|
||||
ctx.setFillStyle('#FFFFFF')
|
||||
ctx.beginPath()
|
||||
|
||||
const rectX = -playerImgSize / 2
|
||||
const rectY = -playerImgSize / 2
|
||||
const rectWidth = playerImgSize
|
||||
const rectHeight = playerImgSize
|
||||
|
||||
// 从左上角开始,顺时针绘制
|
||||
// 左上角圆角
|
||||
ctx.moveTo(rectX + borderRadius, rectY)
|
||||
ctx.quadraticCurveTo(rectX, rectY, rectX, rectY + borderRadius)
|
||||
|
||||
// 左边
|
||||
ctx.lineTo(rectX, rectY + rectHeight - borderRadius)
|
||||
|
||||
// 左下角圆角
|
||||
ctx.quadraticCurveTo(rectX, rectY + rectHeight, rectX + borderRadius, rectY + rectHeight)
|
||||
|
||||
// 下边
|
||||
ctx.lineTo(rectX + rectWidth - borderRadius, rectY + rectHeight)
|
||||
|
||||
// 右下角圆角
|
||||
ctx.quadraticCurveTo(rectX + rectWidth, rectY + rectHeight, rectX + rectWidth, rectY + rectHeight - borderRadius)
|
||||
|
||||
// 右边
|
||||
ctx.lineTo(rectX + rectWidth, rectY + borderRadius)
|
||||
|
||||
// 右上角圆角
|
||||
ctx.quadraticCurveTo(rectX + rectWidth, rectY, rectX + rectWidth - borderRadius, rectY)
|
||||
|
||||
// 上边
|
||||
ctx.lineTo(rectX + borderRadius, rectY)
|
||||
|
||||
ctx.closePath()
|
||||
ctx.fill()
|
||||
|
||||
// 绘制灰色占位符(带内边距)
|
||||
const imgX = -playerImgSize / 2 + padding
|
||||
const imgY = -playerImgSize / 2 + padding
|
||||
const imgSize = playerImgSize - padding * 2
|
||||
|
||||
ctx.setFillStyle('#E0E0E0')
|
||||
ctx.beginPath()
|
||||
const imgRadius = borderRadius - padding
|
||||
|
||||
// 从左上角开始,顺时针绘制
|
||||
// 左上角圆角
|
||||
ctx.moveTo(imgX + imgRadius, imgY)
|
||||
ctx.quadraticCurveTo(imgX, imgY, imgX, imgY + imgRadius)
|
||||
|
||||
// 左边
|
||||
ctx.lineTo(imgX, imgY + imgSize - imgRadius)
|
||||
|
||||
// 左下角圆角
|
||||
ctx.quadraticCurveTo(imgX, imgY + imgSize, imgX + imgRadius, imgY + imgSize)
|
||||
|
||||
// 下边
|
||||
ctx.lineTo(imgX + imgSize - imgRadius, imgY + imgSize)
|
||||
|
||||
// 右下角圆角
|
||||
ctx.quadraticCurveTo(imgX + imgSize, imgY + imgSize, imgX + imgSize, imgY + imgSize - imgRadius)
|
||||
|
||||
// 右边
|
||||
ctx.lineTo(imgX + imgSize, imgY + imgRadius)
|
||||
|
||||
// 右上角圆角
|
||||
ctx.quadraticCurveTo(imgX + imgSize, imgY, imgX + imgSize - imgRadius, imgY)
|
||||
|
||||
// 上边
|
||||
ctx.lineTo(imgX + imgRadius, imgY)
|
||||
|
||||
ctx.closePath()
|
||||
ctx.fill()
|
||||
|
||||
ctx.restore()
|
||||
console.log('球员图片占位符绘制完成')
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制分享卡片
|
||||
const drawShareCard = async () => {
|
||||
const drawShareCard = async (ctx: any) => {
|
||||
// 防止重复绘制
|
||||
if (isDrawing) {
|
||||
console.log('正在绘制中,跳过重复绘制')
|
||||
@@ -240,10 +433,6 @@ const ShareCardCanvas: React.FC<ShareCardCanvasProps> = ({
|
||||
setIsDrawing(true)
|
||||
|
||||
try {
|
||||
// 在微信小程序中,需要使用Taro.createCanvasContext
|
||||
const ctx = Taro.createCanvasContext('shareCardCanvas')
|
||||
console.log('Canvas上下文创建成功:', ctx)
|
||||
|
||||
// 设置Canvas的实际尺寸(使用dpr确保高清显示)
|
||||
const canvasWidthPx = canvasWidth * dpr
|
||||
const canvasHeightPx = canvasHeight * dpr
|
||||
@@ -322,192 +511,35 @@ const ShareCardCanvas: React.FC<ShareCardCanvasProps> = ({
|
||||
drawSVGPathToCanvas(ctx)
|
||||
|
||||
// 绘制球员图片(右上角)已完成
|
||||
const playerImgX = scale * 340 * dpr
|
||||
const playerImgY = scale * 35 * dpr
|
||||
const playerImgSize = scale * 124 * dpr
|
||||
const borderRadius = scale * 24 * dpr
|
||||
const padding = scale * 4 * dpr
|
||||
const rotation = scale * -8 // 旋转-8度
|
||||
let venueBaseConfig = {
|
||||
venueImgX: scale * 340 * dpr,
|
||||
venueImgY: scale * 35 * dpr,
|
||||
rotation: scale * -8, // 旋转-8度
|
||||
venueImgSize: scale * 124 * dpr,
|
||||
borderRadius: scale * 24 * dpr,
|
||||
padding: scale * 4 * dpr,
|
||||
venueImage: data.venueImages?.[0]
|
||||
}
|
||||
|
||||
try {
|
||||
const playerImgPath = await loadImage(data.playerImage || data.venueImage)
|
||||
ctx.save()
|
||||
|
||||
// 移动到旋转中心点
|
||||
const centerX = playerImgX + playerImgSize / 2
|
||||
const centerY = playerImgY + playerImgSize / 2
|
||||
ctx.translate(centerX, centerY)
|
||||
|
||||
// 旋转-8度
|
||||
ctx.rotate((rotation * Math.PI) / 180)
|
||||
|
||||
// 1. 先绘制白色圆角矩形背景
|
||||
ctx.setFillStyle('#FFFFFF')
|
||||
ctx.beginPath()
|
||||
|
||||
// 使用更精确的圆角矩形绘制
|
||||
const rectX = -playerImgSize / 2
|
||||
const rectY = -playerImgSize / 2
|
||||
const rectWidth = playerImgSize
|
||||
const rectHeight = playerImgSize
|
||||
|
||||
// 从左上角开始,顺时针绘制
|
||||
// 左上角圆角
|
||||
ctx.moveTo(rectX + borderRadius, rectY)
|
||||
ctx.quadraticCurveTo(rectX, rectY, rectX, rectY + borderRadius)
|
||||
|
||||
// 左边
|
||||
ctx.lineTo(rectX, rectY + rectHeight - borderRadius)
|
||||
|
||||
// 左下角圆角
|
||||
ctx.quadraticCurveTo(rectX, rectY + rectHeight, rectX + borderRadius, rectY + rectHeight)
|
||||
|
||||
// 下边
|
||||
ctx.lineTo(rectX + rectWidth - borderRadius, rectY + rectHeight)
|
||||
|
||||
// 右下角圆角
|
||||
ctx.quadraticCurveTo(rectX + rectWidth, rectY + rectHeight, rectX + rectWidth, rectY + rectHeight - borderRadius)
|
||||
|
||||
// 右边
|
||||
ctx.lineTo(rectX + rectWidth, rectY + borderRadius)
|
||||
|
||||
// 右上角圆角
|
||||
ctx.quadraticCurveTo(rectX + rectWidth, rectY, rectX + rectWidth - borderRadius, rectY)
|
||||
|
||||
// 上边
|
||||
ctx.lineTo(rectX + borderRadius, rectY)
|
||||
|
||||
ctx.closePath()
|
||||
ctx.fill()
|
||||
|
||||
// 2. 绘制图片(带4px内边距)
|
||||
const imgX = -playerImgSize / 2 + padding
|
||||
const imgY = -playerImgSize / 2 + padding
|
||||
const imgSize = playerImgSize - padding * 2
|
||||
|
||||
// 设置圆角裁剪区域
|
||||
ctx.beginPath()
|
||||
const imgRadius = borderRadius - padding
|
||||
|
||||
// 从左上角开始,顺时针绘制
|
||||
// 左上角圆角
|
||||
ctx.moveTo(imgX + imgRadius, imgY)
|
||||
ctx.quadraticCurveTo(imgX, imgY, imgX, imgY + imgRadius)
|
||||
|
||||
// 左边
|
||||
ctx.lineTo(imgX, imgY + imgSize - imgRadius)
|
||||
|
||||
// 左下角圆角
|
||||
ctx.quadraticCurveTo(imgX, imgY + imgSize, imgX + imgRadius, imgY + imgSize)
|
||||
|
||||
// 下边
|
||||
ctx.lineTo(imgX + imgSize - imgRadius, imgY + imgSize)
|
||||
|
||||
// 右下角圆角
|
||||
ctx.quadraticCurveTo(imgX + imgSize, imgY + imgSize, imgX + imgSize, imgY + imgSize - imgRadius)
|
||||
|
||||
// 右边
|
||||
ctx.lineTo(imgX + imgSize, imgY + imgRadius)
|
||||
|
||||
// 右上角圆角
|
||||
ctx.quadraticCurveTo(imgX + imgSize, imgY, imgX + imgSize - imgRadius, imgY)
|
||||
|
||||
// 上边
|
||||
ctx.lineTo(imgX + imgRadius, imgY)
|
||||
|
||||
ctx.closePath()
|
||||
ctx.clip()
|
||||
|
||||
// 绘制图片
|
||||
ctx.drawImage(playerImgPath, imgX, imgY, imgSize, imgSize)
|
||||
|
||||
ctx.restore()
|
||||
} catch (error) {
|
||||
// 如果图片加载失败,绘制占位符
|
||||
ctx.save()
|
||||
const centerX = playerImgX + playerImgSize / 2
|
||||
const centerY = playerImgY + playerImgSize / 2
|
||||
ctx.translate(centerX, centerY)
|
||||
ctx.rotate((rotation * Math.PI) / 180)
|
||||
|
||||
// 绘制白色圆角矩形背景
|
||||
ctx.setFillStyle('#FFFFFF')
|
||||
ctx.beginPath()
|
||||
|
||||
const rectX = -playerImgSize / 2
|
||||
const rectY = -playerImgSize / 2
|
||||
const rectWidth = playerImgSize
|
||||
const rectHeight = playerImgSize
|
||||
|
||||
// 从左上角开始,顺时针绘制
|
||||
// 左上角圆角
|
||||
ctx.moveTo(rectX + borderRadius, rectY)
|
||||
ctx.quadraticCurveTo(rectX, rectY, rectX, rectY + borderRadius)
|
||||
|
||||
// 左边
|
||||
ctx.lineTo(rectX, rectY + rectHeight - borderRadius)
|
||||
|
||||
// 左下角圆角
|
||||
ctx.quadraticCurveTo(rectX, rectY + rectHeight, rectX + borderRadius, rectY + rectHeight)
|
||||
|
||||
// 下边
|
||||
ctx.lineTo(rectX + rectWidth - borderRadius, rectY + rectHeight)
|
||||
|
||||
// 右下角圆角
|
||||
ctx.quadraticCurveTo(rectX + rectWidth, rectY + rectHeight, rectX + rectWidth, rectY + rectHeight - borderRadius)
|
||||
|
||||
// 右边
|
||||
ctx.lineTo(rectX + rectWidth, rectY + borderRadius)
|
||||
|
||||
// 右上角圆角
|
||||
ctx.quadraticCurveTo(rectX + rectWidth, rectY, rectX + rectWidth - borderRadius, rectY)
|
||||
|
||||
// 上边
|
||||
ctx.lineTo(rectX + borderRadius, rectY)
|
||||
|
||||
ctx.closePath()
|
||||
ctx.fill()
|
||||
|
||||
// 绘制灰色占位符(带内边距)
|
||||
const imgX = -playerImgSize / 2 + padding
|
||||
const imgY = -playerImgSize / 2 + padding
|
||||
const imgSize = playerImgSize - padding * 2
|
||||
|
||||
ctx.setFillStyle('#E0E0E0')
|
||||
ctx.beginPath()
|
||||
const imgRadius = borderRadius - padding
|
||||
|
||||
// 从左上角开始,顺时针绘制
|
||||
// 左上角圆角
|
||||
ctx.moveTo(imgX + imgRadius, imgY)
|
||||
ctx.quadraticCurveTo(imgX, imgY, imgX, imgY + imgRadius)
|
||||
|
||||
// 左边
|
||||
ctx.lineTo(imgX, imgY + imgSize - imgRadius)
|
||||
|
||||
// 左下角圆角
|
||||
ctx.quadraticCurveTo(imgX, imgY + imgSize, imgX + imgRadius, imgY + imgSize)
|
||||
|
||||
// 下边
|
||||
ctx.lineTo(imgX + imgSize - imgRadius, imgY + imgSize)
|
||||
|
||||
// 右下角圆角
|
||||
ctx.quadraticCurveTo(imgX + imgSize, imgY + imgSize, imgX + imgSize, imgY + imgSize - imgRadius)
|
||||
|
||||
// 右边
|
||||
ctx.lineTo(imgX + imgSize, imgY + imgRadius)
|
||||
|
||||
// 右上角圆角
|
||||
ctx.quadraticCurveTo(imgX + imgSize, imgY, imgX + imgSize - imgRadius, imgY)
|
||||
|
||||
// 上边
|
||||
ctx.lineTo(imgX + imgRadius, imgY)
|
||||
|
||||
ctx.closePath()
|
||||
ctx.fill()
|
||||
|
||||
ctx.restore()
|
||||
console.log('球员图片占位符绘制完成')
|
||||
if (data.venueImages.length > 1) {
|
||||
// 后面的图
|
||||
const venueBackConfig = {
|
||||
...venueBaseConfig,
|
||||
venueImage: data.venueImages?.[1],
|
||||
venueImgX: scale * 400 * dpr,
|
||||
venueImgY: scale * 35 * dpr,
|
||||
rotation: scale * -10, // 旋转-10度
|
||||
}
|
||||
await drawVenueImages(ctx, venueBackConfig)
|
||||
// 前面的图
|
||||
const venueFrontConfig = {
|
||||
...venueBaseConfig,
|
||||
venueImage: data.venueImages?.[0],
|
||||
rotation: scale * 8, // 旋转-8度
|
||||
}
|
||||
await drawVenueImages(ctx, venueFrontConfig)
|
||||
} else {
|
||||
await drawVenueImages(ctx, venueBaseConfig)
|
||||
}
|
||||
|
||||
// 绘制球局信息区域
|
||||
@@ -516,8 +548,11 @@ const ShareCardCanvas: React.FC<ShareCardCanvasProps> = ({
|
||||
|
||||
// 球局类型和技能等级
|
||||
const gameInfoY = infoStartY
|
||||
const iconSize = scale * 40
|
||||
// 图标大小
|
||||
const iconSize = scale * 48
|
||||
// 图标距离左侧距离
|
||||
const iconX = scale * 35
|
||||
// 文本距离左侧距离
|
||||
const textX = iconX + iconSize + 20
|
||||
|
||||
// 绘制网球图标
|
||||
@@ -552,45 +587,45 @@ const ShareCardCanvas: React.FC<ShareCardCanvasProps> = ({
|
||||
ctx.drawImage(calendarPath, iconX, timeInfoY, iconSize, iconSize)
|
||||
|
||||
// 绘制日期(绿色)
|
||||
drawText(ctx, data.gameDate, dateX, timeInfoY + 4, 300, timeInfoFontSize, '#4CAF50')
|
||||
drawText(ctx, data.gameDate, dateX, timeInfoY + 8, 300, timeInfoFontSize, '#4CAF50')
|
||||
|
||||
// 绘制时间(黑色)
|
||||
const timeX = textX + ctx.measureText(data.gameDate).width + 10 * dpr
|
||||
drawText(ctx, data.gameTime, timeX, timeInfoY + 4, 300, timeInfoFontSize, '#000000')
|
||||
drawText(ctx, data.gameTime, timeX, timeInfoY + 8, 300, timeInfoFontSize, '#000000')
|
||||
|
||||
// 绘制地点
|
||||
const locationInfoY = infoStartY + infoSpacing * 2
|
||||
const locationFontSize = scale * 22 * dpr
|
||||
const locationPath = await loadImage("https://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/adc9a167-2ea9-4e3b-b963-6a894a1fd91b.jpg")
|
||||
ctx.drawImage(locationPath, iconX, locationInfoY, iconSize, iconSize)
|
||||
drawText(ctx, data.venueName, danDaX, locationInfoY + 4, 600, locationFontSize, '#000000')
|
||||
drawText(ctx, data.venueName, danDaX, locationInfoY + 10, 600, locationFontSize, '#000000')
|
||||
|
||||
// 绘制完成,调用draw方法
|
||||
console.log('开始调用ctx.draw()')
|
||||
ctx.draw(false, () => {
|
||||
console.log('Canvas绘制完成,开始生成图片...')
|
||||
// 延迟一下再生成图片,确保绘制完成
|
||||
setTimeout(() => {
|
||||
Taro.canvasToTempFilePath({
|
||||
canvasId: 'shareCardCanvas',
|
||||
fileType: 'png',
|
||||
quality: 1,
|
||||
success: (res) => {
|
||||
console.log('图片生成成功:', res.tempFilePath)
|
||||
setIsDrawing(false) // 绘制完成,重置状态
|
||||
resolve(res.tempFilePath)
|
||||
onGenerated?.(res.tempFilePath)
|
||||
setTempImagePath(res.tempFilePath)
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('图片生成失败:', error)
|
||||
setIsDrawing(false) // 绘制失败,重置状态
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
}, 500) // 延迟500ms确保Canvas完全渲染
|
||||
})
|
||||
console.log('Canvas绘制命令已发送')
|
||||
// 绘制完成,调用draw方法
|
||||
console.log('开始调用ctx.draw()')
|
||||
ctx.draw(false, () => {
|
||||
console.log('Canvas绘制完成,开始生成图片...')
|
||||
// 延迟一下再生成图片,确保绘制完成
|
||||
setTimeout(() => {
|
||||
Taro.canvasToTempFilePath({
|
||||
canvasId: 'shareCardCanvas',
|
||||
fileType: 'png',
|
||||
quality: 1,
|
||||
success: (res) => {
|
||||
console.log('图片生成成功:', res.tempFilePath)
|
||||
setIsDrawing(false) // 绘制完成,重置状态
|
||||
resolve(res.tempFilePath)
|
||||
onGenerated?.(res.tempFilePath)
|
||||
setTempImagePath(res.tempFilePath)
|
||||
},
|
||||
fail: (error) => {
|
||||
console.error('图片生成失败:', error)
|
||||
setIsDrawing(false) // 绘制失败,重置状态
|
||||
reject(error)
|
||||
}
|
||||
})
|
||||
}, 500) // 延迟500ms确保Canvas完全渲染
|
||||
})
|
||||
console.log('Canvas绘制命令已发送')
|
||||
|
||||
} catch (error) {
|
||||
console.error('绘制分享卡片失败:', error)
|
||||
@@ -613,7 +648,10 @@ const ShareCardCanvas: React.FC<ShareCardCanvasProps> = ({
|
||||
console.log('组件挂载,开始绘制分享卡片')
|
||||
// 延迟一下确保Canvas已经渲染
|
||||
setTimeout(() => {
|
||||
drawShareCard()
|
||||
// 在微信小程序中,需要使用Taro.createCanvasContext
|
||||
const ctx = Taro.createCanvasContext('shareCardCanvas')
|
||||
console.log('Canvas上下文创建成功:', ctx)
|
||||
drawShareCard(ctx)
|
||||
}, 500)
|
||||
}
|
||||
}, [data]) // 只依赖data,移除canvasWidth避免无限循环
|
||||
|
||||
Reference in New Issue
Block a user