canvas 2d 实现分享海报 (2d的写法, 图片被盖住,图片输出模糊等问题)

时间:2021-10-14
本文章向大家介绍canvas 2d 实现分享海报 (2d的写法, 图片被盖住,图片输出模糊等问题),主要包括canvas 2d 实现分享海报 (2d的写法, 图片被盖住,图片输出模糊等问题)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

小程序官方推荐使用性能更高的canvas 2d实现绘图,仅此随笔记录踩坑过程, 项目使用Taro框架,涉及方法基本与原生小程序自带的方法相同,将Taro.xxx(),改为wx.xxx()即可

canvas 2d 写法

<Canvas
          id='card-canvas'
          type='2d'
          className='card-canvas'
          style={`width: ${300 * rate}px; height: ${470 * rate}px; background-color: #fff; border-radius: ${20 * rate}px; padding: 0px;`}
        ></Canvas>

canvas 2d 使用需要设定type='2d',而非原先的canvseId

    const getCanvas = Taro.createSelectorQuery()
    getCanvas.select('#card-canvas')
      .fields({ node: true, size: true })
      .exec((res) => {
        const _canvas = res[0].node
        const ctx = _canvas.getContext('2d')
        console.log(_canvas, '画布对象', res[0]);
	// 下列几行代码是解决图片模糊问题的关键
        const dpr = Taro.getSystemInfoSync().pixelRatio
        _canvas.width = res[0].width * dpr
        _canvas.height = res[0].height * dpr
        ctx.scale(dpr, dpr)
`Taro.createSelectorQuery() 该方法在此处用于获取canvas对象实例,_cavnas是我们的画布对象,ctx 返回_canvas的内容上下文`

图片模糊问题

图片模糊问题除了长宽比没对齐之外,更大的可能是输出的图片像素不够导致,此处的解决思路是增大图片像素
通过 `const dpr = Taro.getSystemInfoSync().pixelRatio`获取像素比,此处输出dpr为`3`
通过控制台打印`_canvas`对象,可以查看该对象实际宽高,如下图


由于小程序那边我没有找到较为官方的说法,经过多次对比输出后个人总结如下:

width和height是画布内容的实际宽高(像素点),而_height和_width和值是显示宽高,即:如果设置
<cavnas style='width: 312px;height: 489px'>, 当设置_canvas.width = res[0].width * dpr时,
画布的实际像素为936px,而显示像素只有312px>,若此时没有设置ctx.scale(dpr,dpr),画布输出结果如下
画布显示还是`312*489`, 但图片只有原来的三分之一,此时输出的像素确实为`939*1146`,所以应该理解为
`style设置width:312px对应canvas对象的width:936, 而canvas对象的_width是width的映射,即1/3大小`,
若此时加上`ctx.scale(dpr,dpr)`,则图片会撑满整个画布,得到一个实际大小`936*1146`但显示出来的比例为`312*489`的图片


小结:通过_canvas.width= res[0].width * dpr,增加图片像素,再使用ctx.scale(dpr,dpr)将图片拉大至画布大小

图片互相覆盖问题

因为canvas 2d采用的是createImage()创建图片对象并通过onload加载出来,过程会涉及到异步问题,此处的做法是将后面的图片在背景图的onload里调用,以此转换为同步
const img = _canvas.createImage()
img.src = '../xxx.png'
img.onload = () =>{
	ctx.drawImage(img, x, y, width, height)
	contentImg()
}
const contentImg = () =>{
	const content = _canvas.createImage()
	content.src = '../xxx.png'
	cotent.onload = () =>{
	ctx.drawImage(content, x, y, width, height)
	}
	// 文字
	ctx.font = '12px PingFang SC'
	ctx.fillStyle = '#888'
	ctx.fillText('hello', x, y, maxWidth)
}

原文地址:https://www.cnblogs.com/wushengchu/p/15404009.html