详解HTML5 canvas制图基础应用方式

日期:2021-02-26 类型:科技新闻 

关键词:免费自助建站,手机建站平台,wap建站,免费自助建站平台,H5网站,H5模板建站

<canvas></canvas>是HTML5中新增的标识,用于绘图图型,具体上,这个标识和别的的标识1样,其独特的地方在于该标识能够获得1个CanvasRenderingContext2D目标,大家能够根据JavaScript脚本制作来操纵该目标开展制图。

<canvas></canvas>只是1个绘图图型的器皿,除id、class、style等特性外,也有height和width特性。在<canvas>>元素上制图关键有3步:

  1. 获得<canvas>元素对应的DOM目标,这是1个Canvas目标;
  2. 启用Canvas目标的getContext()方式,获得1个CanvasRenderingContext2D目标;
  3. 启用CanvasRenderingContext2D目标开展制图。

绘图直线moveTo()和lineTo()

下列是1个简易的<canvas>制图示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF⑻">
    <title>canvas制图演试</title>
    <style type="text/css">
        #canvas{
            border: 1px solid #ADACB0;
            display: block;
            margin: 20px auto;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="300" height="300">
        你的访问器还不适用canvas
    </canvas>
</body>
<script type="text/javascript">
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    //设定目标起止点和终点站
    context.moveTo(10,10);
    context.lineTo(200,200);
    //设定款式
    context.lineWidth = 2;
    context.strokeStyle = "#F5270B";
    //绘图
    context.stroke();
</script>
</html>

假如沒有根据moveTo()非常特定,lineTo()的起止点是以上1个点为准。因而,假如必须再次挑选起止点,则必须根据moveTo()方式。假如必须对不一样的直线设定款式,则必须根据context.beginPath()再次打开1条相对路径,下面是1个示例:

<script type="text/javascript">
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    //设定目标起止点和终点站
    context.beginPath();
    context.moveTo(100,100);
    context.lineTo(700,100);
    context.lineTo(700,400);
    context.lineWidth = 2;
    context.strokeStyle = "#F5270B";
    //绘图
    context.stroke();

    context.beginPath();
    context.moveTo(100,200);//这里的moveTo换为lineTo实际效果是1样的
    context.lineTo(600,200);
    context.lineTo(600,400);
    //strokeStyle的色调有新的值,则遮盖上面设定的值
    //lineWidth沒有新的值,则按上面设定的值显示信息
    context.strokeStyle = "#0D25F6";
    //绘图
    context.stroke();
</script>

绘图矩形框rect()、fillRect()和strokeRect()

  1. context.rect( x , y , width , height ):只界定矩形框的相对路径;
  2. context.fillRect( x , y , width , height ):立即绘图出填充的矩形框;
  3. context.strokeRect( x , y , width , height ):立即绘图出矩形框边框;
<script type="text/javascript">
    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");

    //应用rect方式
    context.rect(10,10,190,190);
    context.lineWidth = 2;
    context.fillStyle = "#3EE4CB";
    context.strokeStyle = "#F5270B";
    context.fill();
    context.stroke();

    //应用fillRect方式
    context.fillStyle = "#1424DE";
    context.fillRect(210,10,190,190);

    //应用strokeRect方式
    context.strokeStyle = "#F5270B";
    context.strokeRect(410,10,190,190);

    //另外应用strokeRect方式和fillRect方式
    context.fillStyle = "#1424DE";
    context.strokeStyle = "#F5270B";
    context.strokeRect(610,10,190,190);
    context.fillRect(610,10,190,190);
</script>

这里必须表明两点:第1点便是stroke()和fill()绘图的前后左右次序,假如fill()后边绘图,那末当stroke边框较大时,会显著的把stroke()绘图出的边框遮挡住1半;第2点:设定fillStyle或strokeStyle特性时,能够根据“rgba(255,0,0,0.2)”的设定方法来设定,这个设定的最终1个主要参数是全透明度。

此外也有1个跟矩形框绘图相关的:消除矩形框地区:context.clearRect(x,y,width,height)。

接受主要参数各自为:消除矩形框的起止部位和矩形框的宽和长。

在上面的编码中绘图图型的最终再加:

context.clearRect(100,60,600,100);

能够获得下列实际效果:

绘图5角星

根据对5角星剖析,大家能够明确各个端点座标的规律性,这里必须留意的1点是:在canvas中,Y轴的方位是向下的。

相应编码以下:

var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    context.beginPath();
    //设定是个端点的座标,依据端点制订相对路径
    for (var i = 0; i < 5; i++) {
        context.lineTo(Math.cos((18+i*72)/180*Math.PI)*200+200,
                        -Math.sin((18+i*72)/180*Math.PI)*200+200);
        context.lineTo(Math.cos((54+i*72)/180*Math.PI)*80+200,
                        -Math.sin((54+i*72)/180*Math.PI)*80+200);
    }
    context.closePath();
    //设定边框款式和填充色调
    context.lineWidth="3";
    context.fillStyle = "#F6F152";
    context.strokeStyle = "#F5270B";
    context.fill();
    context.stroke();

最终实际效果:

线条特性

除上面用到的lineWidth特性,线条也有下列几个特性:

lineCap 特性设定或回到线条尾端线帽的款式,能够取下列几个值:

  1. “butt” 向线条的每一个尾端加上平直的边沿(默认设置);
  2. “round” 向线条的每一个尾端加上圆形线帽;
  3. “square” 向线条的每一个尾端加上正方形线帽。

lineJoin 特性当两条线交汇时设定或回到所建立边角的种类,能够取下列几个值:

  1. “miter” 建立尖角(默认设置);
  2. “bevel” 建立斜角;
  3. “round” 建立圆角。

miterLimit 特性设定或回到最大斜接长度(默认设置为10)。斜接长度指的是在两条线交汇处内角和外角之间的间距。仅有当 lineJoin 特性为 “miter” 时,miterLimit 才合理。

var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    //检测lineCap特性
    //设定标准线便于观查
    context.moveTo(10,10);
    context.lineTo(10,200);
    context.moveTo(200,10);
    context.lineTo(200,200);
    context.lineWidth="1";
    context.stroke();
    //butt
    context.beginPath();
    context.moveTo(10,50);
    context.lineTo(200,50);
    context.lineCap="butt";
    context.lineWidth="10";
    context.stroke();
    //round
    context.beginPath();
    context.moveTo(10,100);
    context.lineTo(200,100);
    context.lineCap="round";
    context.lineWidth="10";
    context.stroke();
    //square
    context.beginPath();
    context.moveTo(10,150);
    context.lineTo(200,150);
    context.lineCap="square";
    context.lineWidth="10";
    context.stroke();

    //检测linJoin特性
    //miter
    context.beginPath();
    context.moveTo(300,50);
    context.lineTo(450,100);
    context.lineTo(300,150);
    context.lineJoin="miter";
    context.lineWidth="10";
    context.stroke();
    //round
    context.beginPath();
    context.moveTo(400,50);
    context.lineTo(550,100);
    context.lineTo(400,150);
    context.lineJoin="round";
    context.lineWidth="10";
    context.stroke();
    //square
    context.beginPath();
    context.moveTo(500,50);
    context.lineTo(650,100);
    context.lineTo(500,150);
    context.lineJoin="bevel";
    context.lineWidth="10";
    context.stroke();

    //检测miterLimit特性
    context.beginPath();
    context.moveTo(700,50);
    context.lineTo(850,100);
    context.lineTo(700,150);
    context.lineJoin="miter";
    context.miterLimit="2";
    context.lineWidth="10";
    context.strokeStyle="#2913EC";
    context.stroke();

各特性的不一样赋值的实际效果以下:

填充款式

前面用到的fillStyle和strokeStyle除设定色调外,还能设定别的填充款式,这里以fillStyle为例:

线形渐变色

应用流程

(1)var grd = context.createLinearGradient( xstart , ystart, xend , yend )建立1个线形渐变色,设定起止座标和终点站座标;
(2)grd.addColorStop( stop , color )为线形渐变色加上色调,stop为0~1的值;
(3)context.fillStyle=grd将取值给context。

轴向渐变色

该方式与线形渐变色应用方式相近,只是第1步接受的主要参数不1样

var grd = context.createRadialGradient(x0 , y0, r0 , x1 , y1 , r1 );接受起止圆心的座标和圆半径和终点站圆心的座标和圆的半径。

位图填充

createPattern( img , repeat-style )应用照片填充,repeat-style能够取repeat、repeat-x、repeat-y、no-repeat。

var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");

    //线形渐变色
    var grd = context.createLinearGradient( 10 , 10, 100 , 350 );
    grd.addColorStop(0,"#1EF9F7");
    grd.addColorStop(0.25,"#FC0F31");
    grd.addColorStop(0.5,"#ECF811");
    grd.addColorStop(0.75,"#2F0AF1");
    grd.addColorStop(1,"#160303");
    context.fillStyle = grd;
    context.fillRect(10,10,100,350);

    //轴向渐变色
    var grd = context.createRadialGradient(325 , 200, 0 , 325 , 200 , 200 );
    grd.addColorStop(0,"#1EF9F7");
    grd.addColorStop(0.25,"#FC0F31");
    grd.addColorStop(0.5,"#ECF811");
    grd.addColorStop(0.75,"#2F0AF1");
    grd.addColorStop(1,"#160303");
    context.fillStyle = grd;
    context.fillRect(150,10,350,350);

    //位图填充
    var bgimg = new Image();
    bgimg.src = "background.jpg";
    bgimg.onload=function(){
        var pattern = context.createPattern(bgimg, "repeat");
        context.fillStyle = pattern;
        context.strokeStyle="#F20B0B";
        context.fillRect(600, 100, 200,200);
        context.strokeRect(600, 100, 200,200);
    };

实际效果以下:

图型转换

平移:context.translate(x,y),接受主要参数各自为原点在x轴方位平移x,在y轴方位平移y。

放缩:context.scale(x,y),接受主要参数各自为x座标轴按x占比放缩,y座标轴按y占比放缩。

转动:context.rotate(angle),接受主要参数是座标轴转动的角度。

必须表明的是,对图型开展转变后,接下来的1次制图是紧接着上1次的情况的,因此假如必须返回原始情况,要用到context.save();context.restore();来储存和修复当今情况:

 var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");

    //translate()
    context.save();
    context.fillStyle = "#1424DE";
    context.translate(10,10);
    context.fillRect(0,0,200,200);
    context.restore();

    //scale()
    context.save();
    context.fillStyle = "#F5270B";
    context.scale(0.5,0.5);
    context.fillRect(500,50,200,200);
    context.restore();
    //rotate()

    context.save();
    context.fillStyle = "#18EB0F";
    context.rotate(Math.PI / 4);
    context.fillRect(300,10,200,200);
    context.restore();

实际效果以下:

此外1个跟图型转换有关的是:引流矩阵转换 :context.transform(a, b, c, d, e, f, g)。主要参数的含意以下:
a 水平放缩 ( 默认设置为1 )
b 水平歪斜 ( 默认设置为 0 )
c 竖直歪斜 ( 默认设置为 0 )
d 竖直放缩 ( 默认设置为1 )
e 水平位移 ( 默认设置为 0 )
f 竖直位移 ( 默认设置为 0 )
读者能够自主认证其各个主要参数的实际效果,这里就不11详细介绍了。

绘图曲线图

跟绘图曲线图的有4个涵数,各自是:

context.arc(x,y,r,sAngle,eAngle,counterclockwise);用于建立弧/曲线图(用于建立圆或一部分圆)。接受的主要参数含意:
| 主要参数 | 含意 |
| :————- |:————-|
| x | 圆的管理中心的 x 座标 |
|y|圆的管理中心的 y 座标|
|r|圆的半径|
|sAngle|起止角,以弧度计(弧的圆形的3点钟部位是 0 度)|
|eAngle|完毕角,以弧度计|
|counterclockwise|可选。要求应当逆时针還是顺时针制图。False = 顺时针,true = 逆时针|

下面是几个arc()涵数的几个示例:

    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");

    context.strokeStyle = "#F22D0D";
    context.lineWidth = "2";
    //绘图圆
    context.beginPath();
    context.arc(100,100,40,0,2*Math.PI);
    context.stroke();

    //绘图半圆
    context.beginPath();
    context.arc(200,100,40,0,Math.PI);
    context.stroke();

    //绘图半圆,逆时针
    context.beginPath();
    context.arc(300,100,40,0,Math.PI,true);
    context.stroke();

    //绘图封闭式半圆
    context.beginPath();
    context.arc(400,100,40,0,Math.PI);
    context.closePath();
    context.stroke();

实际效果以下:

context.arcTo(x1,y1,x2,y2,r); 在画布上建立介于两个切线之间的弧/曲线图。接受的主要参数含意:

主要参数 含意 x1 弧的操纵点的 x 座标 y1 弧的操纵点的 y 座标 x2 弧的终点站的 x 座标 y2 弧的终点站的 y 座标 r 弧的半径

这里必须留意的是arcTo涵数绘图的曲线图的起止点必须根据moveTo()涵数来设定,下面运用arcTo涵数绘图1个圆角矩形框:

function createRoundRect(context , x1 , y1 , width , height , radius)
    {
        // 挪动到左上角
        context.moveTo(x1 + radius , y1);
        // 加上1条联接到右上角的直线
        context.lineTo(x1 + width - radius, y1);
        // 加上1段圆弧
        context.arcTo(x1 + width , y1, x1 + width, y1 + radius, radius);
        // 加上1条联接到右下角的直线
        context.lineTo(x1 + width, y1 + height - radius);
        // 加上1段圆弧
        context.arcTo(x1 + width, y1 + height , x1 + width - radius, y1 + height , radius);
        // 加上1条联接到左下角的直线
        context.lineTo(x1 + radius, y1 + height); 
        // 加上1段圆弧
        context.arcTo(x1, y1 + height , x1 , y1 + height - radius , radius);
        // 加上1条联接到左上角的直线
        context.lineTo(x1 , y1 + radius);
        // 加上1段圆弧
        context.arcTo(x1 , y1 , x1 + radius , y1 , radius);
        context.closePath();
    }
    // 获得canvas元素对应的DOM目标
    var canvas = document.getElementById('mc');
    // 获得在canvas上制图的CanvasRenderingContext2D目标
    var context = canvas.getContext('2d');
    context.lineWidth = 3;
    context.strokeStyle = "#F9230B";
    createRoundRect(context , 30 , 30 , 400 , 200 , 50);
    context.stroke();

实际效果以下:

context.quadraticCurveTo(cpx,cpy,x,y);绘图2次贝塞曲线图,主要参数含意以下:

  主要参数 含意 cpx 贝塞尔操纵点的 x 座标 cpy 贝塞尔操纵点的 y 座标 x 完毕点的 x 座标 y 完毕点的 y 座标

曲线图的刚开始点是当今相对路径中最终1个点。假如相对路径不存在,那末请应用 beginPath() 和 moveTo() 方式来界定刚开始点。

context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y); 绘图3次贝塞尔曲线图,主要参数以下:

  主要参数 含意 cp1x 第1个贝塞尔操纵点的 x 座标 cp1y 第1个贝塞尔操纵点的 y 座标 cp2x 第2个贝塞尔操纵点的 x 座标 cp2y 第2个贝塞尔操纵点的 y 座标 x 完毕点的 x 座标 y 完毕点的 y 座标

文本3D渲染

与文字3D渲染相关的关键有3个特性和3个方式:

  特性 叙述 font 设定或回到文字內容确当前字体样式特性 textAlign 设定或回到文字內容确当前对齐方法 textBaseline 设定或回到在绘图文字时应用确当前文字基准线

方式 叙述 fillText() 在画布上绘图”被填充的”文字 strokeText() 在画布上绘图文字(无填充) measureText() 回到包括特定文字宽度的目标

上述的特性和方式的基础用法以下:

var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");

    context.font="bold 30px Arial"; //设定款式
    context.strokeStyle = "#1712F4";
    context.strokeText("欢迎来到我的blog!",30,100);

    context.font="bold 50px Arial"; 
    var grd = context.createLinearGradient( 30 , 200, 400 , 300 );//设定渐变色填充款式
    grd.addColorStop(0,"#1EF9F7");
    grd.addColorStop(0.25,"#FC0F31");
    grd.addColorStop(0.5,"#ECF811");
    grd.addColorStop(0.75,"#2F0AF1");
    grd.addColorStop(1,"#160303");
    context.fillStyle = grd;
    context.fillText("欢迎来到我的blog!",30,200);

    context.save();
    context.moveTo(200,280);
    context.lineTo(200,420);
    context.stroke();
    context.font="bold 20px Arial"; 
    context.fillStyle = "#F80707";
    context.textAlign="left";
    context.fillText("文字在特定的部位刚开始",200,300);
    context.textAlign="center";
    context.fillText("文字的管理中心被置放在特定的部位",200,350);
    context.textAlign="right";
    context.fillText("文字在特定的部位完毕",200,400);
    context.restore();

    context.save();
    context.moveTo(10,500);
    context.lineTo(500,500);
    context.stroke();
    context.fillStyle="#F60D0D";
    context.font="bold 20px Arial"; 
    context.textBaseline="top";
    context.fillText("特定部位在上面",10,500);
    context.textBaseline="bottom";
    context.fillText("特定部位在下面",150,500);
    context.textBaseline="middle";
    context.fillText("特定部位垂直居中",300,500);
    context.restore();


    context.font="bold 40px Arial"; 
    context.strokeStyle = "#16F643";
    var text = "欢迎来到我的blog!";
    context.strokeText("欢迎来到我的blog!",10,600);
    context.strokeText("上面标识符串的宽度为:"+context.measureText(text).width,10,650);

实际效果以下:

别的特性和方式

黑影绘图:

  1. shadowColor 设定或回到用于黑影的色调。
  2. shadowBlur 设定或回到用于黑影的模糊不清级別(标值越大越模糊不清)。
  3. shadowOffsetX 设定或回到黑影与样子的水平间距。
  4. shadowOffsetY 设定或回到黑影与样子的竖直间距。

大家为以前绘图的5角星加上1下黑影

var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");
    context.beginPath();
    //设定是个端点的座标,依据端点制订相对路径
    for (var i = 0; i < 5; i++) {
        context.lineTo(Math.cos((18+i*72)/180*Math.PI)*200+200,
                        -Math.sin((18+i*72)/180*Math.PI)*200+200);
        context.lineTo(Math.cos((54+i*72)/180*Math.PI)*80+200,
                        -Math.sin((54+i*72)/180*Math.PI)*80+200);
    }
    context.closePath();
    //设定边框款式和填充色调
    context.lineWidth="3";
    context.fillStyle = "#F6F152";
    context.strokeStyle = "#F5270B";
    context.shadowColor = "#F7F2B4";
    context.shadowOffsetX = 30;
    context.shadowOffsetY = 30;
    context.shadowBlur = 2;
    context.fill();
    context.stroke();

实际效果以下:

图型组成:

globalAlpha: 设定或回到制图确当前 alpha 或全透明值

该方式关键是设定图型的全透明度,这里就不实际详细介绍。

globalCompositeOperation: 设定或回到新图象怎样绘图到已有的图象上,该方式有下列特性值:

      值 叙述 source-over 在总体目标图象上显示信息源图象(默认设置) source-atop 在总体目标图象顶部显示信息源图象。源图象坐落于总体目标图象以外的一部分是不能见的 source-in 在总体目标图象中显示信息源图象。仅有总体目标图象以内的源图象一部分会显示信息,总体目标图象是全透明的 source-out 在总体目标图象以外显示信息源图象。仅有总体目标图象以外的源图象一部分会显示信息,总体目标图象是全透明的 destination-over 在源图象上显示信息总体目标图象 destination-atop 在源图象顶部显示信息总体目标图象。总体目标图象坐落于源图象以外的一部分是不能见的 destination-in 在源图象中显示信息总体目标图象。仅有源图象以内的总体目标图象一部分会被显示信息,源图象是全透明的 destination-out 在源图象以外显示信息总体目标图象。仅有源图象以外的总体目标图象一部分会被显示信息,源图象是全透明的 lighter 显示信息源图象 + 总体目标图象 copy 显示信息源图象。忽视总体目标图象 xor 应用异或实际操作对源图象与总体目标图象开展组成

下面是1个小示例,能够根据点一下更改组成实际效果:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF⑻">
    <title>图型组成</title>
    <style type="text/css">
        #canvas{
            border: 1px solid #1C0EFA;
            display: block;
            margin: 20px auto;
        }
        #buttons{
            width: 1000px;
            margin: 5px auto;
            clear:both;
        }
        #buttons a{
            font-size: 18px;
            display: block;
            float: left;
            margin-left: 20px;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="1000" height="800">
            你的访问器还不适用canvas
    </canvas>
    <div id="buttons">
        <a href="#">source-over</a>
        <a href="#">source-atop</a>
        <a href="#">source-in</a>
        <a href="#">source-out</a>
        <a href="#">destination-over</a>
        <a href="#">destination-atop</a>
        <a href="#">destination-in</a>
        <a href="#">destination-out</a>
        <a href="#">lighter</a>
        <a href="#">copy</a>
        <a href="#">xor</a>
    </div>
</body>
<script type="text/javascript">

window.onload = function(){
    draw("source-over");

    var buttons = document.getElementById("buttons").getElementsByTagName("a");
    for (var i = 0; i < buttons.length; i++) {
        buttons[i].onclick = function(){
            draw(this.text);
            return false;
        };
    }
};

    function draw(compositeStyle){
        var canvas = document.getElementById("canvas");
        var context = canvas.getContext("2d");

        context.clearRect(0, 0, canvas.width, canvas.height);

        //draw title
        context.font = "bold 40px Arial";
        context.textAlign = "center";
        context.textBasedline = "middle";
        context.fillStyle = "#150E0E";
        context.fillText("globalCompositeOperation = "+compositeStyle, canvas.width/2, 60);

        //draw a rect
        context.fillStyle = "#F6082A";
        context.fillRect(300, 150, 500, 500);

        //draw a triangle
        context.globalCompositeOperation = compositeStyle;
        context.fillStyle = "#1611F5";
        context.beginPath();
        context.moveTo(700, 250);
        context.lineTo(1000,750);
        context.lineTo(400, 750);
        context.closePath();
        context.fill();
    }

</script>
</html>

读者能够点一下标识来观查不一样的组成实际效果,实际效果以下:

剪辑地区:

clip()方式从初始画布中裁切随意样子和规格。

提醒:1旦裁切了某个地区,则全部以后的制图都会被限定在被裁切的地区内(不可以浏览画布上的别的地区)。您还可以在应用 clip() 方式前根据应用 save() 方式对当今画布地区开展储存,并在之后的随意時间对其开展修复(根据 restore() 方式)

下列是用1个圆去截取1个矩形框的示例:

var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");

    context.beginPath();
    context.fillStyle = "#0C0101";
    context.fillRect(0,0,canvas.width,canvas.height);

    context.beginPath();
    context.fillStyle = "#FFFDFD";
    context.arc(400,400,100,0,2*Math.PI);
    context.fill();
    context.clip();

    context.beginPath();
    context.fillStyle = "#F60825";
    context.fillRect(200, 350, 400,50);

除上述的特性的和方式,也有下列等方式:

drawImage(): 向画布上绘图图象、画布或视頻。

toDataURL() :储存图型

isPointInPath(): 假如特定的点坐落于当今相对路径中,则回到 true,不然回到 false。

这里就不逐一举例表明了。

以上便是本文的所有內容,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。