https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes
canvas的基础使用
- canvas可以填充矩形
- canvas可以绘制设定好的路径
- canvas可以绘制文字
- canvas可以绘制渐变
-
CanvasRenderingContext2D对象的api
fillRect(x:number, y:number, width:number, height:number)
绘制一个填充的矩形fillStyle属性,
设置或获取填充的颜色,结合fillRect使用。strokeStyle属性,
设置或获取填充的颜色,结合路径使用。globalAlpha属性,
设置透明度,取值范围0~1lineWidth属性,
设置线条宽度lineWidth属性,
设置线条末端样式,取值范围butt(方块), round(圆) , square(方块,额外计算宽高尺寸的,宽度和线段相同,高度是线段厚度一半)。默认值是 butt。lineJoin属性,
设置线条连接处的样式,round(圆), bevel(矩形拐角), miter(延伸, 可以通过miterLimit设置属性值)。默认值是 miter。miterLimit属性,
设置限制当两条线相交时交接处最大长度;所谓交接处长度(斜接长度)是指线条交接处内角顶点到外角顶点的长度。number值,斜接面限制比例的的数字。 0、负数、Infinity 和 NaN 都会被忽略,默认值是10.0。lineDashOffset属性,
设置虚线样式的起始偏移量。偏移量是float精度的数字。 初始值为 0.0。setLineDash(segments)
设置当前虚线样式。值可以是[5, 15, 25]getLineDash()
返回一个包含当前虚线样式,长度为非负偶数的数组。clearRect(x:number, y:number, width:number, height:number)
清除指定矩形区域,让清除部分完全透明,要比绘制矩形区域大才能清除。beginPath()
新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。生成路径的第一步叫做beginPath()。本质上,路径是由很多子路径构成,这些子路径都是在一个列表中,所有的子路径(线、弧形、等等)构成图形。而每次这个方法调用之后,列表清空重置,然后我们就可以重新绘制新的图形。moveTo(_x:number_, _y:number_)
将笔触移动到指定的坐标x以及y上,如果在画路径时,不移动笔触的话会出现下面的情况。当前路径为空,即调用beginPath()之后,或者canvas刚建的时候,第一条路径构造命令通常被视为是moveTo(x, y),无论实际上是什么。出于这个原因,你几乎总是要在设置路径之后专门指定你的起始位置。
- 不移动笔触 ,移动笔触
lineTo(_x:number_, _y:number_)
画一条线closePath()
闭合路径之后图形绘制命令又重新指向到上下文中。闭合路径closePath(),不是必需的。这个方法会通过绘制一条从当前点到开始点的直线来闭合图形。如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。stroke()
通过线条来绘制图形轮廓。strokeRect(x:number, y:number, width:number, height:number)
绘制一个矩形的边框fill()
通过填充路径的内容区域生成实心的图形。当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合。arc(x:number, y:number, radius:number, startAngle:number, endAngle:number, anticlockwise: boolean)
画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle(圆弧的起始点)开始到endAngle(圆弧的结束点)结束,按照anticlockwise给定的方向(默认为顺时针)来生成。ctx.arc(75, 75, 50, 0, 2 * Math.PI);
弧度=(Math.PI/180)*角度。
arcTo(x1, y1, x2, y2, radius)
根据给定的控制点和半径画一段圆弧,再以直线连接两个控制点
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
您的浏览器不支持 HTML5 canvas 标签。
</canvas>
<script>
// 找到canvas标签
var c=document.getElementById("myCanvas");
// 通过canvas元素,创建Context对象
var ctx=c.getContext("2d");
// 设置填充颜色
// ctx.fillStyle="#FF0000";
// ctx.fillStyle = "rgb(200,0,0)";
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
// 绘制一个矩形
ctx.fillRect(0,0,150,75);
</script>
</body>
</html>
画圆形
var canvas = document.getElementById('myCanvas');
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.closePath();
// 绘制路径
ctx.stroke();
不移动笔触 ,移动笔触
画三角形
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
// 填充三角形
ctx.beginPath();
ctx.moveTo(25,25);
ctx.lineTo(105,25);
ctx.lineTo(25,105);
ctx.fill();
// 描边三角形
ctx.beginPath();
ctx.moveTo(125,125);
ctx.lineTo(125,45);
ctx.lineTo(45,125);
ctx.closePath();
ctx.stroke();
}
}
绘制文字
// 实心文字用填充实现
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="30px Arial";
ctx.fillText("Hello World",10,50);
// 空心文字用路径实现
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="30px Arial";
ctx.strokeText("Hello World",10,50);
canvas创建渐变效果
- createLinearGradient(x,y,x1,y1) - 创建线条渐变
- createRadialGradient(x,y,r,x1,y1,r1) - 创建一个径向/圆渐变 ```javascript var c=document.getElementById(“myCanvas”); var ctx=c.getContext(“2d”);
// 创建线性渐变 var grd=ctx.createLinearGradient(0,0,200,0); grd.addColorStop(0,”red”); grd.addColorStop(1,”white”);
// 填充渐变 ctx.fillStyle=grd; ctx.fillRect(10,10,150,80);
// ########## var c=document.getElementById(“myCanvas”); var ctx=c.getContext(“2d”);
// 创建颈向/圆渐变 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);
<a name="0UiX2"></a>
#### canvas绘制图像
```javascript
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<p>Image to use:</p>
<img id="scream" src="img_the_scream.jpg" alt="The Scream" width="220" height="277"><p>Canvas:</p>
<canvas id="myCanvas" width="250" height="300" style="border:1px solid #d3d3d3;">
您的浏览器不支持 HTML5 canvas 标签。</canvas>
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("scream");
img.onload = function() {
ctx.drawImage(img,10,10);
}
</script>
</body>
</html>
Canvas API
HTMLCanvasElement对象
属性
width
height
方法
getContext(ContextId : string);
接收一个string的参数,是一个contextId,允许的值现在只有3个,2d”和”experimental-webgl”.”experimental-webgl”,
- 调用getContext(“2d”)会返回一个 CanvasRenderingContext2D对象
调用getContext(“experimental-webgl”)会返回一个WebGLRenderingContext对象.
toDataURL(type: string, encoderOptions: number);
返回base64的data值;
type 默认取值,默认为 PNG 格式。图片的分辨率为96dpi。
- encoderOptions,在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。
var canvas = document.getElementById("canvas");
var dataURL = canvas.toDataURL();
console.log(dataURL);
// "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNby
// blAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC"
var fullQuality = canvas.toDataURL("image/jpeg", 1.0);
// data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...9oADAMBAAIRAxEAPwD/AD/6AP/Z"
var mediumQuality = canvas.toDataURL("image/jpeg", 0.5);
var lowQuality = canvas.toDataURL("image/jpeg", 0.1);
toBlob(callback: () => void, type: string, encoderOptions:number);
- callback 回调函数,可获得一个单独的Bolb对象参数
- type 默认取值,默认为 PNG 格式。图片的分辨率为96dpi。
- encoderOptions,在指定图片格式为 image/jpeg 或 image/webp的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他参数会被忽略。
示例,如何把一个canvas元素转换成图片,再把图片地址传给一个元素并显示出来.
var canvas = document.getElementById("canvas");
canvas.toBlob(function(blob) {
var newImg = document.createElement("img"),
url = URL.createObjectURL(blob);
newImg.onload = function() {
// no longer need to read the blob so it's revoked
URL.revokeObjectURL(url);
};
newImg.src = url;
document.body.appendChild(newImg);
});
示例,将canvas转换为ico(仅限Mozilla)
var canvas = document.getElementById("canvas");
var d = canvas.width;
ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(d / 2, 0);
ctx.lineTo(d, d);
ctx.lineTo(0, d);
ctx.closePath();
ctx.fillStyle = "yellow";
ctx.fill();
function blobCallback(iconName) {
return function(b) {
var a = document.createElement("a");
a.textContent = "Download";
document.body.appendChild(a);
a.style.display = "block";
a.download = iconName + ".ico";
a.href = window.URL.createObjectURL(b);
}
}
canvas.toBlob(blobCallback('passThisString'), 'image/vnd.microsoft.icon',
'-moz-parse-options:format=bmp;bpp=32');
实例
画椭圆或圆
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>椭圆</title>
</head>
<body>
<canvas id="canvas" style="border:1px solid #aaa;display:block;margin:50px auto;">
当前浏览器不支持Canvas,请更换浏览器后再试
</canvas>
<script>
window.onload = function(){
var canvas = document.getElementById("canvas");
var ctx=canvas.getContext('2d');
if(ctx.ellipse){
// ctx.ellipse(v1, v2, v3, v4, v5, v6, v7)
// v1 = 圆心x坐标点
// v2 = 圆心y坐标点
// v3 = 半径x
// v4 = 半径y
// v5 = startAngle 起始角
// v6 = endAngle
// v7 = anticlockwise 顺时针还是逆时针
ctx.ellipse(canvas.width / 2, canvas.height / 2, 100, 50,0,0,Math.PI*2);
// ctx.fillStyle="#058";
ctx.strokeStyle="#000";
// ctx.fill();
ctx.stroke();
}else{
alert("no ellipse!");
}
}
</script>
</body>
</html>
画圆或椭圆2
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>canvas</title>
</head>
<body>
<canvas width="400" height="400" id="canvas">
</canvas>
<script>
const c = document.getElementById("canvas")
var ctx=c.getContext("2d");
EllipseOne(ctx, 100, 100, 100, 50)
// x,y 圆心的坐标
// a,b 是半径
function EllipseOne(context, x, y, a, b) {
var step = (a > b) ? 1 / a : 1 / b;
context.beginPath();
context.moveTo(x + a, y);
for(var i = 0; i < 2 * Math.PI; i += step) {
context.lineTo(x + a * Math.cos(i), y + b * Math.sin(i));
}
context.closePath();
context.fill();
}
</script>
</body>
</html>
生成文字水印
function watermarkDrawText(text) {
var canvas = document.createElement("canvas");
try {
canvas.width = 200;
canvas.height = 200;
var ctx = canvas.getContext("2d");
canvas.style.position = "fixed";
canvas.style.top = '0px';
canvas.style.left= '0px';
// canvas.style.backgroundColor = "#fff"
document.body.appendChild(canvas);
ctx.rotate(45*Math.PI/180);
ctx.fillStyle = '#ccc'
ctx.font="30px Arial";
ctx.fillText(text || "",50,10);
return canvas.toDataURL("image/png");
} catch (e) {
console.error(e);
} finally {
document.body.removeChild(canvas);
}
}
测量文字宽度的方法,让文字行内居中
ctx.measureText('hello world!').width
ctx.textAlign = 'center';