Canvas从入门到实战( 二 )

 

Canvas从入门到实战

文章插图
 
3.4、绘制圆弧:
 
  • .arc(x,y,radius,startAngle,endAngle,anticlockwise):画一个以(x,y)为圆心的以 radius 为半径的圆弧(圆) , 从 startAngle 开始到 endAngle 结束 , 按照 anticlockwise 给定的方向(默认为顺时针 , false)来生成;
  • arcTo(x1,y1,x2,y2,radius):根据给定的两条切线中的一组切点坐标生成半径为radius的圆弧;
 
Canvas从入门到实战

文章插图
 
注意:arc函数中的角度的单位是弧度而不是度 , 弧度=(Math.PI/180)*度
// 圆左上部分ctx.beginPath()ctx.arc(100,100,50,Math.PI,Math.PI*3/2,false)ctx.strokeStyle = '#ff6700'ctx.stroke()// 圆右上部分ctx.beginPath()ctx.arc(100,100,50,Math.PI*3/2,0,false)ctx.strokeStyle = '#6700ff'ctx.stroke()// 圆右下部分ctx.beginPath()ctx.arc(100,100,50,0,Math.PI/2,false)ctx.strokeStyle = '#00FFFF'ctx.stroke()// 圆左下部分ctx.beginPath()ctx.arc(100,100,50,Math.PI/2,Math.PI,false)ctx.strokeStyle = '#8B008B'ctx.stroke()// 两条切线的交点坐标为(0,0)ctx.beginPath()ctx.moveTo(100,0)ctx.arcTo(0,0,0,100,100)ctx.fillStyle = 'blue'ctx.fill()
3.5、渐变对象:
 
  • .createLinearGradient(x1, y1, x2, y2):创建一个沿参数坐标指定的直线的渐变 , 开始坐标为(x1,y1) , 结束坐标为(x2,y2);
  • .createRadialGradient(x1, y1, r1, x2, y2, r2):创建根据参数确定两个圆的坐标的放射性渐变 , 开始圆形圆心为(x1,y1) , 半径为r1;结束圆形圆心为(x2,y2) , 半径为r2;
 
创建好渐变对象之后 , 可以通过渐变对象上的.addColorStop(offset,color)为每一个渐变阶段填充颜色 , offset为0-1的偏移值 。
const gradient = ctx.createLinearGradient(50, 50, 250, 50)gradient.addColorStop(0, 'blue')gradient.addColorStop(0.5, 'green')gradient.addColorStop(1, 'red')ctx.fillStyle = gradientctx.fillRect(0, 0, 300, 90)const radialGradient = ctx.createRadialGradient(200,200,100,200,200,50);radialGradient.addColorStop(0,"yellow");radialGradient.addColorStop(1,"green");ctx.fillStyle = radialGradient;ctx.fillRect(100,100,200,200);
3.6、像素操作:
 
  • .drawImage(image,x,y,width,height):image可以是image对象、canvas元素、video元素;
  • .getImageData(x,y,width,height):获取坐标为(x,y)一定区域内图像的像素数据;
const div = document.querySelector('div')let mousedown = false;function getRandom() {return Math.round(255 * Math.random());function getColor() {return `rgb(${getRandom()},${getRandom()},${getRandom()})`;const gradient = ctx.createLinearGradient(0, 0, 300, 300);gradient.addColorStop(0, getColor());gradient.addColorStop(0.6, getColor());gradient.addColorStop(1, getColor());function clear() {ctx.fillStyle = gradient;ctx.fillRect(0, 0, canvas.width, canvas.height);ctx.beginPath();ctx.fillStyle = gradient;ctx.fillRect(0, 0, 300, 300);function selector(x = 150, y = 150) {clear();ctx.beginPath();ctx.arc(x, y, 5, 0, Math.PI * 2);ctx.strokeStyle = "#fff";ctx.stroke();const { data } = ctx.getImageData(x, y, 1, 1); // 获取(x,y)点对应的imageDataconst color = `rgba(${data[0]},${data[1]},${data[2]},${data[3] / 255})`div.innerText = `color: ${color}`;div.style.backgroundColor = colorfunction handleSelector(e) {const x = e.offsetX;const y = e.offsetY;selector(x, y);canvas.addEventListener("mousedown", (e) => {mousedown = true;handleSelector(e)canvas.addEventListener("mouseup", () => {mousedown = false;canvas.addEventListener("mousemove", (e) => {if (mousedown) {handleSelector(e)selector(); 
3.7、画布状态:
 
  • .save():将当前画布的状态推入到栈中 , 例如fillStyle、2D转换等;
  • .restore():将栈顶元素弹出 , 恢复上一次推入栈中画布的状态;
 
【Canvas从入门到实战】当我们需要通过空间转换来绘制图形时 , 保存与恢复画布的状态是很关键的 , 因为我们是在同一块画布上绘制图形 , 而变换都是基于画布的 , 这与我们平时使用到的css 2D转换截然不同 , 所以我们在下一步绘制时要确认此时画布的状态是否是我们的理想状态 。
ctx.save() // 保存画布初始状态ctx.translate(100,100) // 将画布原点转移至(100,100)ctx.fillStyle = 'red'ctx.fillRect(0,0,50,50)ctx.restore() // 恢复画布状态 , 此时画布原点为(0,0)ctx.fillStyle = 'blue'ctx.fillRect(0,0,50,50)


推荐阅读