canva学习笔记
创建canvas
- 标签
<canvas id="canvas" width="600" height="400">浏览器不兼容提示文本</canvas>
- js实例
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
矩形绘制
let ctx = canvas.getContext('2d');
/* 绘制填充矩形 */
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect(0, 0, 300, 200);
ctx.fillStyle = "rgba(0,0,200,0.4)";
ctx.fillRect(30, 30, 300, 200);
/* 描边矩形 */
ctx.strokeStyle = "green";
ctx.strokeRect(60, 60, 300, 200);
ctx.strokeStyle = "#F34";
ctx.strokeRect(90, 90, 300, 200);
/* 清除矩形 */
ctx.fillStyle = "orange";
ctx.fillRect(400, 100, 100, 100);
ctx.clearRect(420, 120, 60, 60);
ctx.strokeRect(430, 130, 40, 40);
通过路径绘制图形
let ctx = canvas.getContext('2d');
// 外部矩形边框
ctx.strokeRect(20, 20, 200, 200);
//左边填充三角形
ctx.beginPath();//创建起始路径
ctx.moveTo(40, 40);
ctx.lineTo(40, 180);
ctx.lineTo(180, 40);
ctx.fill();//填充
//右边描边三角形
ctx.beginPath();
ctx.moveTo(60, 200);
ctx.lineTo(200, 200);
ctx.lineTo(200, 60);
ctx.closePath();
ctx.stroke();
利用路径实现涂鸦板
let ctx = canvas.getContext('2d');
/* 监听鼠标按下事件 */
canvas.addEventListener('mousedown', function (e) {
let x = e.clientX - canvas.offsetLeft;
let y = e.clientY - canvas.offsetTop;
/* 起始位 */
ctx.beginPath();
ctx.moveTo(x, y);
/* 鼠标移动 */
function listener(e2) {
let x = e2.clientX - canvas.offsetLeft;
let y = e2.clientY - canvas.offsetTop;
ctx.lineTo(x, y);
ctx.stroke();
}
canvas.addEventListener('mousemove', listener)
/* 鼠标按键升起 */
canvas.addEventListener('mouseup', function (e3) {
canvas.removeEventListener('mousemove', listener)
})
}
绘制圆形
let ctx = canvas.getContext('2d');
ctx.lineWidth = "2";//线条宽度
/* 循环生成 */
for (let i = 1; i <= 3; i++) {
for (let j = 1; j <= 4; j++) {
ctx.beginPath();
let x = 60 * i, y = 60 * j;//起始坐标
let r = 20, st = 0;//半径和起始角度
let ed = Math.PI + Math.PI * (i - 1) / 2;//终点角度
let dir = (j % 2) ? false : true;//是否逆时针
/* 绘制 */
ctx.arc(x, y, r, st, ed, dir);
/* 判断填充还是描边 */
if (j > 2) ctx.fill();
else ctx.stroke();
}
}
渐变
/* -----------------线性渐变----------------- */
/* x1,y1,x2,y2 */
let lingrad = ctx.createLinearGradient(0, 0, 0, 150);
/* 渐变 */
lingrad.addColorStop(0, "red");
lingrad.addColorStop(0.4, "white");
lingrad.addColorStop(0.8, "yellow");
ctx.fillStyle = lingrad;
ctx.fillRect(10, 10, 130, 130);
let lingrad2 = ctx.createLinearGradient(0, 50, 0, 90);
lingrad2.addColorStop(0.5, "#000");
lingrad2.addColorStop(1, "rgba(0,0,0,0)");
ctx.strokeStyle = lingrad2;
/* 渲染矩形 */
ctx.strokeRect(50, 50, 50, 50);
/* -----------------径向渐变----------------- */
// x1,y1,r1,x2,y2,r2
let radgrad = ctx.createRadialGradient(250, 50, 30, 250, 40, 10);
radgrad.addColorStop(0, "rgba(0,0,0,0)");
radgrad.addColorStop(0.3, "green");
radgrad.addColorStop(1, "orange");
ctx.fillStyle = radgrad;
ctx.fillRect(200, 0, 200, 200);
let radgrad2 = ctx.createRadialGradient(300, 100, 40, 300, 100, 20);
radgrad2.addColorStop(0, "rgba(0,0,0,0)");
radgrad2.addColorStop(0.3, "red");
radgrad2.addColorStop(1, "orange");
ctx.fillStyle = radgrad2;
ctx.fillRect(200, 0, 200, 200);
绘制字体
let ctx = canvas.getContext('2d');
/* 字体样式 */
ctx.font = "bold italic 100px arial";
ctx.shadowColor = "#bbb";
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 20;
ctx.shadowOffsetY = 20;
/* 字体渐变 */
let lingrad = ctx.createLinearGradient(20, 0, 400, 100);
lingrad.addColorStop(0, 'red');
lingrad.addColorStop(0.8, 'orange');
lingrad.addColorStop(1, 'yellow');
/* 使用渐变并渲染 */
ctx.fillStyle = lingrad;
ctx.fillText("Hello World", 20, 100);
绘制图片
let ctx = canvas.getContext('2d');
let img = new Image();
img.src = "https://gitee.com/aeipyuan/picture_bed/raw/master/images/20200610184535.png";
img.onload = function () {
//方式1
// let ptrn = ctx.createPattern(img, 'no-repeat');
// ctx.fillStyle = ptrn;
// ctx.fillRect(0, 0, 600, 400);
//方式2
//图片,裁切图像x0,y0,width,height,放置图像x1,y1,width,height
ctx.drawImage(this, 0, 0, 200, 400, 200, 200, 300, 200);
}
剪切clip
let ctx = canvas.getContext('2d');
ctx.rect(50, 20, 200, 120);//边框
ctx.stroke();
ctx.clip();//上图为加与不加此语句的区别
ctx.fillStyle = "green";
ctx.fillRect(0, 0, 150, 100);
图像组合
/* source-over源图像覆盖目标图像 */
let ctx1 = canvas1.getContext('2d');
ctx1.fillStyle = "orange";
ctx1.fillRect(0, 0, 100, 100);// 目标图像
ctx1.globalCompositeOperation = 'source-over';
ctx1.fillStyle = "green";
ctx1.arc(100, 100, 50, 0, Math.PI * 2);
ctx1.fill();//源图像
/* source-atop在只在目标上显示源图像 */
let ctx2 = canvas2.getContext('2d');
ctx2.fillStyle = "orange";
ctx2.fillRect(0, 0, 100, 100);//目标图像
ctx2.globalCompositeOperation = 'source-atop';
ctx2.fillStyle = "green";
ctx2.arc(100, 100, 50, 0, Math.PI * 2);
ctx2.fill();//源图像
/* source-in仅仅显示重叠部分源图像 */
let ctx3 = canvas3.getContext('2d');
ctx3.fillStyle = "orange";
ctx3.fillRect(0, 0, 100, 100);//目标图像
ctx3.globalCompositeOperation = 'source-in';
ctx3.fillStyle = "green";
ctx3.arc(100, 100, 50, 0, Math.PI * 2);
ctx3.fill();//源图像
/* source-out目标图像所在区域透明 */
let ctx4 = canvas4.getContext('2d');
ctx4.fillStyle = "orange";
ctx4.fillRect(0, 0, 100, 100);//目标图像
ctx4.globalCompositeOperation = 'source-out';
ctx4.fillStyle = "green";
ctx4.arc(100, 100, 50, 0, Math.PI * 2);
ctx4.fill();//源图像
canvas动画
let ctx = canvas.getContext('2d');
/* 球对象 */
function Ball(options) {
this.x = options.x || 10;
this.y = options.y || 10;
this.r = options.r || 10;
this.speedX = options.speedX || 2;
this.speedY = options.speedY || 2;
this.color = options.color || 'orange';
}
/* 绘制 */
Ball.prototype.draw = function () {
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
ctx.fill();
}
/* 更新 */
Ball.prototype.move = function () {
if (this.x + this.speedX < this.r || this.x + this.speedX > canvas.width - this.r) {
this.speedX *= -1;
}
if (this.y + this.speedY < this.r || this.y + this.speedY > canvas.height - this.r) {
this.speedY *= -1;
}
this.x += this.speedX;
this.y += this.speedY;
}
/* 开始 */
function start(ball) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ball.draw();
ball.move();
window.requestAnimationFrame(() => start(ball));
}
/* 创建实例 */
let ball = new Ball({ x: 30, y: 30, r: 30 });
start(ball);