前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Canvas学习笔记,记录使用过程中遇到的一些问题

Canvas学习笔记,记录使用过程中遇到的一些问题

作者头像
房东的狗丶
发布2023-02-17 15:16:45
9080
发布2023-02-17 15:16:45
举报
文章被收录于专栏:友人a的笔记丶

2022-11-07

1.反向绘制

fill(),方法用于填充已有的闭合路径,假设有一个如下图的路径,默认情况下圆和方形都会被填充,最后的效果就是一个黑色的方形;

demo

通过fillRule参数,可以指定填充的算法,决定点是在路径内还是在路径外。 允许的值:

  • "nonzero": 非零环绕规则,默认的规则。
  • "evenodd": 奇偶环绕规则。

将填充规则设置为evenodd,绘制的结果会变为下面这样,通过这种方式可以实现反向裁剪。

图片说明文字

通过destination-out的擦除效果,同意可以实现上面的效果

代码语言:javascript
复制
/* 保存状态 */
context.save();
context.fillStyle = "rgba(246,246,246,0.6)"; //背景色
context.fillRect(0, 0, canvas_w, canvas_h); //画圆
context.globalCompositeOperation = "destination-out"

context.fillStyle = "rgba(255,255,255,1)"; //背景色
context.fillRect(x, y, w, h); //画圆
context.restore(); //恢复状态

2.原地旋转

默认的旋转是通过改变坐标系的角度实现的(矩阵),所以旋转后中心点不会在原来的地方;

代码语言:javascript
复制
/* 角度换算弧度 */
let rotateRadius=45*Math.PI/180

/*计算方形的中心点 */
let rectCenterPoint = {
    x: x + w / 2,
    y: y + h / 2
};

/* 旋转的同时,让中心点回到原来的位置 */
context.translate(rectCenterPoint.x, rectCenterPoint.y);
context.rotate(rotateRadius); //旋转
context.translate(-rectCenterPoint.x, -rectCenterPoint.y);

3.原地缩放

默认的旋转是通过改变坐标系的刻度实现的(矩阵),所以缩放后中心点不会在原来的地方;

代码语言:javascript
复制
/* 倍数 */
let scaleRadio=1.5

/*计算方形的中心点 */
let rectCenterPoint = {
    x: x + w / 2,
    y: y + h / 2
};

/* 中心点复位 */
context.translate(
    rectCenterPoint.x * (1 - scaleRadio),
    rectCenterPoint.y * (1 - this.scaleRadio));
context.scale(scaleRadio, scaleRadio);

4.clearRect

如果没有依照 绘制路径 的步骤(begin、close),使用 clearRect() 会导致意想之外的结果(线条乱窜),在调用 clearRect()之后绘制新内容前调用beginPath() 。

5.drawImage模糊

在 iPhone3G 时代,屏幕宽度是 320px,其宽度上的物理像素也是 320px;而到了 4s 时代,屏幕宽度依然是 320px,但是宽度上的物理像素却变成了 640px,是宽度的两倍

屏幕宽度没变,物理像素却增加了,所以为了屏幕显示的内容不改变,原先需要一个像素绘制的点,现在会用两个像素来绘制,为了表示这种屏幕的特性,浏览器全局对象下就有了这样一个属性——devicePixelRatio设备像素比,它的计算方式是 物理像素 / 屏幕宽度的像素;

  • 首先设置canvas的宽度和高度是原来的2倍
  • 使用ctx.scale(2,2)设置绘制的东西也放大2倍
  • 在canvas的父元素上使用缩放,使用css3的 transform:scale(0.5,0.5)即可,意思为缩放到原来的2倍大小,和canvas放大两倍刚好抵消掉。

提示

canvas 绘图时,会从两个物理像素的中间位置开始绘制并向两边扩散 0.5 个物理像素。当设备像素比为 1 时,一个 1px 的线条实际上占据了两个物理像素(每个像素实际上只占一半),由于不存在 0.5 个像素,所以这两个像素本来不应该被绘制的部分也被绘制了,于是 1 物理像素的线条变成了 2 物理像素,视觉上就造成了模糊

6.分层渲染

将多个canvas叠在一起,通过设置每个canvas的 z-index 达到多个画布还是在同一层的错觉;

7.局部渲染

静态画面,本身就可以清空指定区域,然后指定那个区域重新绘制新图行。

8.离屏渲染

OffscreenCanvas提供了一个可以脱离屏幕渲染的canvas对象。它在窗口环境和web worker环境均有效。(一个不在屏幕上实际显示的画布)

代码语言:javascript
复制
 // 离屏canvas 
 const offscreen = new OffscreenCanvas(200, 200);

通过transferToImageBitmap函数可以从OffscreenCanvas对象的绘制内容创建一个ImageBitmap对象。该对象可以用于到其他canvas的绘制。

9.矩阵变换

向量是有长度及方向的量,一般由多个标量(scalar,即单纯的数字)组合而成。比如由两个标量组合而成的二维向量,可以表示二维空间(平面)中有长度及方向的量。由三个标量组成的三维向量,可以表示三维空间中具有长度及方向的量;

矩阵

平移

旋转

缩放

参考:https://www.modb.pro/db/418935

10.touchmove

触发touchstart事件之后,假如move的距离特别小,就不会触发toucemove事件。

所以图形拖动的时候,以touchstart事件的坐标作为拖动的参照点时会产生偏差,结果就是拖动开始的时候,图形会瞬移一段距离。

可以将参照点的坐标调整为第一次touchmove事件触发时的坐标。

2022-11-09

1. canvas导出模糊

移动端受限于屏幕,实际能看到的画布只有手机的大小,按照手机的分辨率导出canvas作为图片,分辨率确实太低了。

可以在导出之前将canvas的长宽放大指定倍数,同时将图形放大,之后再通过toDataURL导出,分辨率相对来说就高了。

小贴士

离屏canvas没有toDataURL方法

2022-11-15

1.放大canvas

canvas的分辨率是实际分辨率的两倍,此时保持图形正常绘制,原点,大小都要跟着放大。

屏幕坐标换算到画布上需要乘以放大的倍数。

2.图形选中

2.1 范围判断

以正方形为例,正常情况下可通过如下算法去判断图形是否被点击(点击point,图形rect)。

代码语言:javascript
复制
if (
    point.x > rect.x  &&
    point.x < rect.x + rect.w &&
    point.y > rect.y  &&
    point.y < rect.y + rect.h
) {
    return true;
} else {
    return false;
}

方大之后这个判断方法仍然有效,但是旋转之后,图形有一部分就点不到了。

2.2 isPointInPath

不管是方形、图片、还是其他的,描绘一个相同的路径(位移、旋转、缩放),都可以进行如下判断

代码语言:javascript
复制
context.beginPath();
context.rect(x, y, w, h);
context.closePath();
this.clicked = context.isPointInPath(point.x, point.y);
2.3 离屏绘制

每个图形在离屏画布上绘制一个大小状态一样的图片,并使用唯一的颜色值填充,这个颜色值就代表这个图形的索引。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-11-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2022-11-07
    • 1.反向绘制
      • 2.原地旋转
        • 3.原地缩放
          • 4.clearRect
            • 5.drawImage模糊
              • 6.分层渲染
                • 7.局部渲染
                  • 8.离屏渲染
                    • 9.矩阵变换
                      • 10.touchmove
                      • 2022-11-09
                        • 1. canvas导出模糊
                        • 2022-11-15
                          • 1.放大canvas
                            • 2.图形选中
                              • 2.1 范围判断
                              • 2.2 isPointInPath
                              • 2.3 离屏绘制
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档