Canvas笔记
Canvas
<canvas>
标签是一个图形容器,可以使用脚本在其中绘制图形- 创建画布
- 建议永远不要使用 css 属性来设置
<canvas>
的宽高,因为有可能发生扭曲;- 替换内容可以是文字、图片或其他
<canvas id="myCanvas" width="300" height="150" style="border: 1px solid black;">你的浏览器不支持canvas!</canvas>
- 创建对象
function draw(){
var canvas = document.getElementById('myCanvas');
if(!canvas.getContext) return; //检测支持性
var ctx = canvas.getContext("2d"); //getContext("2d") 对象是内建的 HTML5 对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。
}
draw();
- 颜色
- 颜色、渐变对象、图案对象
- 透明度
for (var i = 0; i < 6; i++){
for (var j = 0; j < 6; j++){
ctx.strokeStyle = `rgb(${randomInt(0, 255)},${randomInt(0, 255)},${randomInt(0, 255)})`;
ctx.strokeRect(j * 50, i * 50, 40, 40);
}
}
/**
返回随机的 [from, to] 之间的整数(包括from,也包括to)
*/
function randomInt(from, to){
return parseInt(Math.random() * (to - from + 1) + from);
}
ctx.globalAlpha = "transparencyValue"; //影响到 canvas 里所有图形的透明度,有效的值范围是 0.0 (完全透明)到 1.0(完全不透明),默认是 1.0
- 样式
- 线宽
- 线条末端样式
- 线条与线条间接合处的样式
- 虚线
ctx.lineWidth = 20; //线宽,起始点和终点的连线为中心,上下各占线宽的一半
/**
butt:线段末端以方形结束
round:线段末端以圆形结束
square:线段末端以方形结束,但是增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域。
*/
var lineCaps = ["butt", "round", "square"];
ctx.lineCap = lineCaps[i]; //线条末端样式
var lineJoin = ['round', 'bevel', 'miter'];
ctx.lineJoin = lineJoin[i]; //线条与线条间接合处的样式
ctx.setLineDash([20, 5]); //[实线长度, 间隙长度]
ctx.lineDashOffset = -0; //设置起始偏移量
- 渐变
- 创建渐变
var grd=ctx.createLinearGradient(0,0,200,0); //线条渐变
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
var grd=ctx.createRadialGradient(75,50,5,90,60,100); //径向渐变
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
- 填充渐变
ctx.fillStyle=grd;
ctx.fillRect(10,10,150,80);
- 文本
ctx.textAlign=""; //start, end, left, right, center, 默认值是 start
ctx.textBaseline=""; //top, hanging, middle, alphabetic, ideographic, bottom, 默认值是 alphabetic
ctx.direction=""; //ltr, rtl, inherit, 默认值是 inherit
ctx.font="30px Arial";
ctx.fillText("Hello World",10,50[, maxWidth]); //实心,最大宽度可选
ctx.strokeText("Hello World",10,50[, maxWidth]); //空心
- 矩形
ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,150,75); //填充
ctx.strokeRect(10, 70, 100, 50); //描边
ctx.clearRect(15, 15, 50, 25); //清除
- 线
- 描边
- 填充
ctx.beginPath(); //新建路径
ctx.moveTo(50,50); //设置路径的起始点坐标
ctx.lineTo(200,50);
ctx.lineTo(200,200);
ctx.closePath(); //闭合路径
ctx.stroke(); //描边,stroke()不会自动闭合路径
ctx.fill(); //填充,fill()会自动闭合路径
- 圆弧
- 两种方法
ctx.beginPath();
ctx.arc(95,50,40,-Math.PI / 2, Math.PI / 2,flase); //后两个值为弧度制角度和顺逆(false为顺,默认值)
ctx.stroke();
ctx.moveTo(50, 50);
ctx.arcTo(200, 50, 200, 200, 100); //参数1、2:控制点1坐标;参数3、4:控制点2坐标 参数4:圆弧半径
ctx.lineTo(200, 200)
ctx.stroke();
- 贝塞尔曲线
- 二次贝赛尔曲线
- 三次贝赛尔曲线
ctx.beginPath();
ctx.moveTo(10, 200); //起始点
var cp1x = 40, cp1y = 100; //控制点
var x = 200, y = 200; //结束点
ctx.quadraticCurveTo(cp1x, cp1y, x, y); //绘制二次贝塞尔曲线
ctx.stroke();
ctx.beginPath();
ctx.moveTo(40, 200); //起始点
var cp1x = 20, cp1y = 100; //控制点1
var cp2x = 100, cp2y = 120; //控制点2
var x = 200, y = 200; //结束点
ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); //绘制三次贝塞尔曲线
ctx.stroke();
- 图像
- 显示图像(创建 img 或从 html 中获取)
- 切片
var img = new Image(); // 创建一个<img>元素
img.src = 'myImage.png'; // 设置图片源地址
var img=document.getElementById("img");
img.onload = function(){
ctx.drawImage(img, 0, 0[, width, height]);
}
/**
前 4 个参数是定义图像源的切片位置和大小,后 4 个则是定义切片的目标显示位置和大小
*/
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight); //切片
- 状态的保存与恢复
ctx.save(); //当前的状态就被推送到栈中保存,类似数组的 push()
ctx.restore(); //上一个保存的状态从栈中弹出,类似数组的 pop()
- 变形
- 移动原点
- 旋转坐标轴
- 放大与缩小
- 变形
ctx.translate(100, 100); //用来移动 canvas 的原点到指定的位置
ctx.rotate(Math.PI / 180 * 45); //旋转坐标轴
img.scale(x, y); //增减图形在 canvas 中的像素数目,值比 1.0 小表示缩小,比 1.0 大则表示放大
ctx.transform(1, 1, 0, 1, 0, 0);
ctx.fillRect(0, 0, 100, 100);
- 合成
/**
source-in:仅仅会出现新图像与原来图像重叠的部分
source-out:仅仅显示新图像与老图像没有重叠的部分,老图像也不显示
source-atop:新图像仅仅显示与老图像重叠区域,老图像仍然可以显示
destination-over:新图像会在老图像的下面
destination-in:仅仅新老图像重叠部分的老图像被显示
destination-out:仅仅显示老图像与新图像没有重叠的部分
destination-atop:显示重叠部分老图像+新图像
lighter:新老图像都显示,但是重叠区域的颜色做加处理
darken:保留重叠部分最黑的像素。(每个颜色位进行比较,得到最小的)
lighten:保证重叠部分最量的像素。(每个颜色位进行比较,得到最大的)
xor:重叠部分会变成透明
copy:只有新图像会被保留,其余的全部被清除
*/
ctx.globalCompositeOperation = "source-over"; //默认设置,新图像会覆盖在原有图像。
- 裁剪
ctx.beginPath();
ctx.arc(20,20, 100, 0, Math.PI * 2);
ctx.clip(); //把已经创建的路径转换成裁剪路径
ctx.fillStyle = "pink";
ctx.fillRect(20, 20, 100,100);
- 动画
- 其他
stroke为描边,fill为填充
原文作者: 做人要厚道2013
原文地址:https://blog.youkuaiyun.com/u012468376/article/details/73350998