当前位置:网站首页>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
 Insert picture description here
The following is the general effect of my canvas Export The name uses a font here , The white outline is the font outline filling
 Please add a picture description

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
 Insert picture description here

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)
			})

		},
原网站

版权声明
本文为[Ao Houhou~~]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/209/202207281311013820.html