1. 矩形的绘制
矩形的清除、描边及填充
- clearRect(double x, double y, double w, double h)
- strokeRect(double x, double y, double w, double h)
- fillRect(double x, double y, double w, double h)
context.lineJoin = 'round';
context.lineWidth = 30;
context.font = '24px Helvetica';
context.fillText('Click anywhere to erase', 175, 200);
context.strokeStyle = 'goldenrod';
context.fillStyle = 'rgba(0, 0, 255, 0.5)';
context.strokeRect(75, 100, 200, 200);
context.fillRect(325, 100, 200, 200);
2. 渐变色
创建线性渐变、放射渐变
- createLinearGradient(double x0, double y0, double x1, double y1)
- createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1)
gradient = context.createLinearGradient(0, 0, canvas.width, canvas.height);
gradient.addColorStop(0, 'blue');
gradient.addColorStop(0.25, 'white');
gradient.addColorStop(0.5, 'purple');
gradient.addColorStop(0.75, 'red');
gradient.addColorStop(1, 'yellow');
context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);
3. 图案
- createPattern(image|canvas|video, repetition)
image.src = 'img/ben.png';
image.onload = function (e) {
//'repeat', 'repeat-x', 'repeat-y', 'no-repeat'
var pattern = context.createPattern(image, 'repeat');
context.fillStyle = pattern;
context.fillRect(0, 0, canvas.width, canvas.height);
}
4. 阴影
阴影的颜色、水平偏移、垂直偏移、模糊化
- shadowColor
- shadowOffsetX
- shadowOffsety
- shadowBlur
context.shadowColor = 'blue';
context.shadowOffsetX = 1;
context.shadowOffsety = 1;
context.shadowBlur = 2;
context.strokeRect(100, 100, 100, 100);
5. 路径、描边与填充
- arc()
- beginPath()
- closePath()
- fill()
- rect()
- stroke()
//attr
context.font = '48pt Helvetica';
context.strokeStyle = 'blue';
context.fillStyle = 'red';
context.lineWidth = 2;
//Text
context.strokeText('Stroke', 60, 90);
context.fillText('Fill', 440, 90);
context.strokeText('Stroke & Fill', 650, 90);
context.fillText('Stroke & Fill', 650, 90);
//Rectangles
context.lineWidth = 5;
context.beginPath();
context.rect(80, 130, 150, 100);
context.stroke();
context.beginPath();
context.rect(400, 130, 150, 100);
context.fill();
context.beginPath();
context.rect(750, 130, 150, 100);
context.stroke();
context.fill();
//open arcs
context.beginPath();
context.arc(150, 350, 60, 0, Math.PI*3/2);
context.stroke();
context.beginPath();
context.arc(475, 350, 60, 0, Math.PI*3/2);
context.fill();
context.beginPath();
context.arc(820, 350, 60, 0, Math.PI*3/2);
context.stroke();
context.fill();
//close arcs
context.beginPath();
context.arc(150, 530, 60, 0, Math.PI*3/2);
context.closePath();
context.stroke();
context.beginPath();
context.arc(475, 530, 60, 0, Math.PI*3/2);
context.closePath();
context.fill();
context.beginPath();
context.arc(820, 530, 60, 0, Math.PI*3/2);
context.closePath();
context.stroke();
context.fill();
6. 剪纸效果
路径、阴影以及非零环绕
function drawTwoArcs () {
context.beginPath();
context.arc(300, 150, 120, 0, Math.PI*2, false);
context.arc(300, 150, 80, 0, Math.PI*2, true);
context.fill();
context.shadowColor = undefined;
context.shadowOffsetX = 0;
context.shadowOffsety = 0;
context.stroke();
}
function draw () {
context.clearRect(0, 0, canvas.width, canvas.height);
context.save();
context.shadowColor = 'rgba(0, 0, 0, 0.8)';
context.shadowOffsetX = 12;
context.shadowOffsety = 12;
context.shadowBlur = 15;
drawTwoArcs();
context.restore();
}
context.fillStyle = 'rgba(100, 140, 230, 0.5)';
context.strokeStyle = context.fillStyle;
draw();
function draw () {
context.clearRect(0, 0, canvas.width, canvas.height);
context.save();
context.shadowColor = 'rgba(0, 0, 0, 0.8)';
context.shadowOffsetX = 12;
context.shadowOffsety = 12;
context.shadowBlur = 15;
drawCutouts();
strokeCutoutShapes();
context.restore();
}
function drawCutouts () {
context.beginPath();
addOuterRectanglePath(); //CW
addCirclePath(); //CCW
addRectanglePath(); //CCW
addTrianglePath(); //CCW
context.fill();
}
function strokeCutoutShapes () {
context.save();
context.strokeStyle = 'rgba(0, 0, 0, 0.7)';
context.beginPath();
addOuterRectanglePath(); //CW
context.stroke();
context.beginPath();
addCirclePath(); //CCW
addRectanglePath(); //CCW
addTrianglePath(); //CCW
context.stroke();
context.restore();
}
function rect (x, y, w, h, direction) {
if (direction) {
context.moveTo(x, y);
context.lineTo(x, y+h);
context.lineTo(x+w, y+h);
context.lineTo(x+w, y);
context.closePath();
} else {
context.moveTo(x, y);
context.lineTo(x+w, y);
context.lineTo(x+w, y+h);
context.lineTo(x, y+h);
context.closePath();
}
}
function addOuterRectanglePath () {
context.rect(110, 25, 370, 335);
}
function addCirclePath () {
context.arc(300, 300, 40, 0, Math.PI*2, true);
}
function addRectanglePath () {
rect(310, 55, 70, 35, true);
}
function addTrianglePath () {
context.moveTo(400, 200);
context.lineTo(250, 115);
context.lineTo(200, 200);
context.closePath();
}
context.fillStyle = 'goldenrod';
draw();
7. 网格
function drawGrid (context, color, stepx, stepy) {
context.strokeStyle = color;
context.lineWidth = 1;
for (var i = stepx+0.5; i < context.canvas.width; i += stepx) {
context.beginPath();
context.moveTo(i, 0);
context.lineTo(i, context.canvas.height);
context.stroke();
}
for (var i = stepy+0.5; i < context.canvas.height; i += stepy) {
context.beginPath();
context.moveTo(0, i);
context.lineTo(context.canvas.width, i);
context.stroke();
}
}
drawGrid(context, 'lightgray', 10, 10);
8. 橡皮筋
function windowToCanvas (canvas, x, y) {
var bbox = canvas.getBoundingClientRect(); //获取canvas在屏幕中的位置
return {
x: (x-bbox.left)*(canvas.width/bbox.width),
y: (y-bbox.top)*(canvas.height/bbox.height)
};
}
canvas.onmousedown = function (e) {
var loc = windowToCanvas(canvas, e.clientX, e.clientY);
if (mousedown.x0) {
mousedown.x1 = loc.x;
mousedown.y1 = loc.y;
pointArr.push(mousedown);
mousedown = {};
} else {
mousedown.x0 = loc.x;
mousedown.y0 = loc.y;
}
}
canvas.onmousemove = function (e) {
var loc = windowToCanvas(canvas, e.clientX, e.clientY);
if (mousedown.x0) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.strokeStyle = 'blue';
pointArr.forEach(function (point) {
context.beginPath();
context.moveTo(point.x0, point.y0);
context.lineTo(point.x1, point.y1);
context.stroke();
});
context.beginPath();
context.moveTo(mousedown.x0, mousedown.y0);
context.lineTo(loc.x, loc.y);
context.stroke();
drawGrid(context, 'lightgray', 10, 10);
}
}
drawGrid(context, 'lightgray', 10, 10);
9. 贝塞尔曲线
二次方、三次方贝塞尔曲线
- quadraticCurveTo(double cpx, double cpy, double x, double y)
- bezierCurveTo(double cpx, double cpy, double cp2x, double cp2y, double x, double y)
context.beginPath();
context.moveTo(120.5, 130);
context.quadraticCurveTo(150.8, 130, 160.6, 150.5);
context.quadraticCurveTo(190, 250.0, 210.5, 160.5);
context.quadraticCurveTo(240, 100.5, 290, 70.5);
context.stroke();
context.strokeStyle = 'blue';
context.beginPath();
context.moveTo(endPoints[0].x, endPoints[0].y);
context.bezierCurveTo(controlPoints[0].x, controlPoints[0].y, controlPoints[1].x, controlPoints[1].y, endPoints[1].x, endPoints[1].y);
context.stroke();
10. 多边形的绘制
moveTo()、lineTo()以及三角函数
context.beginPath();
context.moveTo(canvas.width/2+radius, canvas.height/2);
for (var i = 1; i < 8; i++) {
context.lineTo(canvas.width/2+radius*Math.cos(i*Math.PI/4), canvas.height/2-radius*Math.sin(i*Math.PI/4));
}
context.closePath();
context.stroke();