HTML5中canvas绘图基础详解

news2024/9/22 6:55:16

第7章 HTML5绘图基础

H5中新增了重要元素canvas,通过绘制任意图形,借助自带API,通过编写js可以控制各种图形,制作动画效果,对web具有划时代意义。

7.1 画布的基础知识

绘图三步骤:

步骤一:使用canvas创建一个画布区域,并获取该元素。

步骤二:获取canvas取得该元素的上下文环境。

步骤三:根据环境画出图形或动画。

7.1.1 canvas基本用法

添加一个标记ID,设置长宽即可。

1.功能描述

新建并绘制一个指定长度的正方形

2.代码实现
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>canvas简单示例</title>
        <script>
            function $$(id) {
                return document.getElementById(id);
            }
            function pageload(){
                var cnv = $$("cnvMain");
                var cxt = cnv.getContext("2d");
                cxt.fillStyle="red";
                cxt.fillRect(30,30,80,80);
            }
        </script>
    </head>
    <body onload="pageload();">
        <canvas id="cnvMain" width="280px" height="190px"></canvas>
    </body>
</html>
3.页面效果

4.源码分析

自定义的pageload()在页面加载时调用,取得上下文对象cxt,

调用画布的getContext方法,传递2d字符串,通过cxt来进行绘图,

本例绘制矩形和背景为红色。

7.1.2 绘制带边框的矩形

除了绘制背景色的图形外,还可以绘制有边框的图形,对应方法:

  • strokeRect(x,y,width,height):画笔触边框矩形,x,y为起点坐标,width和height为宽高
  • strokeStyle:设置笔触颜色,渐变,模式
  • clearRect(x,y,width,height):清空区域,x,y为图形内起点坐标,width和height为宽高
1.功能描述

新建canvas元素,在元素中绘制有背景色和边框的矩形,单击矩形时,清空矩形指定区域的图形色彩。

2.代码实现
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>canvas元素绘制带边框的矩形</title>
    <script>
        function pageload() {
            var cnv = document.getElementById("cnvMain");
            var cxt = cnv.getContext("2d");
            //设置边框
            cxt.strokeStyle = "red";
            cxt.strokeRect(30, 30, 150, 80);
            //设置背景
            cxt.fillStyle = "#eee";
            cxt.fillRect(30, 30, 150, 80);
        }
        function cnvClick() {
            var cnv = document.getElementById("cnvMain");
            var cxt = cnv.getContext("2d");
            //清空图形
            cxt.clearRect(36, 36, 138, 68);
        }
    </script>
</head>

<body onload="pageload();">
    <canvas id="cnvMain" width="280px" height="190px" onclick="cnvClick();"></canvas>
</body>

</html>
3.页面效果

4.源码分析

1.页面加载时定义函数pageload().

2.使用filleRect()方法绘制带背景色的图形。

3.使用strokeRect()方法绘制带边框的图形,边框颜色为红色。

4.点击事件cnvClick(),用clearRect()清空指定区域的色彩。

7.1.3 绘制渐变图形

canvas可以绘制渐变图形,1种是线性渐变,1种是径向渐变。

对应的方法:

  • createLinearGradient(xStart,yStart,xEnd,yEnd):参数为渐变开始和结束坐标轴,创建一个LinearGradient对象.
  • LinearGradient对象的addColorStop(value,color):渐变位置偏移量,0-1,调用两次。
1.功能描述
  1. 新建canvas元素
  2. 调用createLinearGradient(xStart,yStart,xEnd,yEnd),获取LinearGradient对象
  3. 调用addColorStop(value,color)
  4. 赋给fillStyle属性,最后用fillRect()绘制出一个又渐变色的矩形
2.代码实现
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>7.1.3 绘制渐变图形</title>
    <script>
        function pageload() {
            var cnv = document.getElementById("cnvMain");
            var cxt = cnv.getContext("2d");
            //绘制从左到右的颜色渐变图形
            var gnt1 = cxt.createLinearGradient(20, 20, 150, 20);
            gnt1.addColorStop(0, "red");
            gnt1.addColorStop(1, "green");
            cxt.fillStyle = gnt1;
            cxt.fillRect(20, 20, 150, 20);
            //绘制从上到下的颜色渐变图形
            var gnt2 = cxt.createLinearGradient(20, 60, 20, 150);
            gnt2.addColorStop(0, "red");
            gnt2.addColorStop(1, "green");
            cxt.fillStyle = gnt2;
            cxt.fillRect(20, 60, 20, 150);
            //绘制沿着对角线颜色渐变图形
            var gnt3 = cxt.createLinearGradient(60, 60, 100, 100);
            gnt3.addColorStop(0, "red");
            gnt3.addColorStop(1, "green");
            cxt.fillStyle = gnt3;
            cxt.fillRect(60, 60, 100, 100);
        }
    </script>
</head>

<body onload="pageload();">
    <canvas id="cnvMain" width="280px" height="190px"></canvas>
</body>

</html>
3.页面效果

4.源码分析

按功能来看,创建三个不同LinearGradient对象,自左向右,从上到下,沿对角线设置渐变。

7.2 在画布中使用路径

借助画布路径功能来绘制直线和圆,方法如下:

  • moveTo(x,y):绘制直线的开始点, xy是坐标
  • lineTo(x,y):绘制直线结束点,xy也是坐标
  • arc():绘制圆

7.2.1 moveTo与lineTo的用法

如果要绘制直线,通常使用moveTo(x,y)和lineTo(x,y)两个方法,moveTo用于将画笔移至指定点并以该点为直线的开始点,lineTo将用画笔从指定的起点坐标和传递的终点坐标参数之间绘制一条直线,该方法可以多次使用,最后用stroke方法来描边。

1.功能描述
  1. 新建canvas元素
  2. 调用moveTo(x,y)和lineTo(x,y)两个方法绘制两条直线,并显示在页面中。
2.实现代码
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>通过路径画直线</title>
    <script>
        function pageload() {
            var cnv = document.getElementById("cnvMain");
            var cxt = cnv.getContext("2d");
            cxt.moveTo(130, 30);
            cxt.lineTo(30, 100);
            cxt.lineTo(130, 160);
            cxt.lineWidth = 5;
            cxt.stroke();
        }
    </script>
</head>

<body onload="pageload();">
    <canvas id="cnvMain" width="280px" height="190px"></canvas>
</body>

</html>
3.页面效果

4.源码分析

7.2.2 使用arc方法绘制圆形

绘制各种圆形图案:

cxt.arc(x,y,radius,startAngle,endAngle,anticlockwise):x,y表示坐标,radius表示半径(像素),

startAngle,endAngle表示开始和结束角度,anticlockwise表示true表示顺时针。

cxt.beginPath()在arc之前调用,之后调用cxt.closePath(),他两成对出现。

1.功能描述

新建canvas元素,创建三个span内容分别设置为实体圆,边框圆,衔接圆,单击span绘制对应图案。

2.实现代码
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>通过路径画圆形</title>
    <script>
        function spn1() {
            var cnv = document.getElementById("cnvMain");
            var cxt = cnv.getContext("2d");
            //清除画布原有图形
            cxt.clearRect(0, 0, 280, 190);
            //开始画实心圆
            cxt.beginPath();
            cxt.arc(100, 100, 50, 0, Math.PI * 2, true);
            cxt.closePath();
            //设置填充色
            cxt.fillStyle = "red";
            cxt.fill();
        }
        function spn2() {
            var cnv = document.getElementById("cnvMain");
            var cxt = cnv.getContext("2d");
            //清除画布原有图形
            cxt.clearRect(0, 0, 280, 190);
            //开始画边框圆
            cxt.beginPath();
            cxt.arc(100, 100, 50, 0, Math.PI * 2, true);
            cxt.closePath();
            //设置边框色
            cxt.strokeStyle = "red";
            //边框宽度
            cxt.lineWidth = 2;
            cxt.stroke();
        }
        function spn3() {
            var cnv = document.getElementById("cnvMain");
            var cxt = cnv.getContext("2d");
            //清除画布原有图形
            cxt.clearRect(0, 0, 280, 190);
            //开始画圆
            cxt.beginPath();
            cxt.arc(100, 100, 50, 0, Math.PI * 2, true);
            cxt.closePath();
            //设置填充色
            cxt.fillStyle = "#eee";
            cxt.fill();
            cxt.strokeStyle = "#666";
            cxt.lineWidth = 2;
            cxt.stroke();
            //衔接边框圆
            cxt.beginPath();
            cxt.arc(175, 100, 50, 0, Math.PI * 2, true);
            cxt.closePath();
            //设置边框色
            cxt.strokeStyle = "red";
            //边框宽度
            cxt.lineWidth = 2;
            cxt.stroke();
        }
    </script>
</head>

<body>
    <div>
        <p>
            <span onclick="spn1();">实体圆</span>
            <span onclick="spn2();">边框圆</span>
            <span onclick="spn3();">衔接圆</span>
        </p>
    </div>
    <canvas id="cnvMain" width="280px" height="190px"></canvas>
</body>

</html>
3.页面效果

4.源码分析,略

7.2.3 绘制渐变图形

  • createRadialGradient(xStart,yStart,radiusStart,xEnd,yEnd,radiusEnd):xStart,yStart开始渐变坐标点,radiusStart开始渐变半径,xEnd,yEnd结束渐变圆心的坐标,radiusEnd结束渐变圆的半径。
1.功能描述

新建canvas严肃,调用createRadialGradient()创建渐变对象,该对象设置为fillStyle的值,在画布中绘制一个径向渐变的圆。

2.代码实现
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>绘制径向渐变的圆</title>
    <script>
        function pageload() {
            var cnv = document.getElementById("cnvMain");
            var cxt = cnv.getContext("2d");
            //开始创建渐变对象
            var gnt = cxt.createRadialGradient(30, 30, 0, 20, 20, 400);
            gnt.addColorStop(0, "#000");
            gnt.addColorStop(0.3, "#eee");
            gnt.addColorStop(1, "#fff");
            //开始绘制实体圆路径
            cxt.beginPath();
            cxt.arc(125, 95, 80, 0, Math.PI * 2, true);
            cxt.closePath();
            //填充背景色并填充
            cxt.fillStyle = gnt;
            cxt.fill();
            //开始绘制边框圆路径
            cxt.beginPath();
            cxt.arc(125, 95, 80, 0, Math.PI * 2, true);
            cxt.closePath();
            //设置边框颜色
            cxt.strokeStyle = "#666";
            //设置边框宽度
            cxt.lineWidth = 2;
            //开始描边
            cxt.stroke();
        }
    </script>
</head>

<body onload="pageload();">
    <canvas id="cnvMain" width="280px" height="190px"></canvas>
</body>

</html>
3.页面效果

4.源码解析,略。

7.3 对画布中图形的操作

有时需要对图形进行移动,缩放,旋转等操作,可以借助Canvas API来实现。

  • translate(x,y):移动
  • scale(x,y):缩放
  • rotate(angle):旋转

7.3.1 变换图形原点坐标

1.功能描述

新建canvas,画布绘制一个正方形,创建button,分别设置移动,缩放,旋转,对正方形进行相应的操作。

2.实现代码
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>移动、缩放、旋转绘制的图形</title>
    <style>
        button {
            border-radius: 5px;
            background-color: steelblue;
            color: white;
        }
    </style>
    <script>
        function drawRect() {
            var cnv = document.getElementById("cnvMain");
            var cxt = cnv.getContext("2d");
            cxt.strokeStyle = "red"
            cxt.lineWidth = 2;
            cxt.strokeRect(105, 70, 60, 60);
        }
        //上下移动已绘制的正方形
        function btn1() {
            var cxt = document.getElementById("cnvMain").getContext("2d");
            cxt.translate(-20, -20);
            drawRect();
            cxt.translate(40, -40);
            drawRect();
        }
        //缩放已绘制的正方形
        function btn2() {
            var cxt = document.getElementById("cnvMain").getContext("2d");
            cxt.scale(1.2, 1.2);
            drawRect();
            cxt.scale(1.2, 1.2);
            drawRect();
        }
        //旋转已绘制的正方形
        function btn3() {
            var cxt = document.getElementById("cnvMain").getContext("2d");
            cxt.rotate(Math.PI / 8);
            drawRect();
            cxt.rotate(Math.PI / 4);
            drawRect();
        }
    </script>
</head>

<body onload="drawRect();">
    <div>
        <button onclick="btn1();">移动</button>
        <button onclick="btn2();">缩放</button>
        <button onclick="btn3();">旋转</button>
    </div>
    <canvas id="cnvMain" width="280px" height="190px"></canvas>
</body>

</html>
3.页面效果

7.3.2 组合多个图形

绘制多个有交叉点的图形,新绘制的会覆盖原图形,想要改变默认多图组合的显示形式,可以修改:

globalCompositeOperation:source是新图形,destination是原图形

属性值有多个:

  • source-over:默认值,覆盖原图形
  • copy:只显示新图形,其他部分透明处理
  • darker:两种都显示,重叠部分颜色值相减后形成
  • destination-atop:只显示与原图形重叠部分和新图形剩余部分,其他透明处理
  • destination-in:只显示与原图形重叠部分,其他透明处理
  • destination-out:只显示与原图形不重叠部分,其他透明处理
  • destination-over:原图形覆盖新图形
  • lighter:都显示,重叠部分相加形成
  • source-atop:重叠部分+原图形其余部分,其他透明
  • source-in:重叠部分,其他透明
  • source-out:不重叠部分,其他透明
  • xor:都绘制,重叠部分透明
1.功能描述

新建canvas并定义pageload函数,创建一个正方形和圆形,两个图组合后的globalCompositeOperation设置为lighter后显示到画布中。

2.代码实现
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>设置多图形组合显示的方式</title>
    <script>

        //绘制正方形
        function drawRect(cxt) {
            cxt.fillStyle = "#666";
            cxt.fillRect(60, 50, 80, 80);
        }
        //绘制圆形
        function drawCirc(cxt) {
            cxt.beginPath();
            cxt.arc(130, 120, 50, 0, Math.PI * 2, true);
            cxt.closePath();
            cxt.fillStyle = "#ccc";
            cxt.fill();
        }

        function pageload() {
            var cxt = document.getElementById("cnvMain").getContext("2d");
            drawRect(cxt);
            cxt.globalCompositeOperation = "lighter";
            drawCirc(cxt);
        }
    </script>
</head>

<body>

    <body onload="pageload();">
        <canvas id="cnvMain" width="280px" height="190px"></canvas>
    </body>
</body>

</html>
3.页面效果

7.3.3 添加图形阴影

绘制图形时,可以给背景添加阴影,达到立体效果,属性如下:

  • shadowOffsetX:阴影与图形的水平距离,作为负,右为正
  • shadowOffsetY:阴影与图形的垂直距离,上为负,下为正
  • shadowColor:阴影颜色值
  • shadowBlur:阴影模糊值,值越大,越模糊,通常1-10之间
1.功能描述

画两个完全相同的长方形,分别添加不同方向的阴影,同时显示在画布中。

2.代码实现
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>添加绘制图形阴影的效果</title>
    <script>
        function pageload() {
            var cxt = document.getElementById("cnvMain").getContext("2d");
            //设置左上方向的阴影
            cxt.shadowOffsetX = -6;
            cxt.shadowOffsetY = -6;
            cxt.shadowColor = "#ccc";
            cxt.shadowBlur = 1;
            cxt.fillStyle = "#eee";
            cxt.fillRect(20, 28, 100, 130);
            //设置右下方向的阴影
            cxt.shadowOffsetX = 6;
            cxt.shadowOffsetY = 6;
            cxt.shadowColor = "#ccc";
            cxt.shadowBlur = 1;
            cxt.fillStyle = "#eee";
            cxt.fillRect(150, 28, 100, 130);
        }
    </script>
</head>

<body onload="pageload();">
    <canvas id="cnvMain" width="280px" height="190px"></canvas>
</body>

</html>
3.页面效果

7.4 处理画布中的图像

不仅可以绘制各种图形,也可以通过Canvas API将磁盘或者网络上的图片导入的画布中,并且对导入的图片进行平铺,切割,像素处理等多项操作。

7.4.1 绘制图像

  • drawImage(image,dx,dy):image页面图片(可以是和js的Image对象),dx是在画布中的横坐标,dy是纵坐标。
  • drawImage(image,dx,dy,dw,dh):dw表示源图像缩放至画布中的宽度,dh表示缩放至画布上的高度。
  • drawImage(image,sx,sy,sh,dx,dy,dw,dh):sx,sy,sw,sh表示源图像需要裁剪的范围,sx,sy表示需要裁剪的坐标,sw,sh表示裁剪的长宽。
1.功能描述

新建canvas元素,连续点击分别使用上述三种绘制图像的方法,先绘制指定位置的图像,然后是指定位置和大小的图像,最后以映射的方式将源图像中的部分图像以放大方式绘制在画布中。

2.代码实现
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>使用drawImage方法在画布中绘制图像</title>
    <script>
        var intNum = 0;
        function cnvClick(cnv) {
            intNum++;
            intNum = (intNum == 4) ? 1 : intNum;
            var cxt = cnv.getContext("2d");
            cxt.clearRect(0, 0, cnv.width, cnv.height);
            var objImg = new Image();
            objImg.src = "img/moon.jpg";//图片大小164*99px
            objImg.onload = function () {
                switch (intNum) {
                    case 1: cxt.drawImage(objImg, 10, 10); break;
                    case 2: cxt.drawImage(objImg, 10, 10, 94, 123); break;
                    case 3: cxt.drawImage(objImg, 10, 10, 94, 123); cxt.drawImage(objImg, 45, 50, 100, 150, 110, 10, 160, 180); break;
                }
            }
        }
    </script>
</head>

<body>
    <canvas style="border: 1px dotted;" id="cnvMain" width="280px" height="190px" onclick="cnvClick(this);"></canvas>
</body>

</html>
3.页面效果

7.4.2 平铺图像

createPattern()方法关联图像,将平铺对象给fillStyle,然后填充fillRect()方法:

cxt.createPattern(image,type):type有4中,no-repeat(不平铺),repeat-x(水平方向),repeat-y(垂直方向),repeat(全方位平铺)

1.功能描述

新建canvas元素,由于图片宽度164px,高度99px,设置画布宽度330px,高度400px.

每次点击画布,调用不同的平铺方式,显示图像到画布中。

2.代码实现
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>使用createPattern方法在画布中平铺图像</title>
    <script>
        var intNum = 0;
        function cnvClick(cnv) {
            intNum++;
            intNum = (intNum == 5) ? 1 : intNum;
            var strPrnType = "";
            switch (intNum) {
                case 1: strPrnType = "no-repeat"; break;
                case 2: strPrnType = "repeat-x"; break;
                case 3: strPrnType = "repeat-y"; break;
                case 4: strPrnType = "repeat"; break;
            }
            var cxt = cnv.getContext("2d");
            cxt.clearRect(0, 0, cnv.width, cnv.height);
            var objImg = new Image();
            objImg.src = "img/moon.jpg";//图片大小164*99px
            var prn = cxt.createPattern(objImg, strPrnType);
            objImg.onload = function () {
                cxt.fillStyle = prn;
                cxt.fillRect(0, 0, cnv.width, cnv.height);
            }
        }
    </script>
</head>

<body>
    <canvas style="border: 1px dotted;" id="cnvMain" width="330px" height="400px" onclick="cnvClick(this);"></canvas>
</body>

</html>
3.页面效果

7.4.3 切割图像

用clip()方法切割画布中绘制的图像,该方法是无参方法,调用方法前先使用路径方式在画布中绘制区域,才能通过clip来对该区域进行切割。

1.功能描述

新建canvas,调用clip()方法,将画布绘制的图像切割成一个光盘形状。

2.代码实现
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>使用clip方法在画布中切割图像</title>
    <script>
        function pageload() {
            var cxt = document.getElementById("cnvMain").getContext("2d");
            var objImg = new Image();
            objImg.src = "img/moon.jpg";
            objImg.onload = function () {
                drawCirc(cxt, 60, true);
                cxt.drawImage(objImg, 70, 50);
                drawCirc(cxt, 10, false);
            }
        }
        //根据参数绘制圆
        function drawCirc(cxt, intR, blnC) {
            cxt.beginPath();
            cxt.arc(140, 95, intR, 0, Math.PI * 2, true)
            cxt.closePath();
            //设置边框颜色
            cxt.strokeStyle = "red";
            cxt.lineWidth = 3;
            cxt.stroke();
            if (blnC) {
                cxt.clip();
            } else {
                cxt.fillStyle = "#fff";
                cxt.fill();
            }
        }
    </script>
</head>

<body onload="pageload();">
    <canvas style="border: 1px dotted;" id="cnvMain" width="280px" height="190px"></canvas>
</body>

</html>
3.页面效果

7.4.4 处理像素

处理画布图像的像素,例如做成蒙版效果,黑白色效果等。

两个方法:

cxt.getImageData(sx,sy,sw,sh):sx,sy是所需图像区域的坐标,sw,sh是所选区域的宽高,获取的区域可以用objImgData变量保存,该变量是CanvasPixelArray对象,objImgData.data是一个保存像素的数组,[r1,g1,b1,a1,r2,g2,b2,a2...],objImgData.data.length获取像素总量,可以遍历时使用该值。

cxt.putImageData(image,dx,dy):image表示重新绘制的图像,dx,dy表示绘制在画布上的坐标。

1.功能描述

新建canvas,第一次单击绘制一幅图像,再次单击处理该图像的像素,以反色彩的形式在画布中重新绘制。

2.实现代码
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>使用getImageData和putImageData方法处理图像像素</title>
    <script>
        var intNum = 0;
        function cnvclick(cnv) {
            intNum++;
            intNum = (intNum == 3) ? 1 : intNum;
            var cxt = cnv.getContext("2d");
            var objImg = new Image();
            objImg.src = "img/moon.jpg";
            //使图片居中的坐标
            var intX = cnv.width / 2 - objImg.width / 2;
            var intY = cnv.height / 2 - objImg.height / 2;
            objImg.onload = function () {
                switch (intNum) {
                    case 1: cxt.drawImage(objImg, intX, intY); break;
                    case 2: dealPixel(cxt, objImg, intX, intY); break;
                }
            }
        }
        function dealPixel(cxt, objImg, intX, intY) {
            var imgData = cxt.getImageData(intX, intY, objImg.width, objImg.height);
            //遍历像素数组,进行颜色取反
            for (var i = 0; i < imgData.data.length; i += 4) {
                imgData.data[i] = 255 - imgData.data[i];
                imgData.data[i + 1] = 255 - imgData.data[i + 1];
                imgData.data[i + 2] = 255 - imgData.data[i + 2];
            }
            cxt.putImageData(imgData, intX, intY);
        }
    </script>
</head>

<body>
    <canvas style="border: 1px dotted;" onclick="cnvclick(this);" id="cnvMain" width="280px" height="190px"></canvas>
</body>

</html>
3.页面效果

7.5 画布的其他应用

H5中通过canvas不仅可以绘制图形,图像,还可以调用相关方法绘制文字,同时将绘制的图形保存,还原,以base64位的URL形式在浏览器中输出,以及在画布上制作简单的动画。

7.5.1 绘制文字

fillText()方法以填充的方式绘制文字:

  • cxt.fillText(content,dx,dy,[maxLength]):content是文字内容,dx,dy是左上角坐标,maxLength是文字显示的最大长度,设置后在长度范围内绘制文字。
  • cxt.strokeText(content,dx,dy,[maxWidth]):与以上参数一致。

绘制文字的相关属性:

  • font: CSS样式字体的任何值,样式,名称,大小,粗细,行距等
  • textAlign:文本对齐方式,start,end,left,right,center
  • textBaseline:文本相对于起点的位置,top,bottom,middle
1.功能描述

新建canvas元素,页面加载时,设置三种不同字体的文字,分别绘制在画布元素中的不同坐标位置。

2.代码实现

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>使用fillText与strokeText绘制文字</title> <script> function pageload() { var cxt = document.getElementById("cnvMain").getContext("2d"); drawText(cxt, "bold 35px impact", 90, 70, false); drawText(cxt, "bold 35px monospace‌‌", 130, 110, true); drawText(cxt, "bold 35px cursive", 170, 150, true); } //根据参数绘制不同类型的字体 function drawText(cxt, strFont, intX, intY, blnFill) { cxt.font = strFont; cxt.textAlign = "center"; cxt.textBaseline = "bottom"; if (blnFill) { cxt.fillStyle = "#ccc"; cxt.fillText("HTML5实战", intX, intY); } else { cxt.strokeStyle = "#666"; cxt.strokeText("HTML实战", intX, intY); } } </script> </head> <body οnlοad="pageload();"> <canvas style="border: 1px dotted;" id="cnvMain" width="280px" height="190px"></canvas> </body> </html>

3.页面效果

7.5.2 保存、恢复以及输出图形

有时需要绘制多个图形,并在图形之间进行切换,如果不进行保存,切换后,原先绘制的图形将丢失,为解决这一问题,可以调用save()方法保存,用restore()方法进行还原,或者toDataURL(ImgType)方法保存图形输出至浏览器,ImgType表示MIME类型,例如"image/png"。

对内存栈的操作。

1.功能描述

新建1个canvas元素,和三个button元素,分别为保存,恢复,输出。

第一次单击画布,绘制指定填充色的大小图形,点击保存按钮,保存第一次绘制的图形,

第二次单击画布,绘制与第一次填充色不同的图形,点击恢复标记,用于最后一次绘制图形时使用,

第三次单击画布,由于还原了第一次的填充色,因此在最后一次绘制图形时,将第一次填充色填充到最后一次绘制的图形,单击输出是,以图形的base64输出至浏览器。

2.代码实现
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>使用fillText与strokeText绘制文字</title>
    <script>
        function pageload() {
            var cxt = document.getElementById("cnvMain").getContext("2d");
            drawText(cxt, "bold 35px impact", 90, 70, false);
            drawText(cxt, "bold 35px monospace‌‌", 130, 110, true);
            drawText(cxt, "bold 35px cursive", 170, 150, true);
        }
        //根据参数绘制不同类型的字体
        function drawText(cxt, strFont, intX, intY, blnFill) {
            cxt.font = strFont;
            cxt.textAlign = "center";
            cxt.textBaseline = "bottom";
            if (blnFill) {
                cxt.fillStyle = "#ccc";
                cxt.fillText("HTML5实战", intX, intY);
            } else {
                cxt.strokeStyle = "#666";
                cxt.strokeText("HTML实战", intX, intY);
            }
        }
    </script>
</head>

<body onload="pageload();">
    <canvas style="border: 1px dotted;" id="cnvMain" width="280px" height="190px"></canvas>
</body>

</html>
3.页面效果

7.5.3 制作简单的动画

制作动画分两步:

第一步:自定义一个函数,用于图形的移动或其他动作。

第二部:使用setInterval()方法设置动画执行的间隔时间,反复执行自定义函数。

1.功能描述

新建canvas元素,绘制一个卡通笑脸,加载页面时,该笑脸从左往右移动,到右边时改为从右往左移动到起始为止。

2.实现代码
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>在画布中制作简单的动画</title>
    <script>
        var intI, intJ, intX;
        function pageload() {
            var cxt = document.getElementById("cnvMain").getContext("2d");
            drawFace(cxt);
            intI = 1;
            intJ = 11;
            setInterval(moveFace, 200);
        }

        //画笑脸
        function drawFace(cxt) {
            drawCirc(cxt, "#666", 30, 80, 30, 2, true);
            drawCirc(cxt, "#fff", 20, 70, 5, 2, true);
            drawCirc(cxt, "#fff", 40, 70, 5, 2, true);
            drawCirc(cxt, "#fff", 30, 80, 18, 1, false);
        }
        //根据参数画圆
        function drawCirc(cxt, strColor, intX, intY, intR, intH, blnFill) {
            cxt.beginPath();
            cxt.arc(intX, intY, intR, 0, Math.PI * intH, blnFill);
            if (blnFill) {
                cxt.fillStyle = strColor;
                cxt.fill();
            } else {
                cxt.lineWidth = 2;
                cxt.strokeStyle = strColor;
                cxt.stroke();
            }
            cxt.closePath();
        }
        //笑脸移动功能
        function moveFace() {
            var cxt = document.getElementById("cnvMain").getContext("2d");
            cxt.clearRect(0, 0, 280, 190);
            if (intI < 10) {
                intI += 1;
                intX = intI;
            } else {
                if (j > 0) {
                    intJ -= 1;
                    intX = -intJ;
                }
            }
            cxt.translate(intX, 0);
            drawFace(cxt);
        }
    </script>
</head>

<body>

    <body onload="pageload();">
        <canvas style="border: 1px dotted;" id="cnvMain" width="280px" height="190px"></canvas>
    </body>
</body>

</html>
3.页面效果

笑脸没回来,需要微调。。。

页面完整效果看:【有道云笔记】《HTML5实战》
https://note.youdao.com/s/3ubs1KG8 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2115483.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FreeRTOS学习笔记(五)任务进阶篇

文章目录 前言一、列表和列表项1.1 xList 和 xLIST_ITEM1.2 相关API函数1.3 任务就绪列表 二、任务调度器的启动过程2.1 PendSV 和 SysTick 寄存器2.2 prvStartFirstTask( )2.3 xPortStartScheduler( )2.4 vTaskStartScheduler( ) 的整体流程 三、任务切换3.1基于 SysTick 中断…

一名优秀的工程师应该学会在工作中提升自己,面试篇

xxx 进行 xxx 操作&#xff0c;为什么不行&#xff1f;有人知道吗&#xff1f; 此时&#xff0c;[黑人脸问好号.jpg]。 这里大家可以阅读下《提问的艺术》这本书&#xff0c;这是一本教你如何通过富有技巧性的提问来提高沟通效率并提升自身影响力的书。 Github 上一些开源项目…

zabbix6.4连接钉钉发出警告

zabbix6.4配置钉钉告警 注册钉钉 建一个内部群 添加自定义机器人 配置zabbix服务端 打开脚本告警的配置 # vim /etc/zabbix/zabbix_server.conf AlertScriptsPath/usr/lib/zabbix/alertscripts 准备脚本 安装一个依赖包 # dnf -y install python3-requests # vim /usr/li…

希尔排序/选择排序

前言&#xff1a; 本篇主要对常见的排序算法进行简要分析&#xff0c;代码中均以数组 arr[] { 5, 3, 9, 6, 2, 4, 7, 1, 8 } 为例&#xff0c;进行升序排列。 常见的排序算法有如下&#xff1a; 选择排序中&#xff0c;直接选择排序没有任何实际与教育意义&#xff0c;而堆排…

PopupInner源码分析 -- ant-design-vue系列

PopupInner源码分析 – ant-design-vue系列 1 综述 上一篇讲解了vc-align的工作原理&#xff0c;也就是对齐是如何完成的。这一篇主要讲述包裹 Align的组件&#xff1a;PopupInner组件是如何工作的。 PopupInner主要是对动画状态的管理&#xff0c;比如打开弹窗的时候&#…

【Hot100】LeetCode—763. 划分字母区间

目录 1- 思路哈希表 双指针 2- 实现⭐763. 划分字母区间——题解思路 3- ACM 实现 原题链接&#xff1a;763. 划分字母区间 1- 思路 哈希表 双指针 ① 找到元素最远的出现位置&#xff1a;哈希表② 根据最远出现位置&#xff0c;判断区间的分界线&#xff1a;双指针 实现 …

Java类和对象(详解)

前言&#xff1a; Java中类和对象是比较重要的一章&#xff0c;这一章可以让我们深刻认识到Java语言的"精妙之处"&#xff0c;它不像C语言那么"细"&#xff0c;也不想其他语言封装的那么"保守"。 游刃有余的解决一系列面向对象问题。 面向对象的…

数据集 视线估计-unityeyes-合成数据 >> DataBall

视线估计-合成数据-三维建模-人工智能unityeyes 人眼视线估计仿真合成数据集 inproceedings{wood2016_etra, title {Learning an Appearance-Based Gaze Estimator from One Million Synthesised Images}, author {Wood, Erroll and Baltru{\v{s}}aitis, Tadas and Morency,…

如何使div居中?CSS居中终极指南

前言 长期以来&#xff0c;如何在父元素中居中对齐一个元素&#xff0c;一直是一个让人头疼的问题&#xff0c;随着 CSS 的发展&#xff0c;越来越多的工具可以用来解决这个难题&#xff0c;五花八门的招式一大堆&#xff0c;这篇博客&#xff0c;旨在帮助你理解不同的居中方法…

【电子通识】半导体工艺——保护晶圆表面的氧化工艺

在文章【电子通识】半导体工艺——晶圆制造中我们讲到晶圆的一些基础术语和晶圆制造主要步骤&#xff1a;制造锭(Ingot)、锭切割(Wafer Slicing)、晶圆表面抛光(Lapping&Polishing)。 那么其实当晶圆暴露在大气中或化学物质中的氧气时就会形成氧化膜。这与铁(Fe)暴露在大气…

MySQL record 02 part

查看已建数据库的基本信息&#xff1a; show CREATE DATABASE mydb; 注意&#xff0c;是DATABASE 不是 DATABASEs&#xff0c; 命令成功执行后&#xff0c;回显的信息有&#xff1a; CREATE DATABASE mydb /*!40100 DEFAULT CHARACTER SET utf8mb3 / /!80016 DEFAULT ENCRYPTIO…

基于Python+大数据爬虫+数据可视化大屏的耳机信息的爬取与分析平台设计和实现(2025最新优质项目-系统+源码+部署文档)

博主介绍&#xff1a;✌全网粉丝50W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HLM…

新手入门Python:Python类中自带的装饰器详解与应用

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 什么是装饰器?📝 常用装饰器详解📝 高级装饰器📝 综合应用示例⚓️ 相关链接 ⚓️📖 介绍 📖 在Python编程中,有一类特别的工具,它们可以改变或增强函数和方法的行为。这些工具被称为装饰器。对…

使用宝塔面板安装mrdoc

使用宝塔面板安装mrdoc 1、所需环境2、ubuntu系统安装3、宝塔面板安装4、NginxPHPMySQL安装5、python项目管理器安装6、 python版本安装7、mrdoc的部署7.1、下载项目源码7.2、新建python管理器项目 8、使用MySQL作为默认数据库8.1、安装mysqlclient插件8.2、配置数据库连接信息…

qt多线程的两种方法run和movetothread

qt多线程的有什么用&#xff1f; 将耗时长的操作丢入专属线程执行&#xff0c;这样就不会影响主线程的界面操作&#xff0c;操作完再用信号槽等的方式返回结果 1.界面和部件相关都必须在主界面运行&#xff0c;不要用子线程调用或者操作&#xff0c;会引起奇怪的bug&#xff…

推荐一款免费使用的电脑笔记软件,工作必备

今天为大家介绍一款开源的笔记软件——Beaver Notes&#xff08;海狸笔记&#xff09;。 海狸笔记&#xff08;Beaver Notes&#xff09;是一款注重隐私保护的免费、开源且无广告的笔记工具。它拥有一个干净且吸引人的用户界面&#xff0c;操作直观便捷&#xff0c;并且兼容 W…

验证码的作用,为什么要存在验证码?

背景 在现代网络应用中&#xff0c;验证码被广泛使用以实现人机识别和减轻服务器负担。常见的验证码为以下几类&#xff1a; 图形验证码&#xff1a;通过展示一个随机生成的图形&#xff0c;要求用户输入对应的文字或数字来判断用户是否为真实用户。滑块验证码&#xff1a;用…

基于VS2022+Qt5+C++的网络调试助手开发

目录 一、前言 二、环境准备以及项目创建 三、 项目实现 1.ui界面设计 2.添加NetWork模块 QTcpSocket 和 QTcpServer QUdpSocket 3.主要功能实现 ①IP扫描 ②端口设置 ③数据接收 ④数据发送 ⑤日志保存 4.打包成exe 四、效果展示 五、总结 一、前言 我之前用…

Mysql高级篇(中)——索引介绍

Mysql高级篇&#xff08;中&#xff09;——索引介绍 一、索引本质二、索引优缺点三、索引分类&#xff08;1&#xff09;按数据结构分类&#xff08;2&#xff09;按功能分类&#xff08;3&#xff09; 按存储引擎分类&#xff08;4&#xff09; 按存储方式分类&#xff08;5&…

通信工程学习:什么是DB数据库、DBS数据库系统、DBMS数据库管理系统

DB数据库、DBS数据库系统、DBMS数据库管理系统 在计算机科学中&#xff0c;数据库&#xff08;DB&#xff09;、数据库系统&#xff08;DBS&#xff09;和数据库管理系统&#xff08;DBMS&#xff09;是构建和管理数据存储与检索系统的核心概念。下面将分别详细解释这三个术语。…