Meqn / store

转载 && 收藏 && 乱七八糟 :clap:
63 stars 9 forks source link

Canvas文档 #39

Open Meqn opened 3 years ago

Meqn commented 3 years ago

目录


系列教程

Meqn commented 3 years ago

js文档:https://www.canvasapi.cn/
教程:https://wangdoc.com/webapi/canvas.html
参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial
示例:https://www.twle.cn/l/yufei/canvas/canvas-basic-index.html
MDN: CanvasRenderingContext2D API接口参考
贝塞尔曲线 - 维基百科

canvas 文档

目录

1. 绘制形状

Canvas 画布提供了一个作图的平面空间,该空间的每个点都有自己的坐标。原点(0, 0)位于图像左上角,x轴的正向是原点向右,y轴的正向是原点向下。

路径

图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。一个路径,甚至一个子路径,都是闭合的。使用路径绘制图形需要一些额外的步骤。

  1. 首先,你需要创建路径起始点。
  2. 然后你使用画图命令去画出路径。
  3. 之后你把路径封闭。
  4. 一旦路径生成,你就能通过描边或填充路径区域来渲染图形。

以下方法和属性用来绘制路径:

function draw() {
  var canvas = document.getElementById('canvas');
  if (canvas.getContext){
    var ctx = canvas.getContext('2d');
        // 笑脸
    ctx.beginPath();
    ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // 绘制外圆
    ctx.moveTo(110, 75);
    ctx.arc(75, 75, 35, 0, Math.PI, false);   // 口(顺时针)
    ctx.moveTo(65, 65);
    ctx.arc(60, 65, 5, 0, Math.PI * 2, true);  // 左眼
    ctx.moveTo(95, 65);
    ctx.arc(90, 65, 5, 0, Math.PI * 2, true);  // 右眼
    ctx.strokeStyle = "blue"
    ctx.stroke();

    // 扇形
    ctx.beginPath();
    ctx.moveTo(83, 102);
    ctx.bezierCurveTo(83, 94, 89, 88, 97, 88); // 左上1/4圆
    ctx.bezierCurveTo(105, 88, 111, 94, 111, 102); // 右上1/4圆
    ctx.lineTo(97, 116);
    ctx.lineTo(83, 102);
    ctx.strokeStyle = 'red'
    ctx.stroke();
  }
}

线型

lineTo() 绘制直线.

线形的控制属性

弧线

context.arc(x, y, radius, startAngle, endAngle [, anticlockwise]);
// `x, y`: 圆弧对应的圆心横坐标
// `radius`: 圆弧的半径大小。
// `startAngle`: 圆弧开始的角度,单位是弧度。
// `endAngle`: 圆弧结束的角度,单位是弧度。
// `anticlockwise`: 画图时应该逆时针画(true)还是顺时针画(false),这个参数用来控制扇形的方向(比如上半圆还是下半圆)。

context.arcTo(x1, y1, x2, y2, radius)
// `x1, y1`: 是第1个控制点的横坐标;
// `x2, y2`: 是第2个控制点的横坐标;
// `radius`: 是圆弧的半径大小。

注意:arc()函数中表示角的单位是弧度,不是角度。
角度与弧度的js表达式:弧度=(Math.PI/180)*角度。
比如:ctx.arc(60, 60, 50, 0, Math.PI * 2, true) 绘制了一个半径50,起始角度为0,终止角度为 2 * PI 的完整的圆。

贝塞尔曲线

cubic-bezier

贝塞尔曲线 - 维基百科

椭圆

ellipse() 是 Canvas 2D API 添加椭圆路径的方法。椭圆的圆心在(x,y)位置,半径分别是radiusXradiusY ,按照anticlockwise(默认顺时针)指定的方向,从 startAngle 开始绘制,到 endAngle 结束。

ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);
// `x, y`: 椭圆圆心的坐标
// `radiusX`: 椭圆长轴的半径
// `radiusY`: 椭圆短轴的半径
// `rotation, startAngle`: 椭圆将要绘制的起始点和结束点角度,以弧度表示(非角度度数)。
// `anticlockwise`: 如果为 true,逆时针方向绘制椭圆 (逆时针), 反之顺时针方向绘制。

// Demo
ctx.ellipse(100, 100, 50, 75, 45 * Math.PI/180, 0, 2 * Math.PI); //倾斜45°角

Path2D 对象

正如我们所讲,你可以使用一系列的路径和绘画命令来把对象“画”在画布上。为了简化代码和提高性能,Path2D对象已可以在较新版本的浏览器中使用,用来缓存或记录绘画命令,这样你将能快速地回顾路径。

所有的路径方法比如moveTo, rect, arcquadraticCurveTo等,如我们前面见过的,都可以在Path2D中使用。Path2D还有另一个强大的特点,就是使用SVG path data来初始化canvas上的路径。这将使你获取路径时可以以SVG或canvas的方式来重用它们。

const square = new Path2D("M10 10 h 80 v 80 h -80 Z")
ctx.stroke(square)

矩形

以下方法用来绘制矩形:

上面四个方法的格式都一样,都接受四个参数,分别是矩形左上角的横坐标和纵坐标、矩形的宽和高。

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

// line画矩形路径,填充
ctx.moveTo(10, 100)
ctx.lineTo(60, 100)
ctx.lineTo(60, 150)
ctx.lineTo(10, 150)
ctx.fillStyle = 'pink'
ctx.fill()

// rect画矩形路径,填充
ctx.beginPath()
ctx.rect(10, 10, 50, 50)
ctx.fillStyle = 'blue'
ctx.fill()

// fillRect 画矩形
ctx.fillStyle = 'green'
ctx.fillRect(80, 10, 50, 50)

// strokeRect 矩形描边
ctx.strokeStyle = 'red'
ctx.strokeRect(150, 10, 50, 50)

// clearRect 清除矩形区域内容
ctx.clearRect(40, 30, 60, 20)

文本

canvas 提供了fillText()strokeText()两种方法来渲染文本。

文本样式属性:

渐变和图案填充

线性渐变

ctx.createLinearGradient(x0, y0, x1, y1)

x0y0是起点的横坐标和纵坐标,x1y1是终点的横坐标和纵坐标。通过不同的坐标值,可以生成从上至下、从左到右的渐变等等。

该方法的返回值是一个CanvasGradient对象,该对象只有一个addColorStop()方向,用来指定渐变点的颜色。addColorStop()方法接受两个参数,第一个参数是0到1之间的一个位置量,0表示起点,1表示终点,第二个参数是一个字符串,表示 CSS 颜色。

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');

var gradient = ctx.createLinearGradient(0, 0, 200, 0);
gradient.addColorStop(0, 'green');
gradient.addColorStop(1, 'white');
ctx.fillStyle = gradient;
ctx.fillRect(10, 10, 200, 100);

辐射渐变

createRadialGradient()方法定义一个辐射渐变,需要指定两个圆。

ctx.createRadialGradient(x0, y0, r0, x1, y1, r1)

x0y0是辐射起始的圆的圆心坐标,r0是起始圆的半径,x1y1是辐射终止的圆的圆心坐标,r1是终止圆的半径。

图像填充

createPattern()方法定义一个图像填充样式,在指定方向上不断重复该图像,填充指定的区域。

ctx.createPattern(image, repetition)

该方法接受两个参数,第一个参数是图像数据,它可以是<img>元素,也可以是另一个<canvas>元素,或者一个表示图像的 Blob 对象。第二个参数是一个字符串,有四个可能的值,分别是repeat(双向重复)、repeat-x(水平重复)、repeat-y(垂直重复)、no-repeat(不重复)。如果第二个参数是空字符串或null,则等同于null

该方法的返回值是一个CanvasPattern对象。

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = 'https://example.com/pattern.png';
img.onload = function( ) {
  var pattern = ctx.createPattern(img, 'repeat');
  ctx.fillStyle = pattern;
  ctx.fillRect(0, 0, 400, 400);
};

阴影

透明度

通过设置 globalAlpha 属性或者使用一个半透明颜色作为轮廓或填充的样式。

globalAlpha 属性在需要绘制大量拥有相同透明度的图形时候相当高效。不过 strokeStylefillStyle 属性接受符合 CSS 3 规范的颜色值,那可以使用 rgba(255,0,0,0.5)来设置具有透明度的颜色。

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  // 画背景框
  ctx.fillStyle = '#6C0';
  ctx.fillRect(0, 0, 150, 75);
  ctx.fillStyle = 'rgba(0, 153, 255, 0.8)';
  ctx.fillRect(0, 75, 150, 75);

  // 设置透明度值
  ctx.globalAlpha = 0.2;

  // 画半透明圆
  ctx.fillStyle = '#FFF'
  for (var i=0;i<7;i++){
      ctx.beginPath();
      ctx.arc(75,75,10+10*i,0,Math.PI*2,true);
      ctx.fill();
  }
}

合成与裁剪

合成 globalCompositeOperation

我们不仅可以在已有图形后面再画新图形,还可以用来遮盖指定区域,清除画布中的某些部分(清除区域不仅限于矩形,像clearRect()方法做的那样)以及更多其他操作。

裁剪路径 clip

裁切路径和普通的 canvas 图形差不多,不同的是它的作用是遮罩,用来隐藏不需要的部分。

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

ctx.beginPath();
ctx.arc(0,0,60,0,Math.PI*2,true);
ctx.clip(); // 创建一个扇形的裁剪区域

// draw background
var lingrad = ctx.createLinearGradient(0,0,0,150);
lingrad.addColorStop(0, 'blue');
lingrad.addColorStop(1, 'red');
ctx.fillStyle = lingrad;
ctx.fillRect(0,0,150,150);

状态的保存和恢复

Canvas状态存储在栈中,每当save()方法被调用后,当前的状态就被推送到栈中保存。一个绘画状态包括:

可以调用任意多次 save方法。每一次调用 restore 方法,上一个保存的状态就从栈中弹出,所有设定都恢复。

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

ctx.fillRect(0,0,300,300);
ctx.save();   // 保存默认状态

ctx.fillStyle = 'blue'    // 蓝色状态
ctx.fillRect(25,25,250,250);

ctx.save(); // 保存当前状态
ctx.fillStyle = 'red'     // 红色状态
ctx.fillRect(50,50,200,200);

ctx.restore(); // 恢复至蓝色状态
ctx.fillRect(75,75,150,150)

ctx.restore(); // 恢复至默认状态
ctx.fillRect(100,100,100,100)

其他属性和方法

2. 图像变换

以下方法用于图像变换。

旋转

顺时针旋转的弧度。
默认旋转中心点是Canvas的左上角(0, 0)坐标点,如果希望改变旋转中心点,例如以Canvas画布的中心旋转,需要先使用translate()位移旋转中心点。

角度转弧度计算公式是:radian = degree * Math.PI / 180。例如,旋转45°,旋转弧度就是45 * Math.PI / 180

rotate(angle);
// angle : Canvas画布坐标系旋转的角度,单位是弧度。注意,此旋转和CSS3的旋转变换不一样,旋转的是坐标系,而非元素。因此,实际开发的时候,旋转完毕,需要将坐标系再还原。

画布和图片同步旋转 demo :

var canvas = document.getElementById('canvas')
var context = canvas.getContext('2d')

var width = canvas2.width;
var height = canvas2.height;
// 加载图片素材
var img = new Image();
img.onload = function () {
    // 先位移坐标到中心
    context.translate(width / 2, height / 2);
    // 旋转90度
    context.rotate(90 * Math.PI / 180);
    // 此时按照旋转后的尺寸
    // 把定位中心移动到左上角
    context.translate(-1 * height / 2, -1 * width / 2);
    // 绘制图片
    context.drawImage(this, 0, 0, height, width);
    // 坐标系还原到初始
    context.setTransform(1, 0, 0, 1, 0, 0);
};
img.src = './1.jpg';

缩放

根据 x 水平方向和 y 垂直方向,为canvas 单位添加缩放变换的方法。

scale()用来缩放Canvas画布的坐标系,只是影响坐标系,之后的绘制会受此方法影响,但之前已经绘制好的效果不会有任何变化。
默认缩放中心点是Canvas的左上角(0, 0)坐标点,如果希望改变缩放中心点,需要先使用translate()方法进行位移。

ctx.scale(x, y)
// x : Canvas坐标系水平缩放的比例。支持小数,如果值是-1,表示水平翻转。
// y : Canvas坐标系垂直缩放的比例。支持小数,如果值是-1,表示垂直翻转。

位移

将 canvas 按原始 x点的水平方向、原始的 y点垂直方向进行平移变换

ctx.translate(x, y);

矩阵

transform() 方法可以对当前坐标系进行进一步变换,以实现缩放,旋转,拉伸或者位移效果。
此方法和setTransform()方法的区别在于,后者一旦执行会完全重置已有的变换,transform()方法则是累加。

context.transform(a, b, c, d, e, f);
/*
a:水平缩放(默认值1,单位倍数)
b:水平倾斜(默认值0,单位弧度)
c:垂直倾斜(默认值0,单位弧度)
d:垂直缩放(默认值1,单位倍数)
e:水平位移(默认值0,单位像素)
f:垂直位移(默认值0,单位像素)
*/

下面是一个例子。

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
// step 1
ctx.transform(2, 0, 0, 1, 50, 50);
ctx.fillRect(0, 0, 100, 100);
// step 2
ctx.setTransform(1, 0, 0, 1, 0, 100);
ctx.fillStyle = 'red'
ctx.fillRect(0, 0, 100, 100);

上面代码中:step1将原始图形是 100 x 100 的矩形,结果缩放成 200 x 100 的矩形,并且左上角从(0, 0)移动到(50, 50)。step2 将重置当前矩阵,无缩放、无旋转,将画布中心点移至(0, 100)

注意:多个transform()方法具有叠加效果。

图像处理

绘制图片

Canvas API 允许将图像文件写入画布,做法是读取图片后,使用drawImage()方法将这张图片放上画布。

CanvasRenderingContext2D.drawImage()有三种使用格式。

ctx.drawImage(image, dx, dy);
ctx.drawImage(image, dx, dy, dWidth, dHeight);
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

各个参数的含义如下。

切片 Slicing

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

const img = new Image()
img.crossOrigin = 'anonymous'   // 解决图片跨域问题
img.onload = function() {
  // 拉伸图片同时保持图片比例
  ctx.drawImage(img, 0, 42, 500, 250, 0, 0, 300, 150)
}
img.src = 'https://www.canvasapi.cn/assets/images/examples/500/1.jpg'   // 图片实际宽高 500333

如何让一张尺寸为500*300图片填满尺寸为300*150Canvas画布,同时保持图片的原始比例呢?这个就需要用到sx,sy,sWidth和sHeight这几个参数。

上面的示例关键如何理解 0, 42, 500, 250 这4个值是怎么计算来的。我们最终图片要显示在300*150大小的Canvas画布中,比例是2:1,因此,我们最终设置的用来绘制的图片尺寸比例也是2:1。原始图片宽度是500,要保持2:1,则高度我们就设置为250;而原始高度是333,我们希望显示图片中心区域,因此起始垂直坐标计算下,(333 - 250) / 2,四舍五入就是42,因此,就有了对原始图片的剪裁坐标值和尺寸值0, 42, 500, 250

像素读写

getImageData()

CanvasRenderingContext2D.getImageData()方法用来读取<canvas>的内容,返回一个 ImageData 对象,包含了每个像素的信息。

context.getImageData(sx, sy, sWidth, sHeight)

getImageData()方法接受四个参数。sxsy是读取区域的左上角坐标,sWidthsHeight是读取区域的宽度和高度。如果想要读取整个<canvas>区域,可以写成下面这样。

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

getImageData()方法返回的是一个ImageData对象。该对象有三个属性。

putImageData()

CanvasRenderingContext2D.putImageData()方法将ImageData对象的像素绘制在<canvas>画布上。该方法有两种使用格式。

ctx.putImageData(imagedata, dx, dy)
ctx.putImageData(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)

该方法有如下参数。

createImageData()

CanvasRenderingContext2D.createImageData()方法用于生成一个空的ImageData对象,所有像素都是透明的黑色(即每个值都是0)。该方法有两种使用格式。

ctx.createImageData(width, height)
ctx.createImageData(imagedata)

createImageData()方法的参数如下。

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var imageData = ctx.createImageData(100, 100);

上面代码中,imageData是一个 100 x 100 的像素区域,其中每个像素都是透明的黑色。

4. 动画

canvas画布可能最大的限制就是图像一旦绘制出来,它就是一直保持那样了。如果需要移动它,我们不得不对所有东西(包括之前的)进行重绘。重绘是相当费时的,而且性能很依赖于电脑的速度。

动画的基本步骤:

可以通过以下的步骤来画出一帧:

  1. 清空 canvas 除非接下来要画的内容会完全充满 canvas (例如背景图),否则你需要清空所有。最简单的做法就是用 clearRect 方法。
  2. 保存 canvas 状态 如果你要改变一些会改变 canvas 状态的设置(样式,变形之类的),又要在每画一帧之时都是原始状态的话,你需要先保存一下。
  3. 绘制动画图形(animated shapes) 这一步才是重绘动画帧。
  4. 恢复 canvas 状态 如果已经保存了 canvas 的状态,可以先恢复它,然后重绘下一帧。

5. canvas元素方法

Canvas.getContext()

`HTMLCanvasElement.getContext() 返回canvas 的上下文,如果上下文没有定义则返回 null

// 语法
canvas.getContext(contextType);
canvas.getContext(contextType, contextAttributes);

参数说明

Canvas.toDataURL()

<canvas>元素的toDataURL()方法,可以将 Canvas 数据转为 Data URI 格式的图像。

canvas.toDataURL(type, quality)

toDataURL()方法接受两个参数。

该方法的返回值是一个 Data URI 格式的字符串。

function convertCanvasToImage(canvas) {
  var image = new Image();
  image.src = canvas.toDataURL('image/png');
  return image;
}

上面的代码将<canvas>元素,转化成PNG Data URI。

var fullQuality = canvas.toDataURL('image/jpeg', 0.9);
var mediumQuality = canvas.toDataURL('image/jpeg', 0.6);
var lowQuality = canvas.toDataURL('image/jpeg', 0.3);

上面代码将<canvas>元素转成高画质、中画质、低画质三种 JPEG 图像。

Canvas.toBlob()

HTMLCanvasElement.toBlob()方法用于将<canvas>图像转成一个 Blob 对象,默认类型是image/png。它的使用格式如下。

// 格式
canvas.toBlob(callback, mimeType, quality)

// 示例
canvas.toBlob(function (blob) {...}, 'image/jpeg', 0.95)

toBlob()方法可以接受三个参数。

注意,该方法没有返回值。

下面的例子将<canvas>图像复制成<img>图像。

var canvas = document.getElementById('myCanvas');
function blobToImg(blob) {
  var newImg = document.createElement('img');
  var url = URL.createObjectURL(blob);
  newImg.onload = functio () {
    // 使用完毕,释放 URL 对象
    URL.revokeObjectURL(url);
  };
  newImg.src = url;
  document.body.appendChild(newImg);
}
canvas.toBlob(blobToImg);
Meqn commented 3 years ago

HTML Canvas 参考手册

来源1:https://www.w3school.com.cn/tags/html_ref_canvas.asp 来源2:https://www.w3cschool.cn/htmltags/ref-canvas.html

HTML <canvas> 标签用于通过脚本(通常是 JavaScript)动态绘制图形。

描述

HTML5 <获得用于在画布上绘图的对象获得用于在画布上绘图的对象> 标签用于绘制图像(通过脚本,通常是 JavaScript)。

不过,<canvas> 元素本身并没有绘制能力(它仅仅是图形的容器) - 您必须使用脚本来完成实际的绘图任务。

getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性。

本手册提供完整的 getContext("2d") 对象的属性和方法,可用于在画布上绘制文本、线条、矩形、圆形等等。

颜色、样式和阴影

属性 描述
fillStyle 设置或返回用于填充绘画的颜色、渐变或模式。
strokeStyle 设置或返回用于笔触的颜色、渐变或模式。
shadowColor 设置或返回用于阴影的颜色。
shadowBlur 设置或返回用于阴影的模糊级别。
shadowOffsetX 设置或返回阴影与形状的水平距离。
shadowOffsetY 设置或返回阴影与形状的垂直距离。
方法 描述
createLinearGradient() 创建线性渐变(用在画布内容上)。
createPattern() 在指定的方向上重复指定的元素。
createRadialGradient() 创建放射状/环形的渐变(用在画布内容上)。
addColorStop() 规定渐变对象中的颜色和停止位置。

线条样式

属性 描述
lineCap 设置或返回线条的结束端点样式。
lineJoin 设置或返回两条线相交时,所创建的拐角类型。
lineWidth 设置或返回当前的线条宽度。
miterLimit 设置或返回最大斜接长度。

矩形

方法 描述
rect() 创建矩形。
fillRect() 绘制"被填充"的矩形。
strokeRect() 绘制矩形(无填充)。
clearRect() 在给定的矩形内清除指定的像素。

路径

方法 描述
fill() 填充当前绘图(路径)。
stroke() 绘制已定义的路径。
beginPath() 起始一条路径,或重置当前路径。
moveTo() 把路径移动到画布中的指定点,不创建线条。
closePath() 创建从当前点回到起始点的路径。
lineTo() 添加一个新点,然后在画布中创建从该点到最后指定点的线条。
clip() 从原始画布剪切任意形状和尺寸的区域。
quadraticCurveTo() 创建二次贝塞尔曲线。
bezierCurveTo() 创建三次贝塞尔曲线。
arc() 创建弧/曲线(用于创建圆形或部分圆)。
arcTo() 创建两切线之间的弧/曲线。
isPointInPath() 如果指定的点位于当前路径中,则返回 true,否则返回 false。

转换

方法 描述
scale() 缩放当前绘图至更大或更小。
rotate() 旋转当前绘图。
translate() 重新映射画布上的 (0,0) 位置。
transform() 替换绘图的当前转换矩阵。
setTransform() 将当前转换重置为单位矩阵。然后运行 transform()。

文本

属性 描述
font 设置或返回文本内容的当前字体属性。
textAlign 设置或返回文本内容的当前对齐方式。
textBaseline 设置或返回在绘制文本时使用的当前文本基线。
方法 描述
fillText() 在画布上绘制"被填充的"文本。
strokeText() 在画布上绘制文本(无填充)。
measureText() 返回包含指定文本宽度的对象。

图像绘制

方法 描述
drawImage() 向画布上绘制图像、画布或视频。

像素操作

属性 描述
width 返回 ImageData 对象的宽度。
height 返回 ImageData 对象的高度。
data 返回一个对象,其包含指定的 ImageData 对象的图像数据。
方法 描述
createImageData() 创建新的、空白的 ImageData 对象。
getImageData() 返回 ImageData 对象,该对象为画布上指定的矩形复制像素数据。
putImageData() 把图像数据(从指定的 ImageData 对象)放回画布上。

合成

属性 描述
globalAlpha 设置或返回绘图的当前 alpha 或透明值。
globalCompositeOperation 设置或返回新图像如何绘制到已有的图像上。

其他

方法 描述
save() 保存当前环境的状态。
restore() 返回之前保存过的路径状态和属性。
createEvent() 创建新的 Event 对象
getContext() 获得用于在画布上绘图的对象
toDataURL() 导出在 canvas 元素上绘制的图像
Meqn commented 1 year ago

awesome-canvas

精心收录Canvas相关的资源并整理分类,部分同类资源库也收录SVG/WebGL相关的资源。

简体中文 | English

目录

教程

书籍

仓库

图形绘制

3D库

VR/AR

物理引擎

游戏引擎

流程图

甘特图

组织图

图编辑

电子表格

图表库

海报截图

数据处理

图像处理

画板

签名

波纹动画

粒子动画

路径动画

二维码

验证码

运行时

其他

插件资源网站

效果/案例

文章

Meqn commented 5 months ago

Three.js

教程

扩展库