当前位置:网站首页>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)
})
},
边栏推荐
- LeetCode 0142.环形链表 II
- Postgresql14 installation and master-slave configuration
- MySQL开发技巧——视图
- 【Utils】FastDFS工具类
- 什么是自旋锁 自旋锁是指当一个线程尝试获取某个锁时,如果该锁已被其他线程占用,就一直循环检测锁是否被释放,而不是进入线程挂起或睡眠状态。 /** * 为什么用自旋锁:多个线程对同一个变量
- Slam thesis collection
- 基于NoneBot2的qq机器人配置记录
- Websocket chat
- 走进音视频的世界——FLV视频封装格式
- R language uses LM function to build multiple linear regression model, writes regression equation according to model coefficient, and uses conflict function to give 95% confidence interval of regressi
猜你喜欢

Security assurance is based on software life cycle -psp application

《机器学习》(周志华) 第6章 支持向量 学习心得 笔记

QT自制软键盘 最完美、最简单、跟自带虚拟键盘一样

多级缓存方案

在centos中安装mysql5.7.36

LeetCode 105.从前序与中序遍历序列构造二叉树 && 106.从中序与后序遍历序列构造二叉树

Redis sentinel mechanism

离散对数问题(DLP) && Diffie-Hellman问题(DHP)

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

Algorithm --- different paths (kotlin)
随机推荐
Socket类关于TCP字符流编程的理解学习
Rolling update strategy of deployment.
Security assurance is based on software life cycle - networkpolicy application
【LVGL事件(Events)】事件代码
R language test sample proportion: use prop The test function performs the single sample proportion test to calculate the confidence interval of the p value of the successful sample proportion in the
Security assurance is based on software life cycle -istio authentication mechanism
Jmeter安装教程及登录增加token
线程阻塞的三种情况。
es6你用过哪些惊艳的写法
RSA用私钥加密数据公钥解密数据(不是签名验证过程)
jenkins
30 day question brushing plan (II)
多线程与高并发(三)—— 源码解析 AQS 原理
TS literacy method - Basic chapter
R language uses LM function to build linear regression model and subset function to specify subset of data set to build regression model (use floor function and length function to select the former pa
DXF读写:对齐尺寸标注文字居中、上方的位置计算
[lvgl events] Application of events on different components (I)
【翻译】盐业公司来Linkerd公司是为了负载平衡,留下来是为了效率、可靠性和性能。...
多级缓存方案
Redis sentinel mechanism