html5-canvas

canvas

是一个标签,简单理解为一个有特殊功能的盒子标签,最好在标签上写上宽高属性和背景色,否则在页面上看不到效果。canvas 是一个二维网格,canvas 默认左上角坐标为 (0,0),可以通过translate(x,y)来更改原点坐标。
:在低版本浏览器中不兼容,需要提示用户

绘制形式有三种:描边填充描边+填充
canvas绘制
beginPath(): 清除当前所有子路径,以此来重置当前路径,重新规划一条路径。
closePath(): 用于封闭某段开放路径。不是必需的,如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。

画线
moveTo(x,y) 定义线条开始坐标
lineTo(x,y) 定义线条结束坐标

线段也是基于路径绘制的,称为线性路径,创建线性路径的方法:moveTO()与lineTo(),在创建路径之后调用stroke()方法,才能在Canvas中画出线段出来。
moveTo(x,y): 将笔触移动到指定的坐标x以及y上,向当前路径中增加一条子路径,该方法不会清除当前路径中的任何子路径。
lineTo(x,y): 绘制一条从当前位置到指定x以及y位置的直线,如果当前路径中没有子路径,那么这个方法的行为与moveTo()一样。如果当前路径中存在子路径,此方法会将你所指定的这个点加入子路径中。

画圆
arc(x,y,r,start,stop)
文本
font - 定义字体
fillText(text,x,y) - 在 canvas 上绘制实心的文本
strokeText(text,x,y) - 在 canvas 上绘制空心的文本
渐变
createLinearGradient(x,y,x1,y1) - 创建线条渐变
createRadialGradient(x,y,r,x1,y1,r1) - 创建一个径向/圆渐变
画图片
drawImage(image,x,y)
线宽
lineWidth => 数值
图形落地
stroke() => 将设计好的图形绘制出来
strokeStyle => css常用色值均可使用,图形颜色
绘制矩形
fillRect(x,y,width,height)
fillStyle => css常用色值均可使用,图形填充颜色
清除画布
clearRect(x,y,width,height)

绘图模糊的问题

单设canvas画布css样式的宽高会导致绘制模糊:

  • 可以通过同时设置标签上的width和height属性来改善
  • 可以将canvas宽高设为2倍后再缩小一倍
  • 套一个父级div,只设定父级盒子宽高cavas标签自动继承宽高(无法自适应各类手机屏,不推荐)
  • 只设定canvas标签上的width和height的属性(无法自适应各类手机屏,不推荐)

创建&线性&基础知识

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>创建一个canvas</title>
  <style>
    canvas{
      
      
      background: #000;
      margin: 0 auto;
      display: block;
    }
  </style>
</head>
<body>
  <canvas id="myCanvas" width="500px" height="500px">您的浏览器版本过低,请先升级浏览器!</canvas>

  <script type="text/javascript">
    // 获取canvas标签
    var _canvas = document.getElementById("myCanvas");
    // 获取上下文对象创建2d画布
    var ctx = _canvas.getContext("2d");
    // 固定两步可以简写为
    // let ctx = document.getElementById("myCanvas").getContext("2d");

     //设置绘图原点,相对于上一个原点,默认(0,0)
    ctx.translate(250,20);

    (function drawLine(){
      
      
      // 画一条直线
      // 开启一条路径
      ctx.beginPath();
      // 从哪里开始移动
      ctx.moveTo(100,100);
      // 移动到哪里去
      ctx.lineTo(200,200);
      // 线的颜色(不写默认黑色,后设覆盖先设)
      ctx.strokeStyle = "yellow";
      // lineTo可以写多个,首位相连
      ctx.lineTo(200,260);
      ctx.lineTo(100,260);
      // 设置线宽,不能带单位
      ctx.lineWidth = 14;
      // 画线
      ctx.stroke();
      // 结束路径
      ctx.closePath();
    })()
  
    // 通过画线的方式画一个边线方块
    function drawSquare(){
      
      
      // 重置原点
      ctx.translate(-250,20);
      ctx.lineWidth = 2;
      // 几何图形[一条线一个颜色]
      ctx.beginPath();
      ctx.moveTo(100,100);
      ctx.lineTo(100,200);
      ctx.strokeStyle = "blue";
      ctx.stroke();
      ctx.closePath();

      ctx.beginPath();
      ctx.moveTo(100,200);
      ctx.lineTo(200,200);
      ctx.strokeStyle = "yellow";
      ctx.stroke();
      ctx.closePath();

      ctx.beginPath();
      ctx.moveTo(200,200);
      ctx.lineTo(200,100);
      ctx.strokeStyle = "pink";
      ctx.stroke();
      ctx.closePath();

      ctx.beginPath();
      ctx.moveTo(200,100);
      ctx.lineTo(100,100);
      ctx.strokeStyle = "red";
      ctx.stroke();
      ctx.closePath();
    }
    drawSquare()


    // 画三角形
    function drawTriangle(){
      
      
      // 绿色填充三角形
      ctx.translate(150, 0);
      ctx.fillStyle = 'green';
      ctx.strokeStyle = "red";
      ctx.lineWidth = 1;
      ctx.beginPath();
      ctx.moveTo(50, 50);
      ctx.lineTo(50, 150);
      ctx.lineTo(150, 150);
      ctx.fill();
      // 要先关闭路径再画线  => 具体不同可以自行更换代码位置查看
      ctx.closePath();
      ctx.stroke();
      
      // 红色填充三角形
      ctx.translate(150, 0);
      ctx.fillStyle = 'green';
      ctx.strokeStyle = "#fff";
      ctx.lineWidth = 2;
      ctx.beginPath();
      ctx.moveTo(50, 50);
      ctx.lineTo(50, 150);
      ctx.lineTo(150, 150);
      ctx.closePath();
      // 先填充颜色再画边线 不然边线会被遮挡一半
      // 引申:类似table的值,1=2,要实现真正的1单位宽度就需要设置0.5
      ctx.fill();
      ctx.stroke();
    }
    drawTriangle()

	// 验证上方引申
    function drawLineWidth(){
      
      
      ctx.translate(-250,230);
      ctx.strokeStyle = "#fff";
      ctx.lineWidth = 2;
      ctx.beginPath();
      ctx.moveTo(50, 50);
      ctx.lineTo(250, 50);
      ctx.stroke();
      ctx.beginPath();
      ctx.moveTo(50.5, 150.5);
      ctx.lineTo(250.5, 150.5);
      ctx.stroke();
      ctx.beginPath();
      ctx.moveTo(50, 200);
      ctx.lineTo(252, 200);
      ctx.stroke();
      ctx.closePath();
    }
    drawLineWidth()

    // 不存在层级概念(z-index),后画的会覆盖在之前的上面
	// 渐变色
    function drawLineColor(){
      
      
      ctx.lineWidth = 4;
      var gradient = ctx.createLinearGradient(0, 0, 250, 250);
      gradient.addColorStop(0, 'blue');
      gradient.addColorStop(0.5, 'purple');
      gradient.addColorStop(1, 'yellow');
      ctx.strokeStyle = gradient;
      ctx.beginPath();
      ctx.lineTo(50, 50);
      ctx.lineTo(200, 200);
      ctx.stroke();
    }
    drawLineColor()
  </script>
</body>
</html>

填充矩形&清除画布&随机柱状图

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>随机统计图</title>
  <style>
    canvas{
      
      
      background: #000;
      margin: 0 auto;
      display: block;
    }
  </style>
</head>
<body>
  <canvas id="myCanvas" width="500px" height="500px">您的浏览器版本过低,请先升级浏览器!</canvas>

  <script type="text/javascript">
    // 固定两步
    let ctx = document.getElementById("myCanvas").getContext("2d");
    
    ctx.beginPath();
    // fillRect(x,y,width,height) 画一个规则矩形,前两个起始位置的坐标,后两个值是长和宽
    // fillStyle用来设置填充色,默认是黑色
    ctx.fillStyle='pink'
    ctx.fillRect(100,20,60,20)

    // 渐变色矩形
    // 创建线性渐变
    let grd=ctx.createLinearGradient(0,100,100,100);
    grd.addColorStop(0,"red");
    grd.addColorStop(1,"white");
    ctx.fillStyle=grd;
    ctx.fillRect(10,10,150,80);
    //创建径向渐变
    var rad=ctx.createRadialGradient(90,90,10,100,90,100);
    rad.addColorStop(0,"red");
    rad.addColorStop(1,"white");
    ctx.fillStyle=rad;
    ctx.fillRect(30,30,150,150);

    // 画一个‘回’字
    ctx.fillStyle='yellow'
    ctx.fillRect(10,10,60,60)
    // ctx.fillStyle='pink'
    // 用清除的方式
    ctx.clearRect(15,15,50,50)
    ctx.fillStyle='yellow'
    ctx.fillRect(20,20,40,40)
    // 用同色矩形覆盖
    ctx.fillStyle='#000'
    ctx.fillRect(25,25,30,30)
    ctx.closePath();

    // 随机颜色柱状图
    (function drawChart(){
      
      
      ctx.beginPath();
      ctx.moveTo(100,100);
      ctx.lineTo(100,400);
      ctx.lineTo(400,400);
      ctx.strokeStyle='red';
      ctx.stroke();
      ctx.closePath();
      for (let i=0;i<7;i++) {
      
      
        // 随机高度
        let height = Math.random()*280+10;
        // 随机颜色
        ctx.fillStyle="#"+parseInt(Math.random()*0Xffffff).toString(16);
        //画柱子
        ctx.fillRect(120+40*i,400-height,20,height)
      }
    })()
  </script>
</body>
</html>

运用canvas画个调皮笑脸

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>画圆脸</title>
  <style>
    canvas{
      
      
      margin: 0 auto;
      display: block;
      border: 2px solid #ccc;
    }
  </style>
</head>
<body>
  <canvas id="myCanvas" width="500px" height="500px">您的浏览器版本过低,请先升级浏览器!</canvas>

  <script type="text/javascript">
    // 固定两步
    let ctx = document.getElementById("myCanvas").getContext("2d");
    // 圆脸(圆圈)  false顺时针
    ctx.beginPath();
    ctx.arc(250,250,100,0,Math.PI*2,false)
    ctx.lineWidth = 10
    ctx.strokeStyle='red'
    ctx.stroke();
    ctx.closePath();
    
    // 左眼(圆形)  true逆时针
    ctx.beginPath();
    ctx.arc(220,210,15,0,Math.PI*2,true)
    ctx.fillStyle='red'
    ctx.fill();
    ctx.closePath();

    // 右眼(线形)
    ctx.beginPath();
    ctx.lineWidth = 8;
    ctx.moveTo(300,199);
    ctx.lineTo(280,210);
    ctx.lineTo(300,220);
    ctx.stroke();
    ctx.closePath();

    // 嘴(圆弧)
    ctx.beginPath();
    ctx.lineWidth = 8;
    ctx.arc(250,260,50,0,Math.PI,false)
    ctx.stroke();
    ctx.closePath();
  </script>
</body>
</html>

画爱心动效(类进度条)

<!DOCTYPE html>  
<html>
<head>
<title>Draw Heart</title>  
<style type="text/css">  
* {
      
      
  margin: 0;
  padding: 0;
}
html {
      
      
  height: 100%;
  margin: 0;
}
body {
      
      
  height: 100%;
}
.wrap{
      
      
  width: 100vw;
  height: 874px;
  background: skyblue;
  position: fixed;
  bottom: 0;
  left: 0;
}
#myCanvas {
      
      
  width: 100%;
  height: 500px;
  display: block;
  position: absolute;
  z-index: 99;
}
img{
      
      
  z-index: 999;
}
#bgCanvas {
      
      
  width: 100%;
  height: 500px;
  display: block;
}
.bottom{
      
      
  width: 100vw;
  height: 180px;
  background: red;
}
.usr-info{
      
      
  width: 100vw;
  height: 190px;
  background: yellow;
}
.btn{
      
      
  width: 86px;
  height: 86px;
  border-radius: 50%;
  background-color: blue;
  position: absolute;
  top: -136px;
  right: 20px;
  z-index: 9;
}
</style> 
</head>    

<body>
  <div class="wrap">
    <div class="btn"></div>
    <div class="usr-info">

    </div>
    <canvas id="myCanvas"></canvas>
    <canvas id="bgCanvas"></canvas>
    <div class="bottom">

    </div>
  </div>
    <script type="text/javascript">
      var r = 5;
      var radian;//弧度
      var i;
      var radianDecrement;//弧度增量
      var intervalId;
      var num = 360;//分割为 360 个点
      var ctx;
      let timer = null;
      let newX = 0
      let newY = 0
      window.onload = function () {
      
      
        ctx = document.getElementById("myCanvas").getContext("2d");//找到元素并获取2d画图权限
        drawHeart();
        intervalId = setInterval(()=>printHeart(), 10);
        drawBg()
      }
      function drawBg(){
      
      
        content = document.getElementById("bgCanvas").getContext("2d");//找到元素并获取2d画图权限
        content.beginPath();  //开始绘图
        // content.translate(250,250);  //设置绘图原点
        radian = 0;//弧度设为初始弧度
        content.moveTo(getX(radian),getY(radian)); //移动绘图游标至原点
        while(radian <= (Math.PI*2)){
      
        //每增加一次弧度,绘制一条线
          radian += Math.PI/180;
          X = getX(radian);
          Y = getY(radian);
          content.lineTo(X,Y);
        }
          //设置描边样式
        content.stroke();  //对路径描边
        content.textBaseline="middle"; // 控制文字在坐标点的垂直方向位置
        content.textAlign='center'; // 控制文字在坐标点的水平方向位置
        content.font="bold 12px Alin"; // 只有设置了字体风格再设置大小(注意参数位置)
        var gard1 = content.createLinearGradient(0, 50, 50, 50); //线性渐变的起止坐标
        gard1.addColorStop(0,"red");
        gard1.addColorStop(1,"blue");
        content.fillStyle=gard1
        content.fillText('安咯,这里是字符串',10,30);
      }
      // 画爱心
      function drawHeart() {
      
      
          radian = 0;//弧度设为初始弧度
          ctx.moveTo(getX(radian), getY(radian));//初始点开始移动
          var grd = ctx.createLinearGradient(50, 50, 150, 150); //线性渐变的起止坐标
          grd.addColorStop(0,"red");
          grd.addColorStop(1,"yellow");
          ctx.lineWidth = 3;//设置线的宽度
          ctx.strokeStyle = grd;// 设置线的颜色
          i = 0;// 计数器  
      }
      // 头像爱心路线
      function printHeart() {
      
      
          radian += Math.PI/180;
          ctx.lineTo(getX(radian), getY(radian));//在旧点和新点之间连线
          ctx.clearRect(0, 0, 300, 400);
          ctx.stroke();//画线
          var imgpeople = new Image()
          imgpeople.src = "https://cdn-app-tx-bj.colorv.com/colorv/resource/ec6a8f22b19ef0496e4f97548fa3b664.png"
          ctx.drawImage(imgpeople,getX(radian)-10, getY(radian)-10, 20,20);
          i++;
          if (i >= 180) {
      
      
              clearInterval(intervalId);
          }
      }  
      function getX(t) {
      
      //由弧度得到 X 坐标  
          return 150 + r * (15 * Math.pow(Math.sin(t), 3));  
      }
      function getY(t) {
      
      //由弧度得到 Y 坐标
          return 70 - r * (14 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(3 * t));
      }  

  </script>  
</body>    

</html> 

画旋转太极

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>太极</title>
    <style>
        *{
      
      
            padding: 0;
            list-style: none;
            margin: 0;
        }
        canvas{
      
      
            display: block;
            margin: 50px auto;
            animation: rotate 2s linear infinite;
        }
        @keyframes rotate{
      
      
            100%{
      
      
                transform: rotate(360deg)
            }
        }
    </style>
</head>
<body>
    <canvas width="400" height="400" class="canvas"></canvas>
    <script>
        var canvas=document.querySelector(".canvas"),
            ctx=canvas.getContext("2d"),
            deg=Math.PI / 180;
        ctx.beginPath();
        ctx.arc(200,200,200,-deg*90,deg*90);
        ctx.fillStyle="#000";
        ctx.fill();

        ctx.beginPath();
        ctx.arc(200,200,200,deg*90,deg*270)
        ctx.strokeStyle="#000";
        ctx.stroke();

        ctx.beginPath();
        ctx.arc(200,100,100,-deg*90,deg*90);
        ctx.fillStyle="#fff";
        ctx.fill();

        ctx.beginPath();
        ctx.arc(200,300,100,deg*90,deg*270);
        ctx.fillStyle="#000";
        ctx.fill();

        ctx.beginPath();
        ctx.arc(200,100,30,0,deg*360);
        ctx.fillStyle="#000";
        ctx.fill();

        ctx.beginPath();
        ctx.arc(200,300,30,0,deg*360);
        ctx.fillStyle="#fff";
        ctx.fill();
    </script>
</body>
</html>

圆环图

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>扇形图</title>
    <style>
        *{
      
      
            margin: 0;
            padding: 0;
            list-style: none;
        }canvas{
      
      
            display: block;
            margin: 50px auto;
            border: 1px solid #000;
        }
    </style>
</head>
<body>
    <canvas width="800" height="500"></canvas>
    <script>
        //数据
        var dataArray = [{
      
      
            ang: 98,
            color: "orangered",
            num: 98
        }, {
      
      
            ang: 24,
            color: "skyblue",
            num: 24
        }, {
      
      
            ang: 54,
            color: "orange",
            num: 54
        }, {
      
      
            ang: 78,
            color: "hotpink",
            num: 78
        }, {
      
      
            ang: 100,
            color: "greenyellow",
            num: 100
        }, {
      
      
            ang: 16,
            color: "tomato",
            num: 16
        }, {
      
      
            ang: 86,
            color: "wheat",
            num: 86
        }, {
      
      
            ang: 48,
            color: "aqua",
            num: 48
        }, {
      
      
            ang: 90,
            color: "#ccc",
            num: 90
        }];

        var canvas = document.querySelector("canvas"),
            deg = Math.PI / 180,
            ctx = canvas.getContext("2d"),
            start = 0;

        var sum=dataArray.reduce(function(cur,pre){
      
      //求取所有数据总和
            cur+=pre.ang;
            return cur;
        },0);

        ctx.translate(400,250);//移动画布中心点
        dataArray.forEach(function(item){
      
      //循环数组
            var sanl = item.ang / sum * 360,//计算数据比例
            end = start + sanl;//求结束点
            //画扇形
            ctx.beginPath();
            ctx.fillStyle = item.color;//扇形颜色
            ctx.moveTo( 0 , 0 );
            ctx.arc( 0 , 0 , 200 , start * deg,end * deg);
            ctx.fill();

            //求中心点
            var center=(start + sanl/2)*deg,
                preX=Math.cos(center)*200,
                preY=Math.sin(center)*200,
                preX1=Math.cos(center)*230,
                preY1=Math.sin(center)*230;
            ctx.beginPath();
            ctx.strokeStyle=item.color;
            ctx.moveTo(preX,preY);
            ctx.lineTo(preX1,preY1);

            var x3=preX1<0?preX1 - 100:preX1 + 100;
            ctx.lineTo(x3,preY1);
            ctx.stroke();

            ctx.beginPath();
            ctx.arc(x3, preY1, 5, 0, 360 * deg);
            ctx.fill();

            ctx.font = "16px nomal";
            ctx.textAlign = "center";
            x3 = preX1 < 0 ? preX1 - 60 : preX1 + 60;
            ctx.fillText(item.num, x3, preY1 - 5);
            start=end;
        })
        //中心大白圆
        ctx.beginPath();
        ctx.fillStyle="#fff";
        ctx.arc(0,0,150,0,360*deg);
        ctx.fill();
    </script>
</body>
</html>

刻度尺

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>刻度尺</title>
    <style>
        *{
      
      
            margin: 0;
            padding: 0;
            list-style: none;
        }canvas{
      
      
            display: block;
            border: 1px solid #000;
            margin: 50px auto;
        }
    </style>
</head>
<body>
    <canvas width="530" height="100" class="canvas"></canvas>
    <script>
        var canvas=document.querySelector(".canvas"),
            ctx=canvas.getContext("2d");
            du=Math.PI /180;
        ctx.fillStyle="#ccc";
        ctx.fillRect(0,40,530,60);
        ctx.arc(50,70,20,0,du*360);
        ctx.fillStyle="red";
        ctx.fill();
        ctx.beginPath();//开启路径
        ctx.arc(200,68,15,0,du*360);
        ctx.fillStyle="yellow";
        ctx.fill();
        ctx.beginPath();//开启路径
        ctx.arc(300,67,10,0,du*360);
        ctx.fillStyle="skyblue";
        ctx.fill();
        
        var data={
      
      
            num:10*10+1,//刻度线
            x:10,//x轴坐标
            y:5,//y轴坐标
            deg:5,//间隙宽
            height:10,//线高
        }
        render(data);//调用渲染方法
        function render(obj){
      
      
            for(var i=0;i < obj.num;i++){
      
      //循环划线
                ctx.beginPath();//开启路径
                ctx.moveTo(obj.deg*i+obj.x,obj.y);//起始坐标
                ctx.fillStyle="#000";//线颜色
                ctx.font="14px normal";//数字大小
                ctx.textAlign="center";//水平居中
                ctx.textBaseline="middle";//垂直居中
                if(i%10===0){
      
      
                    ctx.lineTo(obj.deg*i+obj.x,obj.height+10);
                    ctx.fillText(i / 10,obj.x+i*obj.deg,30)
                }
                else{
      
      
                    ctx.lineTo(obj.deg*i+obj.x,i%5===0?obj.height+5:obj.height);
                }
                ctx.stroke();//描边  切记描边
            }
            
        }
    </script>
</body>
</html>

表盘(类转速表)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>表盘</title>
    <style>
        *{
      
      
            padding: 0;
            margin: 0;
            list-style: none;
        }canvas{
      
      
            border: 1px solid #000;
            margin: 50px auto;
            display: block;
        }
    </style>
</head>
<body>
    <canvas width="500" height="500" class="canvas"></canvas>
    <script>
        var canvas=document.querySelector(".canvas"),
            ctx=canvas.getContext("2d"),
            deg=Math.PI/180;
            //进度条
            ctx.beginPath();
            ctx.translate(250,250);//改变中心
            ctx.lineWidth="20";//线宽
            ctx.lineCap="round";//线端点样式
            ctx.strokeStyle="#ccc";//线颜色
            ctx.arc(0,0,150,deg*150,deg*30);//画半圆
            ctx.stroke();//描边
            //刻度线-刻度值
            for(var i=0;i<=100;i++){
      
      
                ctx.save();//保存原画布状态
                ctx.beginPath();
                ctx.lineWidth="1";//线粗
                ctx.strokeStyle="#000";//线的颜色
                ctx.textAlign="center";//字体居中
                ctx.font="16px normal";//字体大小
                ctx.rotate((i*2.4 - 120)*deg);//每条线的位置
                if(i%10===0){
      
      
                    ctx.moveTo(0,-170);
                    ctx.lineTo(0,-195);
                    ctx.fillText(i,0,-200);//刻度值
                }else{
      
      
                    ctx.moveTo(0,-170);
                    ctx.lineTo(0,-185);
                }
                ctx.stroke();//描边
                ctx.restore();//返回保存过的路径状态和属性
            }
            //动画
            var num=0;
            function draw(){
      
      
                num++;
                if(num<100){
      
      
                    requestAnimationFrame(draw);
                }
                var endDeg = 150 + 2.4 * num;//每一个刻度所占度数
                ctx.clearRect(-55, -50, 110, 100);//用于改变数据   视觉效果
                var color=ctx.createLinearGradient(0,250,200,250);//设置渐变色
                color.addColorStop(0,'yellow');//起始颜色
                color.addColorStop(1,"red");//终止颜色
                ctx.beginPath();
                ctx.lineWidth=20;//线宽
                ctx.lineCap="round";//圆角端点
                ctx.strokeStyle=color;//渐变色
                ctx.arc(0,0,150,deg*150,endDeg*deg);
                ctx.stroke();
                //数字
                ctx.font="50px normal";//字体大小
                ctx.textAlign="center";//水平居中
                ctx.textBaseline="middle";//垂直居中
                ctx.fillText(num+"%",0,0)//数据展示位置
                
            }
            draw();
    </script>
</body>
</html>

画板(类画图工具)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        canvas {
      
      
            display: block;
        }
    </style>
</head>

<body>

    <canvas width="500" height="400"></canvas>
    <div class="wrapper">
        <input id="color" type="color" value="#ffffff">
        <input id="range" type="range" max="50" min="5">
        <button id="brush" type="button">画笔</button>
        <button id="rubbish" type="button">垃圾桶</button>
        <button id="save" type="button">保存</button>
    </div>


    <script>
        function $(selector) {
      
      
            return typeof selector === "string" ? document.querySelector(selector) : selector;
        };

        var canvas = document.querySelector("canvas"),
            ctx = canvas.getContext("2d");

        ctx.fillRect(0, 0, canvas.width, canvas.height);
        bindEventFn();

        function bindEventFn() {
      
      
            $("#brush").addEventListener("click", brushFn);
            $("#rubbish").addEventListener("click", rubshFn);
            $("#save").addEventListener("click", saveFn);
            canvas.addEventListener("mousedown", startFn)
        };

        //1.source-over
        //这是默认值,他表示绘制的图形将画在现有画布之上
        //2.destination-out
        //在与源不重叠的区域上保留目标。其他部分都变成透明的。

        function brushFn() {
      
      
            if (this.innerHTML === "画笔") {
      
      
                this.innerHTML = "橡皮擦";
                ctx.globalCompositeOperation = "source-over";
            } else {
      
      
                this.innerHTML = "画笔";
                ctx.globalCompositeOperation = "destination-out";
            }
        }


        function saveFn() {
      
      
            //把画布转换为路径
            var src = canvas.toDataURL();
            var img = new Image(); //创建一张图片
            img.src = src;
            img.onload = function() {
      
      
                document.body.appendChild(img);
            }

        }


        function rubshFn() {
      
      
            ctx.fillRect(0, 0, canvas.width, canvas.height);
        }

        var startPos = null;

        function startFn(e) {
      
      
            startPos = {
      
      
                x: e.pageX - this.offsetLeft,
                y: e.pageY - this.offsetTop
            };
            ctx.beginPath();
            ctx.moveTo(startPos.x, startPos.y)
            canvas.addEventListener("mousemove", moveFn);
            canvas.addEventListener("mouseup", upFn);
        };

        function moveFn(e) {
      
      
            var moveX = e.pageX - this.offsetLeft,
                moveY = e.pageY - this.offsetTop;

            ctx.lineWidth = $("#range").value;
            ctx.strokeStyle = $("#color").value;
            ctx.lineTo(moveX, moveY);
            ctx.stroke();
        };

        function upFn() {
      
      
            canvas.removeEventListener("mousemove", moveFn);
        }
    </script>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/vh_YUNYANGYUMO/article/details/117411801