|
@ -0,0 +1,250 @@ |
|
|
|
|
|
<template> |
|
|
|
|
|
<view class="page__view"> |
|
|
|
|
|
|
|
|
|
|
|
<!-- 导航栏 --> |
|
|
|
|
|
<navbar leftClick @leftClick="$utils.navigateBack" bgColor="#4883F9" color="#FFFFFF" /> |
|
|
|
|
|
|
|
|
|
|
|
<view style="width: 750rpx; height: 1184rpx; overflow: hidden;"> |
|
|
|
|
|
<canvas id="myCanvas" canvas-id="firstCanvas1" type="2d" style="width: 100%; height: 100%;"></canvas> |
|
|
|
|
|
</view> |
|
|
|
|
|
|
|
|
|
|
|
<view class="flex bottom"> |
|
|
|
|
|
<view class="flex"> |
|
|
|
|
|
<button class="btn" @click="saveImg">保存到手机</button> |
|
|
|
|
|
</view> |
|
|
|
|
|
</view> |
|
|
|
|
|
|
|
|
|
|
|
</view> |
|
|
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
|
|
<script> |
|
|
|
|
|
export default { |
|
|
|
|
|
data() { |
|
|
|
|
|
return { |
|
|
|
|
|
wxCodeImage: '', |
|
|
|
|
|
baseUrl: 'https://image.hhlm1688.com/', |
|
|
|
|
|
canvas: {}, |
|
|
|
|
|
details: {}, |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
async onLoad({ thesisId }) { |
|
|
|
|
|
await this.getData(thesisId) |
|
|
|
|
|
await this.fetchQrCode() |
|
|
|
|
|
this.draw() |
|
|
|
|
|
}, |
|
|
|
|
|
methods: { |
|
|
|
|
|
async getData(thesisId) { |
|
|
|
|
|
try { |
|
|
|
|
|
this.details = await this.$fetch('queryThesisById', { thesisId }) |
|
|
|
|
|
} catch (err) { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}, |
|
|
|
|
|
async fetchQrCode() { |
|
|
|
|
|
try { |
|
|
|
|
|
// todo: check api |
|
|
|
|
|
this.wxCodeImage = (await this.$fetch('getInviteCode'))?.url |
|
|
|
|
|
|
|
|
|
|
|
} catch (err) { |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
drawTextWithManualLineBreaks(ctx, text, x, y, maxWidth, lineHeight) { |
|
|
|
|
|
let rows = 0 |
|
|
|
|
|
let size = 0 |
|
|
|
|
|
let lines = text.split('\n'); // 支持手动输入的换行符 |
|
|
|
|
|
|
|
|
|
|
|
for (let lIdx = 0; lIdx < lines.length; lIdx++) { |
|
|
|
|
|
let line = lines[lIdx] |
|
|
|
|
|
let row = '' |
|
|
|
|
|
|
|
|
|
|
|
for (let wIdx = 0; wIdx < line.length; wIdx++) { |
|
|
|
|
|
let word = line[wIdx] |
|
|
|
|
|
let metrics = ctx.measureText(row + word); |
|
|
|
|
|
if (metrics.width > maxWidth) { |
|
|
|
|
|
rows++ |
|
|
|
|
|
size += row.length |
|
|
|
|
|
console.log('--rows', rows, '--size', size) |
|
|
|
|
|
if (rows === 4 && size < text.length) { |
|
|
|
|
|
row = row.slice(0, -2) + '......' |
|
|
|
|
|
} |
|
|
|
|
|
ctx.fillText(row, x, y); |
|
|
|
|
|
row = '' |
|
|
|
|
|
y += lineHeight |
|
|
|
|
|
if (rows === 4) { |
|
|
|
|
|
break |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
row += word |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (rows === 4) { |
|
|
|
|
|
break |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (row) { |
|
|
|
|
|
rows++ |
|
|
|
|
|
size += row.length |
|
|
|
|
|
console.log('--rows', rows, '--size', size) |
|
|
|
|
|
if (rows === 4 && size < text.length) { |
|
|
|
|
|
row = row.slice(0, -2) + '......' |
|
|
|
|
|
} |
|
|
|
|
|
ctx.fillText(row, x, y); |
|
|
|
|
|
y += lineHeight |
|
|
|
|
|
|
|
|
|
|
|
if (rows === 4) { |
|
|
|
|
|
break |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}, |
|
|
|
|
|
draw() { |
|
|
|
|
|
|
|
|
|
|
|
uni.showLoading({ |
|
|
|
|
|
title: "拼命绘画中..." |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
wx.createSelectorQuery() |
|
|
|
|
|
.select('#myCanvas') // 绘制的canvas的id |
|
|
|
|
|
.fields({ |
|
|
|
|
|
node: true, |
|
|
|
|
|
size: true |
|
|
|
|
|
}) |
|
|
|
|
|
.exec(async (res) => { |
|
|
|
|
|
const canvas = res[0].node |
|
|
|
|
|
// 渲染上下文 |
|
|
|
|
|
const ctx = canvas.getContext('2d') |
|
|
|
|
|
// Canvas 画布的实际绘制宽高 |
|
|
|
|
|
const width = res[0].width |
|
|
|
|
|
const height = res[0].height |
|
|
|
|
|
// 初始化画布大小 |
|
|
|
|
|
const dpr = wx.getWindowInfo().pixelRatio |
|
|
|
|
|
|
|
|
|
|
|
//根据dpr调整 |
|
|
|
|
|
// dpr 2 4 |
|
|
|
|
|
// 3 6 |
|
|
|
|
|
console.log("--dpr", dpr) |
|
|
|
|
|
canvas.width = width * dpr |
|
|
|
|
|
canvas.height = height * dpr |
|
|
|
|
|
|
|
|
|
|
|
let Ratio = canvas.width / 750 |
|
|
|
|
|
|
|
|
|
|
|
this.canvas = canvas |
|
|
|
|
|
ctx.scale(dpr, dpr) |
|
|
|
|
|
ctx.clearRect(0, 0, width, height) |
|
|
|
|
|
|
|
|
|
|
|
ctx.fillStyle = '#fff' |
|
|
|
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height) |
|
|
|
|
|
|
|
|
|
|
|
ctx.fillStyle = '#999999'; |
|
|
|
|
|
const fontSize = 28 * Ratio / dpr |
|
|
|
|
|
ctx.font = `${fontSize}px PingFangSC-regular`; |
|
|
|
|
|
|
|
|
|
|
|
const descX = 37 * Ratio / dpr |
|
|
|
|
|
const descY = 751 * Ratio / dpr |
|
|
|
|
|
const maxWidth = 677 * Ratio / dpr |
|
|
|
|
|
const lineHeight = 45 * Ratio / dpr |
|
|
|
|
|
this.drawTextWithManualLineBreaks(ctx, this.details.paperDesc, descX, descY, maxWidth, lineHeight) |
|
|
|
|
|
|
|
|
|
|
|
// 海报图片 |
|
|
|
|
|
const paperImage = canvas.createImage() |
|
|
|
|
|
paperImage.src = this.details.paperImage |
|
|
|
|
|
paperImage.onload = () => { |
|
|
|
|
|
const x = 37 * Ratio / dpr |
|
|
|
|
|
const y = 21 * Ratio / dpr |
|
|
|
|
|
const w = 677 * Ratio / dpr |
|
|
|
|
|
const h = 687 * Ratio / dpr |
|
|
|
|
|
ctx.drawImage(paperImage, x, y, w, h) |
|
|
|
|
|
|
|
|
|
|
|
//二维码图片 |
|
|
|
|
|
const coderImage = canvas.createImage() |
|
|
|
|
|
coderImage.src = this.wxCodeImage |
|
|
|
|
|
coderImage.onload = () => { |
|
|
|
|
|
const x = 539 * Ratio / dpr |
|
|
|
|
|
const y = 987 * Ratio / dpr |
|
|
|
|
|
const size = 162 * Ratio / dpr |
|
|
|
|
|
ctx.drawImage(coderImage, x, y, size, size) |
|
|
|
|
|
|
|
|
|
|
|
uni.hideLoading() |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
}, |
|
|
|
|
|
saveImg() { |
|
|
|
|
|
this.$authorize('scope.writePhotosAlbum').then((res) => { |
|
|
|
|
|
this.imgApi() |
|
|
|
|
|
}) |
|
|
|
|
|
}, |
|
|
|
|
|
imgApi() { |
|
|
|
|
|
wx.canvasToTempFilePath({ |
|
|
|
|
|
x: 0, |
|
|
|
|
|
y: 0, |
|
|
|
|
|
width: this.canvas.width, |
|
|
|
|
|
height: this.canvas.height, |
|
|
|
|
|
canvas: this.canvas, |
|
|
|
|
|
success: (res) => { |
|
|
|
|
|
let tempFilePath = res.tempFilePath; |
|
|
|
|
|
this.saveImgToPhone(tempFilePath) |
|
|
|
|
|
}, |
|
|
|
|
|
fail: (err) => { |
|
|
|
|
|
console.log('--canvasToTempFilePath--fail', err) |
|
|
|
|
|
} |
|
|
|
|
|
}, this); |
|
|
|
|
|
|
|
|
|
|
|
}, |
|
|
|
|
|
saveImgToPhone(image) { |
|
|
|
|
|
/* 获取图片的信息 */ |
|
|
|
|
|
uni.getImageInfo({ |
|
|
|
|
|
src: image, |
|
|
|
|
|
success: function(image) { |
|
|
|
|
|
/* 保存图片到手机相册 */ |
|
|
|
|
|
uni.saveImageToPhotosAlbum({ |
|
|
|
|
|
filePath: image.path, |
|
|
|
|
|
success: function() { |
|
|
|
|
|
uni.showModal({ |
|
|
|
|
|
title: '保存成功', |
|
|
|
|
|
content: '图片已成功保存到相册', |
|
|
|
|
|
showCancel: false |
|
|
|
|
|
}); |
|
|
|
|
|
}, |
|
|
|
|
|
complete(res) { |
|
|
|
|
|
console.log(res); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}, |
|
|
|
|
|
} |
|
|
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss"> |
|
|
|
|
|
|
|
|
|
|
|
.page__view { |
|
|
|
|
|
background: $uni-bg-color-grey; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.bottom { |
|
|
|
|
|
position: fixed; |
|
|
|
|
|
left: 0; |
|
|
|
|
|
bottom: 0; |
|
|
|
|
|
width: 100vw; |
|
|
|
|
|
height: 154rpx; |
|
|
|
|
|
padding-bottom: env(safe-area-inset-bottom); |
|
|
|
|
|
background: #FFFFFF; |
|
|
|
|
|
|
|
|
|
|
|
.btn { |
|
|
|
|
|
padding: 20rpx 77rpx; |
|
|
|
|
|
font-size: 28rpx; |
|
|
|
|
|
color: #FFFFFF; |
|
|
|
|
|
background: #4883F9; |
|
|
|
|
|
border-radius: 14rpx; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
</style> |