当前位置:网站首页>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)
- 阿里、京东、抖音:把云推向产业心脏
- Do you really know esmodule
- Slam thesis collection
- 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
- 【Utils】CookieUtil
- strcmp、strstr、memcpy、memmove的实现
- 彻底掌握二分查找
- How to configure ADB environment variables (where to open environment variables)
- Clickhouse架构与设计
猜你喜欢

算法---不同路径(Kotlin)

Clickhouse分布式集群搭建

Redis sentinel mechanism

在centos中安装mysql5.7.36

Multi level cache scheme

对“Image Denoising Using an Improved Generative Adversarial Network with Wasserstein Distance“的理解

JMeter installation tutorial and login add token

Istio四之故障注入和链路追踪

SLAM论文合集

论文研读--Masked Generative Distillation
随机推荐
【Utils】FastDFS工具类
每日一题——奖学金
30 day question brushing plan (IV)
算法---不同路径(Kotlin)
Understand the principle behind the virtual list, and easily realize the virtual list
strcmp、strstr、memcpy、memmove的实现
浅谈WebSocket
Operator3 - design an operator
[lvgl events] event code
Dojnoip201708 cheese solution
作为一个程序员,如何高效的管理时间?
Intersectionobserver
TS literacy method - Basic chapter
VOS3000如何呼入送到OKCC
Istio四之故障注入和链路追踪
30 day question brushing plan (III)
83.(cesium之家)cesium示例如何运行
A label_ File download (download attribute)
掌握闭包,夯实基本功
【Try to Hack】HFish蜜罐部署