MIKUScallion 2020-02-13
画布的基础知识
专门研究画布的大佬
手动实现echar的大佬
echar官方
画布之水印
ctx.font = "bold 20px Arial"; ctx.lineWidth = "1"; ctx.fillStyle = "rgba(255 , 255 , 255, 0.5)"; ctx.fillText("===文字===", 50, 50);
画布之滤镜
var img = new Image() img.src = "./img/photo.jpg" img.onload = function () { var canvas = document.querySelector("#my-canvas"); var ctx = canvas.getContext("2d"); canvas.width = img.width canvas.height = img.height ctx.drawImage(img, 0, 0, canvas.width, canvas.height) // 开始滤镜处理 var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); for (var i = 0; i < imgData.data.length / 4; ++i) { var red = imgData.data[i * 4], green = imgData.data[i * 4 + 1], blue = imgData.data[i * 4 + 2]; var gray = 0.3 * red + 0.59 * green + 0.11 * blue; // 计算gray // 刷新RGB,注意: // imgData.data[i * 4 + 3]存放的是alpha,不需要改动 imgData.data[i * 4] = gray; imgData.data[i * 4 + 1] = gray; imgData.data[i * 4 + 2] = gray; } ctx.putImageData(imgData, 0, 0); // 重写图像数据 }
画布之放大镜
<canvas id="my-canvas"></canvas> <canvas id="off-canvas" style="display: none;"></canvas> var isMouseDown = false,scale = 1.0; var canvas = document.querySelector("#my-canvas"); var offCanvas = document.querySelector("#off-canvas"); // 离屏 canvas var ctx = canvas.getContext("2d"); var offCtx = offCanvas.getContext("2d"); // 离屏 canvas 的 Context对象 var img = new Image(); window.onload = function() { img.src = "./img/xxx.jpg"; img.onload = function() { canvas.width = img.width; canvas.height = img.height; offCanvas.width = img.width; offCanvas.height = img.height; // 计算缩放比例 scale = offCanvas.width / canvas.width; // 初识状态下, 两个canvas均绘制Image ctx.drawImage(img, 0, 0, canvas.width, canvas.height); offCtx.drawImage(img, 0, 0, canvas.width, canvas.height); }; // 鼠标按下 canvas.onmousedown = function(event) { event.preventDefault(); // 禁用默认事件 var point = windowToCanvas(event.clientX, event.clientY); // 获取鼠标相对于 canvas 标签的坐标 isMouseDown = true; drawCanvasWithMagnifier(true, point); // 绘制在离屏canvas上绘制放大后的图像 }; // 鼠标移动 canvas.onmousemove = function(event) { event.preventDefault(); // 禁用默认事件 if (isMouseDown === true) { var point = windowToCanvas(event.clientX, event.clientY); drawCanvasWithMagnifier(true, point); } }; // 鼠标松开 canvas.onmouseup = function(event) { event.preventDefault(); // 禁用默认事件 isMouseDown = false; drawCanvasWithMagnifier(false); // 不绘制离屏放大镜 }; // 鼠标移出canvas标签 canvas.onmouseout = function(event) { event.preventDefault(); // 禁用默认事件 isMouseDown = false; drawCanvasWithMagnifier(false); // 不绘制离屏放大镜 }; }; /** * 返回鼠标相对于canvas左上角的坐标 * @param {Number} x 鼠标的屏幕坐标x * @param {Number} y 鼠标的屏幕坐标y */ function windowToCanvas(x, y) { var bbox = canvas.getBoundingClientRect(); // bbox中存储的是canvas相对于屏幕的坐标 return { x: x - bbox.x, y: y - bbox.y }; } function drawCanvasWithMagnifier(isShow, point) { ctx.clearRect(0, 0, canvas.width, canvas.height); // 清空画布 ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // 在画布上绘制图像 /* 利用离屏,绘制放大镜 */ if(isShow){ var { x, y } = point; var mr = 50; // 正方形放大镜边长 // (sx, sy): 待放大图像的开始坐标 var sx = x - mr / 2,sy = y - mr / 2; // (dx, dy): 已放大图像的开始坐标 var dx = x - mr,dy = y - mr; // 将offCanvas上的(sx,sy)开始的长宽均为mr的正方形区域 // 放大到 // canvas上的(dx,dy)开始的长宽均为 2 * mr 的正方形可视区域 // 由此实现放大效果 ctx.drawImage(offCanvas, sx, sy, mr, mr, dx, dy, 2 * mr, 2 * mr); } }
画布之刮刮乐
<div class="container" id="container"> <div id="box">一等奖</div> <canvas id="canvas">需要定位到box上面</canvas> </div> var canvas = document.querySelector("#canvas"); canvas.width = box.offsetWidth; canvas.height = box.offsetHeight; let context = canvas.getContext('2d'); //背景填充色 context.fillStyle = '#ccc'; context.fillRect(0, 0, box.offsetWidth, box.offsetHeight); //把灰色矩形当做目标对象 然后线当做源对象 //destination-out 在源图像外显示目标图像。只有源图像外的目标图像部分会被显示,源图像是透明的。 //destination-in 在源图像中显示目标图像。只有源图像内的目标图像部分会被显示,源图像是透明的。 context.globalCompositeOperation = 'destination-out'; canvas.addEventListener("touchstart", function (e) { context.beginPath(); context.moveTo(e.touches[0].pageX, e.touches[0].pageY); context.lineWidth = 20; context.lineCap = 'round'; context.lineJoin = 'round'; canvas.addEventListener("touchmove", function (e) { context.lineTo(e.touches[0].pageX, e.touches[0].pageY); context.stroke(); }) canvas.addEventListener("touchend", function (e) { context.closePath(); }) })
画布之图表
画布之动画和游戏
有很多的JS游戏引擎,游戏引擎是什么
这个太高端,原理是用一个很大的对象存放画面上所有物体的位置和大小,用计时器去清空页面再绘制页面,给画布添加点击事件判断位置,可以搜索一些画布做的打飞机,贪吃蛇,象棋游戏看一下源码
饼图
var all = 11; var arr = [["green",5],["red",6]] var startAngle = 0; arr.forEach(function (opt) { var endAngle = startAngle + opt[1]/all * Math.PI * 2; //结束弧度 var cenAngle = startAngle + opt[1]/all * Math.PI; //中间线孤独 ctx.beginPath(); ctx.moveTo(0,0); //移动到到圆心 ctx.fillStyle = opt[0]; ctx.arc(0, 0 , windowW/3, startAngle,endAngle, false); ctx.fill(); var x = windowW/3 * Math.cos(cenAngle),//圆弧上线与圆相交点的x坐标 y = windowW/3 * Math.sin(cenAngle);//圆弧上线与圆相交点的y坐标 x = x<0 ? x-20 : x+20; y = y<0 ? y-20 : y+20; ctx.beginPath(); ctx.strokeStyle = colorObj[opt[0]]; ctx.moveTo(0,0); ctx.lineTo(x,y); ctx.lineTo(x+20,y); ctx.font = "14px Times New Roman"; ctx.fillText(((opt[1]/all)*100).toFixed(1)+'%',x+20,y); ctx.stroke(); ctx.closePath(); startAngle = endAngle; })