当前位置:网站首页>Solve the problem that uniapp wechat applet canvas cannot introduce fonts
Solve the problem that uniapp wechat applet canvas cannot introduce fonts
2022-07-28 14:10:00 【Ao Houhou~~】
This is the recent fix problem of wechat applet , It's about loadFontFace Repair of
Adjust the debugging base library to 2.25.1, I just adjusted to this version, and I didn't try other versions 
The following is the general effect of my canvas Export The name uses a font here , The white outline is the font outline filling 
The first thing to know is api name :uni.loadfontface
here source There can only be network links , Because I don't have a server , I don't want to install local services , So what I use is vscode in Live server Then visit the font link to get the effect first , Then configure the security domain name on the server
scopes This attribute ,native It means that you can be in canvas2d Use this font in
Here are some necessary code snippets
The general logic is to get the canvas object after the font is loaded successfully, draw the text on the canvas, and then export base64 Pictures of the
as for 750 and 176 It's the logic of my code , It can be dynamically modified or written according to your own code logic
<template>
<canvas type="2d" id="canvasName" :style="{width:750 + 'px',height:176 + 'px'}" />
</template>
<script> let canvas = null let ctx = null let dpr = null uni.loadFontFace({
global: true, family: "DINMedium", source: 'url("http://192.168.108.240:5500/files/iconfont2.ttf")', success: () => {
this.draw() }, scopes: ["webview", "native"], }) methods:{
draw() {
const self = this; let fm = 'DINMedium'; const query = wx.createSelectorQuery() query.select('#canvasName') .fields({
node: true, size: true }) .exec((res) => {
console.log(res) canvas = res[0].node ctx = canvas.getContext('2d') dpr = wx.getSystemInfoSync().pixelRatio canvas.width = res[0].width * dpr canvas.height = res[0].height * dpr ctx.scale(dpr, dpr) let x = 20 let y = 20 let fontSize = 20 this.drawText(ctx, " full name ", 88, "#01A5AE", 750 / 2, 88, 400, true, 'center', true,fm) ctx.lineWidth = 2 ctx.strokeStyle = '#ffffff' // ctx.font = "bold " + fontSize + 'px ' + fm; ctx.strokeText(" full name ", 750 / 2, 88) ctx.restore() this.name = canvas.toDataURL() }) }, drawText(ctx, text, fontSize, color, x, y, maxWidth, bold, align, shadow,fontFamily) {
if (bold) {
ctx.font = `bold ${
fontSize}px ${
fontFamily ? fontFamily : 'normal'}`; } else {
ctx.font = `normal ${
fontSize}px ${
fontFamily ? fontFamily : 'normal'}`; } if (align) {
ctx.textAlign = align } else {
ctx.textAlign = 'left' } ctx.fillStyle = color if (ctx.measureText(text).width > maxWidth) {
var count = 1; while (ctx.measureText(text.slice(0, text.length - count)).width > 693) {
count++ } if (shadow) {
ctx.shadowOffsetX = 3; // Used to set the shadow in X Shaft extension ctx.shadowOffsetX = 3; // Used to set the shadow in Y Shaft extension ctx.shadowBlur = 4; // Sets the blur level of the shadow Default 0 ctx.shadowColor = "rgba(0, 0, 0, 0.5)"; } ctx.fillText(text.slice(0, text.length - (count + 1)) + "...", x, y) } else {
ctx.fillText(text, x, y) } }, } </script>
APP and H5 The font is normal no matter it is used uni.loadFontFace Or use it @font-face Can be used directly , There are many things about small programs 
It is not difficult to find through the above code , I drew this text with font style into a picture , This is because before drawing it, I have used most of the patterns of the Jiugongge picture layout and the base plate uni.createCanvasContext This api Finished drawing , Finally, I found that wechat applet fonts can only be drawn in the above way , In order not to let the previous efforts in vain , I choose to draw the name separately and then draw it base64 Turn it into a temporary link and paint it on the canvas content I have written about the painting process before , So now there are two canvases in the running logic , One is the picture
The following is the base64 The logic of turning into a temporary link , Because I found out base64 You can't draw directly on the canvas on the applet , I split
base64ToTemp(base64){
return new Promise((r) => {
let qrcode = base64.replace(/\. +/g, '').replace(/[\r\n]/g, '')
const fs = wx.getFileSystemManager();
// Randomly define the path name
var times = new Date().getTime();
var codeimg = wx.env.USER_DATA_PATH + '/' + times + '.png';
// take base64 Picture writing
var that = this;
fs.writeFile({
filePath: codeimg,
data: qrcode.split('data:image/png;base64,')[1],
encoding: 'base64',
complete(res) {
console.log(res)
},
success: () => {
r(codeimg)
}
})
})
},
// In order to be compatible with applets and APP So it's handled separately
Using the logical (){
// #ifdef MP
var temp = await this.base64ToTemp(this.name)
console.log(temp)
this.temp = temp
this.ctx.drawImage(temp, 0, 554 * (this
.canvasWidth / 750) - 230, this.canvasWidth, 176)
// #endif
// #ifndef MP
this.drawText(this.ctx, " full name ", 88, "#01A5AE", this.canvasWidth / 2, 554 * (this
.canvasWidth / 750) - 140, 400, true,
'center', true)
this.ctx.lineWidth = 2
this.ctx.setStrokeStyle('#ffffff')
this.ctx.strokeText(" full name ", this.canvasWidth / 2, 554 * (this.canvasWidth / 750) - 140)
this.ctx.restore()
// #endif
}
The following is all the logic that I draw the bottom plate of the Jiugong lattice
Some packaging methods designed can refer to me This article
Some methods are slightly changed, but the logic is the same
squaredDraw() {
var colCount = 3;
var gap = 5;
var imageWidth = (750 - ((colCount - 1) * gap)) / colCount
var TextB = 60
this.canvasWidth = 750
var bottomTitle = 72;
var bottomQrCode = 200;
var QrCodeWidth = 160;
this.canvasHeight = TextB + bottomQrCode + bottomTitle + (imageWidth + 5) * Math.ceil(this.drawImageList
.length / colCount)
this.$nextTick(async () => {
uni.showLoading({
title: " Loading ...",
mask: true
})
this.ctx = uni.createCanvasContext('myCanvas')
this.drawText(this.ctx, " Basketball game basketball game basketball game ", 32, "#222222", 375, 46, 200, true, 'center')
for (let i = 0; i < this.drawImageList.length; i++) {
uni.hideLoading()
uni.showLoading({
title: `(${
i + 1}/${
this.drawImageList.length})`,
mask: true
})
await this.drawImageWidthFix1(this.ctx, this.drawImageList[i] + '?type=1&size=300', (
i % colCount == 0 ? 0 :
(imageWidth + 5) * (i % colCount)), (bottomTitle + (imageWidth + gap) *
parseInt(i / colCount)), imageWidth, imageWidth)
}
uni.hideLoading()
uni.showLoading({
title: ` Generating ...`,
mask: true
})
this.ctx.drawImage('../../static/3.png', (750 - 120) / 2, bottomTitle + (
imageWidth + 5) * Math.ceil(this.drawImageList.length / colCount) + (
bottomQrCode - QrCodeWidth) / 2, QrCodeWidth, QrCodeWidth)
this.drawText(this.ctx, " Text description of basketball game text description of basketball game text description of basketball game ", 32, "#222222", 375, bottomTitle + (
imageWidth + 5) * Math.ceil(this.drawImageList.length / colCount) +
bottomQrCode + 20, 400, true, 'center')
this.ctx.drawImage('../../static/top.png', 0, 0, this.canvasWidth, 554 * (this
.canvasWidth / 750))
// #ifdef MP
var temp = await this.base64ToTemp(this.name)
console.log(temp)
this.temp = temp
this.ctx.drawImage(temp, 0, 554 * (this
.canvasWidth / 750) - 230, this.canvasWidth, 176)
// #endif
// #ifndef MP
this.drawText(this.ctx, " full name ", 88, "#01A5AE", this.canvasWidth / 2, 554 * (this
.canvasWidth / 750) - 140, 400, true,
'center', true)
this.ctx.lineWidth = 2
this.ctx.setStrokeStyle('#ffffff')
this.ctx.strokeText(" full name ", this.canvasWidth / 2, 554 * (this.canvasWidth / 750) - 140)
this.ctx.restore()
// #endif
var bottomImageHeight = 404 * (this.canvasWidth / 750)
var bottomImageTop = this.canvasHeight - bottomImageHeight
this.ctx.drawImage('../../static/bottom.png', 0, bottomImageTop, this.canvasWidth,
bottomImageHeight)
this.drawText(this.ctx, " Inner Mongolia Baotou competition area ", 42, "#ffffff", 53, bottomImageTop + 274, 400, true,
'left', true)
this.ctx.restore()
this.drawText(this.ctx, "2020.04.05", 58, "#ffffff", 132, bottomImageTop + 346, 400, true,
'left', true)
this.ctx.restore()
this.ctx.draw()
setTimeout(() => {
uni.canvasToTempFilePath({
x: 0,
y: 0,
width: this.canvasWidth,
height: this.canvasHeight,
destWidth: this.canvasWidth * 2,
destHeight: this.canvasHeight * 2,
// quality: 0.5,
canvasId: 'myCanvas',
complete: () => {
uni.hideLoading()
},
success: (res) => {
this.imageSrc = res
.tempFilePath
}
})
}, 1200)
})
},
边栏推荐
- 软件测试技术之如何编写测试用例
- 算法---不同路径(Kotlin)
- 掌握常见的几种排序-选择排序
- Custom Configuration Sections
- Rust from introduction to mastery 01 introduction
- Poj3268 shortest path solution
- Security assurance is based on software life cycle -istio authorization mechanism
- Socket class understanding and learning about TCP character stream programming
- Rolling update strategy of deployment.
- Multithreading and high concurrency (III) -- source code analysis AQS principle
猜你喜欢

83.(cesium之家)cesium示例如何运行

每日一题——奖学金

Security assurance is based on software life cycle -psp application

Redis sentinel mechanism

DXF reading and writing: align the calculation of the position of the dimension text in the middle and above

如何有效进行回顾会议(上)?

深度学习基础----GNN谱域和空域 (不断完善更新积累)

第六章 支持向量机

Qt5 development from introduction to mastery -- the first overview

What is the reason why the words behind word disappear when typing? How to solve it?
随机推荐
VOS3000如何呼入送到OKCC
Poj1860 currency exchange solution
DXF reading and writing: align the calculation of the position of the dimension text in the middle and above
Do you really know esmodule
深度学习基础----GNN谱域和空域 (不断完善更新积累)
Clickhouse分布式集群搭建
LeetCode 0143. 重排链表
Postgresql14 installation and master-slave configuration
Docker deploys Mysql to realize remote connection [easy to understand]
30 day question brushing plan (III)
qml 图片预览
TS扫盲大法-基础篇
Duplicate data in leetcode (442) array
了解BFC特性,轻松实现自适应布局
Long closed period private placement products reappearance industry insiders have different views
你真的了解esModule吗
安全保障基于软件全生命周期-PSP应用
7. Dependency injection
Security assurance is based on software life cycle -istio authentication mechanism
【服务器数据恢复】HP StorageWorks系列服务器RAID5两块盘离线的数据恢复