解决uniapp微信小程序canvas不能引入字体的问题

这篇具有很好参考价值的文章主要介绍了解决uniapp微信小程序canvas不能引入字体的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这是微信小程序最近修复问题,里面有关于loadFontFace的修复
在使用前要先把调试基础库调整为2.25.1,我调到这个版本就好其他的版本我也没试
解决uniapp微信小程序canvas不能引入字体的问题
下面是我画布导出的大概效果姓名这里使用了字体,白色的轮廓是字体轮廓填充
解决uniapp微信小程序canvas不能引入字体的问题

首先要了解一个api名称:uni.loadfontface
这里source里面只能是网络链接,因为我没有服务器,也不想装搭本地服务,所以我使用的是vscode中Live server然后访问字体链接先把效果搞出来,之后再是上服务器配置安全域名
scopes这个属性,native表示可以在canvas2d中使用这个字体
下面是部分必要代码片段
大致逻辑就是等字体加载成功之后获取画布对象然后把文字绘制到画布上面然后导出base64的图片
至于750和176是我代码的逻辑,按照自己的代码逻辑动态修改或者写死都可以

<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, "姓名", 88, "#01A5AE", 750 / 2, 88, 400, true,
						'center', true,fm)
					ctx.lineWidth = 2
					ctx.strokeStyle = '#ffffff'
					// ctx.font = "bold " + fontSize + 'px ' + fm;
					ctx.strokeText("姓名", 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; //用来设定阴影在 X轴的延伸距
				ctx.shadowOffsetX = 3; //用来设定阴影在 Y轴的延伸距
				ctx.shadowBlur = 4; //设定阴影的模糊程度 默认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和H5字体是正常的不管是用uni.loadFontFace还是用@font-face都可以直接用,就小程序事情多
解决uniapp微信小程序canvas不能引入字体的问题

通过上面代码不难发现,我将这个带字体样式的文字单独绘制成了一张图片,这是因为在绘制它之前我已经把九宫格图片布局以及底板大部分样式已经使用uni.createCanvasContext这个api绘制完了,最后发现微信小程序字体只能通过上面那种方式进行绘制,为了不让之前的努力白费,我选择将名字单独绘制然后将绘制出来的base64转化为一个临时链接绘制到我之前已经写好绘制过程的画布内容上,所以现在的运行逻辑里有两个画布,一个是图片
下面是将base64转成临时链接的逻辑,因为我发现base64在小程序上面不能直接绘制到画布上面,我裂开

base64ToTemp(base64){
	return new Promise((r) => {
		let qrcode = base64.replace(/\. +/g, '').replace(/[\r\n]/g, '')
		const fs = wx.getFileSystemManager();
		//随机定义路径名称
		var times = new Date().getTime();
		var codeimg = wx.env.USER_DATA_PATH + '/' + times + '.png';
		
		//将base64图片写入
		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)
			}
		})
	})
},
// 为了兼容小程序和APP所以这里分开处理了
使用逻辑(){
	// #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, "姓名", 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("姓名", this.canvasWidth / 2, 554 * (this.canvasWidth / 750) - 140)
	this.ctx.restore()
	// #endif
}

下面是我绘制九宫格已经底板的所有逻辑
设计到的一些封装方法可以参考我这个文章
部分方法有点改动不过大逻辑都一样文章来源地址https://www.toymoban.com/news/detail-490964.html

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: "加载中...",
					mask: true
				})
				this.ctx = uni.createCanvasContext('myCanvas')
				this.drawText(this.ctx, "篮球比赛篮球比赛篮球比赛", 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: `生成中...`,
					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, "篮球比赛的文字描述篮球比赛的文字描述篮球比赛的文字描述", 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, "姓名", 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("姓名", 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, "内蒙古包头赛区", 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)
			})

		},

到了这里,关于解决uniapp微信小程序canvas不能引入字体的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 解决在HBuilderX里用uniapp引入vant后在微信小程序里没反应的问题

    在HbuilderX里创建了个uniapp的项目,但是引入vant后,在微信小程序里运行没反应 这是App.vue文件 加了@import 巴拉巴拉那些 问题就出在pages.json文件里, 当我们用快捷输入的 usingComponenets 这个,就有问题了 如果你不是这个原因,那就关了这篇文章吧 如果对你有用,点个赞呗

    2024年02月12日
    浏览(41)
  • uniapp 使用canvas画海报(微信小程序)

    效果展示:  项目要求:点击分享绘制海报,并实现分享到好友,朋友圈,并保存 先实现绘制海报   下面是海报下面的分享弹窗 因为分享到朋友圈实在没找到有使用自定义按钮的可能,所以还是需要点击右上角胶囊    以上就是画海报以及分享的全部过程了,另有一个点:

    2024年02月13日
    浏览(41)
  • 微信小程序canvas绘制自适应图片,UniApp canvas绘制自适应图片

     需求:画布宽高为686 * 686 的正方形(可以进行调整根据自身需要来)             当图片宽度大于高度时,对图片宽度进行裁剪              当图片高度大于宽度时,对图片高度进行裁剪              我是用uniApp进行开发的,如果是小程序原生,直接把“uni” 改为 “

    2024年02月09日
    浏览(43)
  • uniapp微信小程序使用canvas自定义分享名片

    template js 需要分享的页面加上onShareAppMessage,在methods中定义绘画方法createCanvasImage css这里是画布的内容设置

    2024年02月14日
    浏览(36)
  • uniapp 微信小程序canvasToTempFilePath保存的canvas是空白

    问题描述:绘制完canvas后,使用canvasToTempFilePath保存到手机的图片是空白 问题解决: 在绘制图片ctx.draw时,需要使用 箭头函数 调用wx.canvasToTempFilePath 保存图片

    2024年02月15日
    浏览(30)
  • uniapp 微信小程序 placeholder字体、颜色自定义

    效果图: 1、template 2、style

    2024年02月16日
    浏览(38)
  • 微信小程序关于wxs语法、以及能否引入js中的方法(不能调用)

    页面中使用wxs 或者  参考:WXS | 微信开放文档 wxs能引入外部js文件吗 | 微信开放社区 微信小程序中的WXS语法 1、WXS 中不支持let和const,不支持箭头函数。 2、变量命名必须符合下面两个规则: 首字符必须是:字母(a-zA-Z),下划线(_) 剩余字符可以是:字母(a-zA-Z),下划

    2024年02月06日
    浏览(49)
  • uniapp引入微信小程序直播组件

    在manifest.json配置即可,与直接在小程序代码中引入相同。 在工程的manifest.json文件中引入直播插件 通过直播间列表接口查询直播间列表,显示在小程序中 点击直播间,跳转到小程序直播组件即可 未整理参考 未整理参考 未整理参考

    2024年02月22日
    浏览(32)
  • 【uniapp】使用canvas组件编译到微信小程序兼容出错问题

    使用uniapp编译跨平台项目会遇到不少兼容问题,这里主要讲canvas组件的,编译到微信小程序会有兼容出错问题,这里给讲一下解决方案,希望有帮助。 如果使用 CanvasContext 绘制,以下代码,编译到微信小程序上可能发现绘制不出来 看canvas组件的属性 type=\\\"2d\\\" 是否有加,要去掉

    2024年02月02日
    浏览(54)
  • uniapp微信小程序引入vant组件库

    1、首先要有uniapp项目,根据vant官方文档使用yarn或npm安装依赖: 安装完依赖如下: 2、在uniapp项目根目录下(也可以指定目录)本案例在根目录下新建:wxcomponents文件夹 !!!!必须是wxcomponents文件夹! !!!!必须是wxcomponents文件夹! !!!!必须是wxcomponents文件夹! (原

    2024年02月16日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包