JavaScript-canvas(画布)初识、刮刮卡简单练习

JavaScript-canvas(画布)初识、刮刮卡制作、画板

一、canvas初识

Canvas元素的出现,可以说开启的Web世界绘制动画,图形的大门,其功能非常强大,canvas 元素是HTML5中功能最强大的元素,它的能力主要是通过Canvas中的Context(绘图上下文/绘图环境)对象表现出来的。

1.getContext()方法是用来获得渲染上下文和它的绘画功能。
2.绘制矩形:
fillRect(x, y, width, height) 绘制一个填充的矩形
strokeRect(x, y, width, height) 绘制一个矩形的边框
clearRect(x, y, width, height) 清除指定矩形区域,让清除部分完全透明。
3.绘制路径:
beginPath() 新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。
closePath() 闭合路径之后图形绘制命令又重新指向到上下文中。
stroke() 通过线条来绘制图形轮廓。
fill() 通过填充路径的内容区域生成实心的图形。
4.移动笔触: moveTo(x, y) 将笔触移动到指定的坐标x以及y上。绘制直线路径:lineTo(x, y) 绘制一条从当前位置到指定x以及y位置的直线
5.绘制圆弧路径:
arc(x, y, radius, startAngle, endAngle, anticlockwise) 画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针)来生成。
arcTo(x1, y1, x2, y2, radius) 根据给定的控制点和半径画一段圆弧,再以直线连接两个控制点。
角度与弧度的js表达式:radians=(Math.PI/180)*degrees
6.填充颜色:
fillStyle = color 设置图形的填充颜色
strokeStyle = color 设置图形轮廓的颜色
透明度 globalAlpha = transparencyValue 这个属性影响到 canvas 里所有图形的透明度,有效的值范围是 0.0 (完全透明)到 1.0(完全不透明),默认是 1.0。
7.线型 Line styles
lineWidth = value 设置线条宽度,宽度为奇数的线并不能精确呈现
lineCap = type 设置线条末端样式。
lineJoin = type 设定线条与线条间接合处的样式。
miterLimit = value 限制当两条线相交时交接处最大长度;所谓交接处长度(斜接长度)是指线条交接处内角顶点到外角顶点的长度。

canvas属性速查表:
第一步:引入canvas

<body>
   <canvas id="canvas_1" width="600" height="600">
        这里面的内容,正常画布是不显示的,
        canvas三要素:id唯一标识
        width宽height高
        canvas仅仅是一个画布标签,要绘制内容必须用js绘制
    </canvas>
</body>

第二步:引入canvas

    //1、找到画布
    var canvas1 = document.querySelector("#canvas_1");
    console.log([canvas1])
    //2.上下文对象(画笔)
    var pencil = canvas1.getContext("2d");
    //3.绘制路径
    pencil.rect(50,50,300,300);//绘制一个矩形
    //4填充
    pencil.fillStyle = "pink";
    pencil.fill()
    //描边,渲染路径
    pencil.lineWidth = 20;//设置绘制宽度
    pencil.strokeStyle = "salmon";//设置绘制颜色
    pencil.stroke()

示例
绘制矩形

<!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>
</head>
<body>
    <canvas id="canvas_1" width="600" height="600">
        这里面的内容,正常画布是不显示的,
        canvas三要素:id唯一标识
        width宽height高
        canvas仅仅是一个画布标签,要绘制内容必须用js绘制
    </canvas>
    <script>
    //1、找到画布
    var canvas1 = document.querySelector("#canvas_1");
    console.log([canvas1])
    //2.上下文对象(画笔)
    var pencil = canvas1.getContext("2d");
    console.log(pencil);
    //3.绘制路径
    pencil.rect(50,50,300,300);
    //填充
    pencil.fillStyle = "pink";
    pencil.fill()
    //描边,渲染路径
    pencil.lineWidth = 20;
    pencil.strokeStyle = "salmon";
    pencil.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>Document</title>
</head>
<body>
    <canvas id="canvas_1" width="500" height="500"></canvas>
    <script>
    var canvas1 = document.querySelector("#canvas_1");
    var cvs = canvas1.getContext('2d');
    console.log(cvs)
    //设置开始路径
    cvs.beginPath()
    //设置经过某个位置的起点
    cvs.moveTo(50,50);
    //设置经过某个位置
    cvs.lineTo(50,200);
    //设置经过某个位置
    cvs.lineTo(60,300);
    //设置经过某个位置
    cvs.lineTo(100,50);
    //设置结束路径
    cvs.closePath()
    //绘制路径
    cvs.lineCap = "round";//设置路径经过的边缘为圆角
    cvs.lineJoin = "round";
    cvs.strokeStyle = "pink";
    cvs.lineWidth = 10;
    cvs.stroke();
    </script>
</body>
</html>
二、绘制文本

绘制文本

cvs.font = "30px 微软雅黑";
<!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>
</head>
<body>
    <canvas id="canvas_1" width="500" height="500"></canvas>
    <script>
    var canvas1 = document.querySelector("canvas");
    var cvs = canvas1.getContext("2d");
    //设置阴影
    cvs.shadowBlur = 20;
    cvs.shadowColor = "skyblue";
    cvs.shadowOffsetX = 10;
    cvs.shadowOffsetY = 10;
    cvs.font = "30px 微软雅黑";
    cvs.strokeStyle = "#333";
    var x = 500;
    setInterval(function(){
        cvs.clearRect(0,0,500,500)
        x -=3;
        if(x<-100){
            x=500
        }
        cvs.strokeText("这也太可爱吧",x,200);
    },30)
    </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>
  </head>
  <body>
    <canvas id="canvas_1" width="600" height="600"></canvas>
    <script>
      var canvas1 = document.querySelector("canvas");
      var cvs = canvas1.getContext("2d");
      //绘制图像cvs.drawImage(图片对象,x位置,y位置)
      //绘制图像cvs.drawImage(图片对象,x位置,y位置,宽度,高度)
      //绘制图像cvs.drawImage(图片对象,裁剪的位置x,裁剪的位置y,裁剪的宽度,裁剪的高度,x位置,y位置,宽度,高度)
      var img = new Image();
      img.src = "../js学习/imag/clockbg.png";
      img.onload = function() {
        cvs.translate(400, 300);
        cvs.arc(0, 0, 200, 0, 2 * Math.PI);
        cvs.clip();
        cvs.drawImage(img, -200, -200, 400, 400);
        cvs.strokeStyle = "orange";
        cvs.lineWidth = 10;
        cvs.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>Document</title>
</head>
<body>
        <video src="../MP3/mda-mke7tdctjt86cnib.mp4" controls="controls"  width="400" height=""></video>
    <canvas id="canvas" width="600" height="600"></canvas>
<script>
    var interid;
    var video1 = document.querySelector("video");
    var canvas1 = document.querySelector("canvas");
    var cvs = canvas1.getContext("2d");
    video1.onplay = function(){
        interid = setInterval(function(){
            cvs.clearRect(0,0,600,600)
            cvs.fillRect(0,0,600,600)
            cvs.drawImage(video1,100,70,400,225);
        },16)
    }
    video1.onpause = function(){
        clearInterval(interid);
    }
</script>
</body>
</html>

在这里插入图片描述

四、时钟

save用于保存当前的画布状态,restore将画布状态重置到save保存时的样子。画布状态分为画布的坐标(transform),画布绘制区域(clip),画布中设置的组合方式(globalCompositeOperatio)。当我们在使用transform,clip和globalCompositeOperatio时会改变画布的状态,而这种改变会影响到接下来的画布绘制操作,所以在进行这种操作前需要使用save来对画布进行一次保存,在进行改变状态后的下一步操作中使用restore来重置画布状态。

<!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>
  </head>
  <body>
    <canvas id="canvas_1" width="800" height="600"></canvas>
    <script>
      var img = new Image();
      img.src = "../js学习/imag/clockbg.png";
      var canvas1 = document.querySelector("canvas");
      var cvs = canvas1.getContext("2d");
      img.onload= function(){
        xuanranclock();
      setInterval(function() {
        xuanranclock();
      }, 1000);
      }
      function xuanranclock() {
        cvs.clearRect(0, 0, 800, 600);
        //绘制表盘
        cvs.beginPath();
        cvs.arc(400, 300, 200, 0, 2 * Math.PI);
        cvs.clip();
        cvs.drawImage(img, 200, 100, 400, 400);
        cvs.strokeStyle = "orange";
        cvs.lineWidth = 10;
        cvs.stroke();
        cvs.closePath();
        //保存一下状态
        cvs.save();
        //将画布的坐标移动到画布的中央
        cvs.translate(400, 300);
        cvs.rotate((-2 * Math.PI) / 4);
        cvs.save();
        //绘制时钟刻度
        for (var i = 0; i < 12; i++) {
          cvs.rotate((Math.PI * 2) / 12);
          cvs.beginPath();
          cvs.moveTo(180, 0);
          cvs.lineTo(200, 0);
          cvs.strokeStyle = "orange";
          cvs.stroke();
          cvs.closePath();
        }
        cvs.restore();
        cvs.save();
        //绘制秒针
        for (var i = 0; i < 60; i++) {
          cvs.beginPath();
          cvs.rotate(Math.PI / 30);
          cvs.moveTo(180, 0);
          cvs.lineTo(200, 0);
          cvs.lineWidth = 2;
          cvs.strokeStyle = "orange";
          cvs.stroke();
          cvs.closePath();
        }
        cvs.restore();
        cvs.save();

        var time = new Date();
        var hour = time.getHours();
        var min = time.getMinutes();
        var sec = time.getSeconds();
        //如果时间大于12那就直接减去十二
        hour = hour > 12 ? hour - 12 : hour;
        //绘制秒针
        cvs.beginPath();
        cvs.rotate(((2 * Math.PI) / 60) * sec);
        cvs.moveTo(-20, 0);
        cvs.lineTo(170, 0);
        cvs.lineWidth = 2;
        cvs.strokeStyle = "rgb(135, 197, 248)";
        cvs.stroke();
        cvs.closePath();
        cvs.restore();
        cvs.save();
        //绘制fen针
        cvs.beginPath();
        cvs.rotate((2 * Math.PI * min) / 60 + ((2 * Math.PI) / 3600) * sec);
        cvs.moveTo(-20, 0);
        cvs.lineTo(160, 0);
        cvs.lineWidth = 4;
        cvs.strokeStyle = "#333";
        cvs.stroke();
        cvs.closePath();
        cvs.restore();
        cvs.save();
        //绘制时针刻度
        cvs.beginPath();
        cvs.rotate(
          (2 * Math.PI * hour) / 12 +
            ((2 * Math.PI) / 60 / 12) * min +
            ((2 * Math.PI) / 12 / 60 / 60) * sec
        );
        cvs.moveTo(-10, 0);
        cvs.lineTo(140, 0);
        cvs.lineWidth = 6;
        cvs.strokeStyle = " rgb(105, 69, 236)";
        cvs.stroke();
        cvs.closePath();
        cvs.restore();

        cvs.beginPath();
        //盖子
        cvs.arc(0, 0, 10, 0, 2 * Math.PI);
        cvs.fillStyle = "black";
        cvs.fill();
        cvs.closePath();
        cvs.restore();
      }
    </script>
  </body>
</html>

效果图
在这里插入图片描述

五、刮刮卡制作

预备知识

globalCompositeOperation用于控制源图像在目标图像上的显示方式。
源图像:指你准备绘制到画布上的图像
目标图像:在画布上已经绘制的图像

属性值:

描述
source-over默认。在目标图像上显示源图像。
source-atop源图像为透明的,只有源图像与目标图像有交集的地方显示源图像,其他部分透明
source-in源图像和目标图像都透明,只有源图像和目标图像有交集的地方不透明,且显示源图像
source-out目标图像透明,源图像不透明,如果目标图像和源图像有交集的话,交集部分的图像透明
destination-over将源图像绘制在目标图像的下层
destination-atop目标图像透明,源图像不透明,如果目标图像和源图像有交集的话,在交际部分显示目标图像
destination-in源图像和目标图像都透明,只有目标图像和源图像交集的部分不透明且显示目标图像
destination-out目标图像不透明,源图像透明,如果目标图像和源图像有交集的话,交集部分图像透明
lighter源图像和目标图像一起绘制在画布中,如果两者之间有交集的话颜色会进行叠加
copy画布上只显示源图像,目标图像都不在画布中显示
xor源图像和目标图像都在画布中显示,如果两者之间有交集的话,交集部分不显示图像

    <script>
      var canvas1 = document.querySelector("canvas");
      var cvs = canvas1.getContext("2d");
      cvs.fillStyle = "red";
      cvs.fillRect(0,0,200,200);
      cvs.fillStyle = "pink";
      cvs.fillRect(100,100,200,200);
    </script>

效果图
在这里插入图片描述

cvs.globalCompositeOperation = "source-over";

在这里插入图片描述

cvs.globalCompositeOperation = "source-atop";

在这里插入图片描述

cvs.globalCompositeOperation = "source-in";

在这里插入图片描述

cvs.globalCompositeOperation = "source-out";

在这里插入图片描述

cvs.globalCompositeOperation = "destination-over";

在这里插入图片描述

 cvs.globalCompositeOperation = "destination-atop";

在这里插入图片描述

cvs.globalCompositeOperation = "destination-in";

在这里插入图片描述

cvs.globalCompositeOperation = "destination-out";

在这里插入图片描述

<!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>
  </head>
  <style>
    .ggk {
      width: 250px;
      height: 150px;
      position: relative;
    }
    .content,
    #canvas_1 {
      width: 250px;
      height: 150px;
      text-align: center;
      line-height: 150px;
      position: absolute;
      left: 0;
      top: 0;
    }
  </style>
  <body>
    <div class="ggk">
      <div class="content">一等奖</div>
      <canvas id="canvas_1" width="250" height="150"></canvas>
    </div>
    <script>
      var isDraw;
      var canvas1 = document.querySelector("canvas");
      var cvs = canvas1.getContext("2d");
      var ggk = document.querySelector("div");
      var content = document.querySelector(".content");
      cvs.fillStyle = "red";
      cvs.fillRect(0, 0, 250, 150);
      cvs.font = "30px 微软雅黑";
      cvs.fillStyle = "#fff";
      cvs.fillText("刮刮卡", 85, 80);
      canvas1.onmousemove = function(e) {
        if (isDraw) {
          var x = e.pageX - ggk.offsetLeft;
          var y = e.pageY - ggk.offsetTop;
          cvs.globalCompositeOperation = "destination-out"
          cvs.arc(x, y, 18, 0, 2 * Math.PI);
          cvs.fill();
        }
      };
      canvas1.onmousedown = function(e) {
        isDraw = true;
        console.log(e);
      };
      canvas1.onmouseup = function(e) {
        isDraw = false;
        console.log(e);
      };
    </script>
  </body>
</html>

请添加图片描述

六、画板练习
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <link rel="stylesheet" href="../css/huaban.css" />
    <link rel="stylesheet" href="../js学习//font/hubanfont/iconfont.css" />
  </head>
  <body>
    <div class="tool">
      <div class="btn"><span class="iconfont icon-huaban"></span></div>
      <div class="btn"><span class="iconfont icon-juxingxuanze"></span></div>
      <div class="btn">
        <span class="iconfont icon-xingzhuang-tuoyuanxing"></span>
      </div>
      <div class="btn"><span class="iconfont icon-xianduan"></span></div>
      <div class="btn"><input type="color" class="color"></span></div>
      <div class="btn"><span class="iconfont icon-bold "></span></div>
      <div class="btn"><span class="iconfont icon-xiangpica "></span></div>
      <div class="btn"><span class="iconfont icon-xiazai "></span></div>
      <div class="btn" hidden><a href="">xiazai</a></div>
    </div>
    <canvas id="canvas1"></canvas>
    <script>
      var canvas = document.querySelector("canvas");
      var huabiBtn = document.querySelector(".btn:nth-child(1)");
      var rectBtn = document.querySelector(".btn:nth-child(2)");
      var circleBtn = document.querySelector(".btn:nth-child(3)");
      var weightBtn = document.querySelector(".btn:nth-child(4)");
      var colorbtnBtn = document.querySelector(".btn:nth-child(5)");
      var jiacuBtn = document.querySelector(".btn:nth-child(6)");
      var xiangpiBtn = document.querySelector(".btn:nth-child(7)");
      var downloadBtn = document.querySelector(".btn:nth-child(8)");
      var colorInput = document.querySelector(".color");
      var btnList = document.querySelectorAll(".btn");
      canvas.setAttribute("width", canvas.offsetWidth);
      canvas.setAttribute("height", canvas.offsetHeight);
      var cvs = canvas.getContext("2d");
      var huanban = {
        imgData: null,
        beginX: 0,
        beginY: 0,
        lineWidth:6,
        color:"#333",
        type: "none",
        isDraw: false,
        huabiFn: function(e) {
          var x = e.pageX - canvas.offsetLeft;
          var y = e.pageY - canvas.offsetTop;
          cvs.strokeStyle = huanban.color;
          cvs.lineTo(x,y);   
          cvs.lineWidth = huanban.lineWidth;
          cvs.stroke();
        },
        rectFn: function(e) {
          var x = e.pageX - canvas.offsetLeft;
          var y = e.pageY - canvas.offsetTop;
          cvs.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight);
          if(huanban.imgData != null){
              cvs.putImageData(huanban.imgData,0,0,0,0,canvas.offsetWidth,canvas.offsetHeight);
            }
          cvs.beginPath();
          cvs.strokeStyle = huanban.color;
          cvs.rect(
            huanban.beginX,
            huanban.beginY,
            x - huanban.beginX,
            y - huanban.beginY
          );
          cvs.stroke();
          cvs.closePath();
        },
        circleFn: function(e) {
          var x = e.pageX - canvas.offsetLeft;
          var y = e.pageY - canvas.offsetTop;
          cvs.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight);
          if(huanban.imgData != null){
                cvs.putImageData(huanban.imgData,0,0,0,0,canvas.offsetWidth,canvas.offsetHeight);
            }
          cvs.beginPath();
          cvs.strokeStyle = huanban.color;
          cvs.arc(
            huanban.beginX,
            huanban.beginY,
            y - huanban.beginY ,0, 2 * Math.PI
          );
          cvs.stroke();
          cvs.closePath();
        },
      };
      function clearclass() {
        btnList.forEach(function(item,index){
          for(var i=1;i<9;i++){
            item.classList.remove("active"+i);
          }
        })
      }
      huabiBtn.onclick = function() {
        clearclass();
        huabiBtn.classList.add("active1");
        huanban.type = "huabi";
      };
      rectBtn.onclick = function() {
        clearclass();
        rectBtn.classList.add("active2");
        huanban.type = "rect";
      };
      circleBtn.onclick = function() {
        clearclass();
        circleBtn.classList.add("active3");
        huanban.type = "circle";
      };
      weightBtn.onclick = function() {
        clearclass();
        weightBtn.classList.add("active4");
      };
      colorbtnBtn.onclick = function() {
        clearclass();
        colorbtnBtn.classList.add("active5");
      };
      colorInput.onchange = function(e){
        huanban.color = colorInput.value;
      console.log(colorInput.value)
      }
      jiacuBtn.onclick = function(){
        clearclass();
        jiacuBtn.classList.add("active6");
      }
      xiangpiBtn.onclick = function(){
        clearclass();
        xiangpiBtn.classList.add("active7");
        cvs.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight);
        huanban.imgData = null;
      }
      downloadBtn.onclick = function(){
        clearclass();
        var hiddenxiazaia = document.querySelector(".btn a");
        downloadBtn.classList.add("active8");
        huanban.type = "download";
        var url = canvas.toDataURL();
        hiddenxiazaia.setAttribute("href",url);
        hiddenxiazaia.click()
        console.log(url)
      }
      canvas.onmousedown = function(e) {
          huanban.isDraw = true;
          var x = e.pageX - canvas.offsetLeft;
          var y = e.pageY - canvas.offsetTop;
          huanban.beginX = x;
          huanban.beginY = y;
        if (huanban.type == "huabi"){
          cvs.beginPath();
          cvs.moveTo(x,y);
        }
      };
      canvas.onmousemove = function(e) {
        if (huanban.isDraw) {
          var strFn = huanban.type + "Fn";
          huanban[strFn](e);
        }
      };
      canvas.onmouseup = function() {
        huanban.imgData = cvs.getImageData(0,0,canvas.offsetWidth,canvas.offsetHeight);
        huanban.isDraw = false;
        if (huanban.type == "huabi"){
          cvs.closePath();
        }
      };
    </script>
  </body>
</html>

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可可鸭~

想吃糖~我会甜

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值