Canvas相关概念集合

发布于:2023-01-12 ⋅ 阅读:(630) ⋅ 点赞:(0)

使用 canvas 来绘制图形过程详细说明api调用的方法和过程:

绘制一个矩形:

init();
function init(){
    var canvas = document.querySelector("canvas");/* 首先,找到 <canvas> 元素: */
    if (canvas.getContext) {
        var ctx = canvas.getContext('2d');/*然后,创建 context 对象:  */
        ctx.fillStyle="#FF0000";
        ctx.fillRect(25, 25, 100, 100);/* 绘制一个填充的矩形 */
        ctx.clearRect(45, 45, 60, 60);/* 清除指定矩形区域,让清除部分完全透明。 */
        ctx.strokeRect(50, 50, 50, 50);/* 绘制一个矩形的边框 */
    }
}

上面提供的方法之中每一个都包含了相同的参数。x 与 y 指定了在 canvas 画布上所绘制的矩形的左上角(相对于原点)的坐标。width 和 height 设置矩形的尺寸。
在这里插入图片描述

绘制路径

  1. 首先,你需要创建路径起始点。
  2. 然后你使用画图命令去画出路径。
  3. 之后你把路径封闭。
  4. 一旦路径生成,你就能通过描边填充路径区域来渲染图形。

ctx.beginPath();

  • 新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。

ctx.closePath();

  • 闭合路径之后图形绘制命令又重新指向到上下文中。

stroke()

  • 通过填充路径的内容区域生成实心的图形。

生成路径的第一步叫做 beginPath()。本质上,路径是由很多子路径构成,这些子路径都是在一个列表中,所有的子路径(线、弧形、等等)构成图形。而每次这个方法调用之后,列表清空重置,然后我们就可以重新绘制新的图形。

备注: 当前路径为空,即调用 beginPath() 之后,或者 canvas 刚建的时候,第一条路径构造命令通常被视为是 moveTo();指明起始的位置。

闭合路径 closePath(),不是必需的。这个方法会通过绘制一条从当前点到开始点的直线来闭合图形。如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。

当你调用 fill() 函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用 closePath() 函数。但是调用 stroke() 时不会自动闭合。

通过路径描边和填充完成一个三角形和圆形

var canvas = document.querySelector("canvas")
var ctx = canvas.getContext('2d');
ctx.beginPath();
/*moveTo()函数设置起点。*/
ctx.moveTo(75, 50);/*将笔触移动到指定的坐标 x 以及 y 上。*/
/*绘制一条从当前位置到指定 x 以及 y 位置的直线。*/
ctx.lineTo(100, 75);
ctx.lineTo(100, 25);
ctx.lineTo(75, 50);
ctx.closePath();/* 闭合 */
ctx.stroke();/* 描边//通过起始点闭合 */
// ctx.fill();/* 填充 //自动闭合*/


/* 绘制一个圆型 */
ctx.beginPath();//又开始一个路径
ctx.arc(100,200,40,0,2*Math.PI);
ctx.stroke();

在这里插入图片描述

绘制圆弧:

绘制圆弧或者圆,我们使用arc()方法。
arc(x, y, radius, startAngle, endAngle, anticlockwise)
画一个以(x,y)为圆心的以 radius 为半径的圆弧(圆),从 startAngle 开始到 endAngle 结束,按照 anticlockwise 给定的方向(false:默认为顺时针)来生成。
但是0,表示开始的位置是坐标点的半径最右端开始都是以 x 轴为基准

arc() 函数中表示角的单位是弧度,不是角度。角度与弧度的 js 表达式:

弧度=(Math.PI/180)*角度。

/* 绘制一个圆型 */
ctx.beginPath();
ctx.arc(100,200,50,0,2*Math.PI);
ctx.stroke();
/* 绘制一个半圆型 */
ctx.beginPath();
ctx.arc(100,200,50,Math.PI/180*180,Math.PI/180*360);
ctx.stroke();

绘制多行弧度值不一样的圆弧。

init();
function init(){
    var canvas = document.querySelector("canvas");
    var ctx = canvas.getContext("2d");
    for(var i=0;i<4;i++){
        for(var j=0;j<3;j++){
            ctx.beginPath()
            var x= 25+j*50;
            var y= 25+i*50;
            var radius = 20;
            var start = 0;
            var end = Math.PI + (Math.PI*j)/2;
            var distion = i%2 == 0? false:true;
            ctx.arc(x,y,radius,start,end,distion);
            if(i>1)
                ctx.fill();
            else 
                ctx.stroke();
        }
    }
}

在这里插入图片描述

使用样式和颜色

色彩 Colors
fillStyle = color
设置图形的填充颜色。
strokeStyle = color
设置图形轮廓的颜色。

随机色版,填充样式作为 ctx.fillStyle方法;

drow();
function drow(){
    var ctx = document.querySelector("canvas").getContext("2d");
    for(var i=0;i<50;i++){
        for(var j=0;j<35;j++){
            ctx.fillStyle = Array(6).fill(1).reduce(v=>v+ (~~(Math.random()*16)).toString(16),"#")
            ctx.fillRect(j*25,i*25,25,25)
        }
    }
}

在这里插入图片描述

strokeStyle方法

draw();
function draw(){
    var ctx = document.querySelector("canvas").getContext("2d");
    for(var i=0;i<30;i++){
        for(var j=0;j<60;j++){
            ctx.strokeStyle = Array(6).fill(1).reduce(v=>v+ (~~(Math.random()*16)).toString(16),"#")
            ctx.beginPath();
            ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true);
            ctx.stroke();
        }
    }
}

在这里插入图片描述

设置透明度Transparency

除了可以绘制实色图形,我们还可以用 canvas 来绘制半透明的图形。通过设置 globalAlpha 属性或者使用一个半透明颜色作为轮廓填充的样式。

rgba() 方法与 rgb() 方法类似,就多了一个用于设置色彩透明度的参数。它的有效范围是从 0.0(完全透明)到 1.0(完全不透明)。

daoe();

function daoe() {
    var ctx = document.querySelector("canvas").getContext("2d");
    // 画背景
    ctx.fillStyle = 'rgb(255,221,0)';
    ctx.fillRect(0, 0, 150, 37.5);
    ctx.fillStyle = 'rgb(102,204,0)';
    ctx.fillRect(0, 37.5, 150, 37.5);
    ctx.fillStyle = 'rgb(0,153,255)';
    ctx.fillRect(0, 75, 150, 37.5);
    ctx.fillStyle = 'rgb(255,51,0)';
    ctx.fillRect(0, 112.5, 150, 37.5);
    for (var i = 0; i < 10; i++) {
        ctx.fillStyle = 'rgba(255,255,255,' + (i + 1) / 10 + ')';
        console.log(ctx.fillStyle);
        for (var j = 0; j < 4; j++) {
            ctx.fillRect(5 + i * 14, 5 + j * 37.5, 14, 27.5)
        }
    }

}

在这里插入图片描述

线型 Line styles

lineWidth = value
设置线条宽度。

draw() ;
function draw() {
    var ctx = document.querySelector("canvas").getContext("2d");
    for (var i = 0; i < 10; i++) {
        ctx.lineWidth = 1 + i;
        ctx.beginPath();
        ctx.moveTo(5 + i * 14, 5);
        ctx.lineTo(5 + i * 14, 140);
        ctx.stroke();
    }
}

在这里插入图片描述

lineCap = type
设置线条末端样式。

draw() ;
function draw() {
    var ctx = document.querySelector("canvas").getContext("2d");
    var lineCap = ['butt', 'round', 'square'];

    // 创建蓝色路径
    ctx.strokeStyle = '#09f';
    ctx.beginPath();
    ctx.moveTo(10, 10);
    ctx.lineTo(140, 10);
    ctx.moveTo(10, 140);
    ctx.lineTo(140, 140);
    ctx.stroke();
   

    // 画竖立线条
    ctx.strokeStyle = 'black';
    for (var i = 0; i < lineCap.length; i++) {
        ctx.lineWidth = 15;
        ctx.lineCap = lineCap[i];
        ctx.beginPath();
        ctx.moveTo(25 + i * 50, 10);
        ctx.lineTo(25 + i * 50, 140);
        ctx.stroke();
    }
}

在这个例子里面,我绘制了三条直线,分别赋予不同的 lineCap 值。还有两条辅助线,为了可以看得更清楚它们之间的区别,三条线的起点终点都落在辅助线上。

最左边的线用了默认的 butt 。可以注意到它是与辅助线齐平的。中间的是 round 的效果,端点处加上了半径为一半线宽的半圆。右边的是 square 的效果,端点处加上了等宽且高度为一半线宽的方块。
在这里插入图片描述

lineJoin = type
设定线条与线条间接合处的样式。
lineJoin 的属性值决定了图形中两线段连接处所显示的样子。它可以是这三种之一:round, bevel 和 miter。默认是 miter``。

draw();
function draw() {
    var ctx = document.querySelector("canvas").getContext("2d");
    var lineJoin = ['round', 'bevel', 'miter'];
    ctx.lineWidth = 10;
    for (var i = 0; i < lineJoin.length; i++) {
        ctx.lineJoin = lineJoin[i];
        ctx.beginPath();
        ctx.moveTo(-5, 5 + i * 40);
        ctx.lineTo(35, 45 + i * 40);
        ctx.lineTo(75, 5 + i * 40);
        ctx.lineTo(115, 45 + i * 40);
        ctx.lineTo(155, 5 + i * 40);
        ctx.stroke();
    }
}

miterLimit = value
限制当两条线相交时交接处最大长度;所谓交接处长度(斜接长度)是指线条交接处内角顶点到外角顶点的长度。

draw();
function draw() {
    var ctx = document.querySelector("canvas").getContext("2d");
    var lineJoin = ['round', 'bevel', 'miter'];
    ctx.lineWidth = 10;
    for (var i = 0; i < lineJoin.length; i++) {
        ctx.lineJoin = lineJoin[i];
        ctx.beginPath();
        ctx.moveTo(-5, 5 + i * 40);
        ctx.lineTo(35, 45 + i * 40);
        ctx.lineTo(75, 5 + i * 40);
        ctx.lineTo(115, 45 + i * 40);
        ctx.lineTo(155, 5 + i * 40);
        ctx.stroke();
    }
}

在这里插入图片描述

Canvas 填充规则

当我们用到 fill();
该填充规则根据某处在路径的外面或者里面来决定该处是否被填充,这对于自己与自己路径相交或者路径被嵌套的时候是有用的。
也可以填充文本: ctx.fillText("Sample String", 5, 30);

draw();
function draw() {
    var ctx = document.querySelector("canvas").getContext("2d");
    ctx.beginPath();
    ctx.arc(50, 50, 30, 0, Math.PI * 2, true);
    ctx.arc(50, 50, 15, 0, Math.PI * 2, true);
    // ctx.fill()
    ctx.fill("evenodd");
}

在这里插入图片描述

draw();

function draw() {
    var ctx = document.querySelector("canvas").getContext("2d");

    ctx.shadowOffsetX = 2;/* 来设定阴影在 X 和 Y 轴的延伸距离 */
    ctx.shadowOffsetY = 2;
    ctx.shadowBlur = 2;/* shadowBlur 用于设定阴影的模糊程度,其数值并不跟像素数量挂钩,也不受变换矩阵的影响,默认为 0。 */
    ctx.shadowColor = "rgba(0, 0, 0, 0.5)";/* shadowColor 是标准的 CSS 颜色值,用于设定阴影颜色效果,默认是全透明的黑色。 */

    ctx.font = "20px Times New Roman";/* 字体 */
    ctx.fillStyle = "Black"; /* 填充颜色 */
    ctx.fillText("Sample String", 5, 30);/* 填充文本 */
}

在这里插入图片描述

渐变 Gradients

我们可以用线性或者径向的渐变来填充或描边。我们用下面的方法新建一个 canvasGradient 对象,并且赋给图形的 fillStyle 或 strokeStyle 属性。
线性渐变;
createLinearGradient(x1, y1, x2, y2)
createLinearGradient 方法接受 4 个参数,表示渐变的起点 (x1,y1) 与终点 (x2,y2)。

function draw() {
     var ctx = document.querySelector("canvas").getContext("2d");
     /* 渐变的起点是针对与canvas来算的 */
     var file = ctx.createLinearGradient(0,0,100,100);/*表示渐变的起点 (x1,y1) 与终点 (x2,y2)。  */
     file.addColorStop(0,"red");/* 开始结束的过程百分比 */
     file.addColorStop(1,"orange");/* 开始结束的过程百分比 */
     ctx.fillStyle = file;
     ctx.fillRect(0,0,100,100)
 }

在这里插入图片描述
柱状图:

var arr = [120,80,95,70]/* 高 */ ,baseLine = 60/* 基线 */,scale=3/* 高比例 */,width=50;
var initY;/* 最终基线 */
var initX = 30;/* 靠左的距离 */
init();
function init(){
    console.log(canvas.height);
    initY = canvas.height-baseLine;
    for(var i=0;i<arr.length;i++){
        drawRect(arr[i],i*(width+50));
    }
}
function drawRect(num,x){
    var ctx = document.querySelector("canvas").getContext("2d");
    ctx.fillRect(initX+x,initY-num*scale,width,num*scale);
}

在这里插入图片描述

加入线性渐变

var arr = [120,80,95,70]/* 高 */ ,baseLine = 60/* 基线 */,scale=3/* 高比例 */,width=50;
var initY;/* 最终基线 */
var initX = 30;/* 靠左的距离 */
var color = ["red","orange","yellow"];
init();
function init(){
    console.log(canvas.height);
    initY = canvas.height-baseLine;
    for(var i=0;i<arr.length;i++){
        drawRect(arr[i],i*(width+50));
    }
}
function drawRect(num,x){
   
    var ctx = document.querySelector("canvas").getContext("2d");
    var fill = ctx.createLinearGradient(initX+x,initY-num*scale,initX+x,initY);
    color.forEach((t,i)=>{fill.addColorStop(1/color.length*(i+1),t)});
    ctx.fillStyle = fill;
    ctx.fillRect(initX+x,initY-num*scale,width,num*scale);
}

在这里插入图片描述

径向渐变:
createRadialGradient(x1, y1, r1, x2, y2, r2)
createRadialGradient 方法接受 6 个参数,前三个定义一个以 (x1,y1) 为原点,半径为 r1 的圆,后三个参数则定义另一个以 (x2,y2) 为原点,半径为 r2 的圆。

var ctx = document.querySelector("canvas").getContext("2d");
var fill = ctx.createRadialGradient(150,150,0,150,150,50);
fill.addColorStop(0,"red");
fill.addColorStop(1,"orange");
ctx.fillStyle = fill;
ctx.fillRect(100,100,100,100)

在这里插入图片描述

var ctx = document.querySelector("canvas").getContext("2d");
ctx.strokeStyle="#000000";
ctx.lineWidth=5;
ctx.lineCap="round";


canvas.addEventListener("mousedown",mouseHandler);
function mouseHandler(e){
    if(e.type==="mousedown"){
        canvas.addEventListener("mousemove",mouseHandler);
        document.addEventListener("mouseup",mouseHandler);
        ctx.moveTo(e.offsetX,e.offsetY);
    }else if(e.type==="mousemove"){
        ctx.lineTo(e.offsetX,e.offsetY);
        ctx.stroke();
    }else if(e.type==="mouseup"){
        canvas.removeEventListener("mousemove",mouseHandler);
        document.removeEventListener("mouseup",mouseHandler);
    }
}

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到