Basic use and precautions of vue-canvas - animation flickering effect - adaptive adaptation to different resolutions

foreword

  • Canvas is a new feature of html, familiar with the canvas we can complete a lot of functions of dragging, labeling and animation

  • It's easy to implement a small example using canvas, but when we actually use it in a project, we need to pay attention to many things

  • The basic principle of canvas is that it is based on the rendering method, and renders the canvas effect according to the relative x, y coordinates, length, and width of the canvas.

  • Between proficient use, we definitely need to connect the basic use and related precautions, so that we can quickly solve problems when we encounter them

Basic use of canvas - generate canvas - .vue page

1. First write a canvas tag in html

2. Find the canvas tag by id or ref to generate the canvas

// 书写canvas标签
<canvas ref="canvas"></canvas>
// 找到画布标签
this.canvas = this.$refs.canvas;
// 设置画布宽高
this.canvas.width = 500;
this.canvas.height = 200;
// 生成画布
this.ctx = this.canvas.getContext("2d");

Basic use of canvas - rendering text

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>canvas-渲染文字</title>
  </head>
  <body>
    <canvas
      id="canvas_1"
      width="1000"
      height="500"
      style="box-shadow: 0px 0px 20px skyblue;"
    >
    </canvas>
  </body>
​
  <script>
    // 获取画布
    var canvas = document.getElementById('canvas_1')
    // 生成画布 - 获取实例
    var ctx = canvas.getContext('2d')
​
    // canvas-文字基本使用
    // ctx.font = '字体大小 字体样式'
    // ctx.fillStyle = '字体颜色'
    // ctx.fillText ('字体','画布x坐标','画布y坐标','总体字体宽度')
    // 细节-ctx.fillText字体宽度-小于实际字体总宽度时会生效,大于实际字体总宽度时,不生效-就是默认字体总宽度
​
    // 实心文字
    ctx.font = '30px Arial'
    ctx.fillText('欢迎来到canvas', 10, 50)
​
    // 空心文字
    ctx.font = '30px Arial'
    ctx.strokeText('欢迎来到canvas', 10, 100)
​
    // 有颜色实体字
    ctx.font = '30px Arial'
    ctx.fillStyle = '#1ba035'
    ctx.fillText('欢迎来到canvas', 10, 150)
​
    // 空心文字有颜色 - 没有效果
​
    // 实心文字 - 有颜色 - 总体字体宽度
    ctx.font = '30px Arial'
    ctx.fillStyle = '#1ba035'
    ctx.fillText('欢迎来到canvas', 10, 200, 100)
​
    // 空心文字 - 总体宽度500 - 超过实际字体总宽度 - 会是默认字体总宽度
    ctx.font = '30px Arial'
    ctx.strokeText('欢迎来到canvas', 10, 260, 800)
  </script>
</html>

Basic use of canvas - rendering circle - fill color

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>用canvas画一个圆</title>
  </head>
  <body>
    <canvas
      id="canvas_1"
      width="1000"
      height="500"
      style="box-shadow: 0px 0px 20px skyblue;"
    >
    </canvas>
  </body>
​
  <script>
    // 获取画布
    var canvas = document.getElementById('canvas_1')
    // 生成画布
    var ctx = canvas.getContext('2d')
    // 开始绘制
    ctx.beginPath()
    // 圆形坐标
    let x = 50
    let y = 50
    // arc 的意思是“弧”
    // 2*Math.PI=360度
    // ctx.arc(在画布x坐标,在画布y坐标,园半径,起始位置,结束位置)
    ctx.arc(x, y, 40, 0, 2 * Math.PI)
    // 填充颜色
    ctx.fillStyle = '#007acc'
    //开始填充
    ctx.fill()
    // 绘制线条颜色更改
    ctx.strokeStyle = 'blue'
    // 绘制线条颜色-默认黑色
    ctx.stroke()
  </script>
</html>

Basic use of canvas - animation - circular flickering effect animation

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>用canvas画一个圆-闪动</title>
  </head>
  <body>
    <canvas
      id="canvas_1"
      width="1000"
      height="500"
      style="box-shadow: 0px 0px 20px skyblue;"
    >
    </canvas>
    <button></button>
  </body>
​
  <script>
    // 获取画布
    var canvas = document.getElementById('canvas_1')
    // 生成画布
    var ctx = canvas.getContext('2d')
    let maxRadius = 50
    let minRadius = 30
    let radius = 30
    let flg = 1
    let z = 1
    let color = 'red'
    let x = 100
    let y = 100
    let start = function () {
      radius += flg * z
      if (radius >= maxRadius) flg = -flg
      if (radius <= minRadius) flg = -flg
      ctx.beginPath()
      ctx.arc(x, y, radius, 0, 2 * Math.PI)
      ctx.clearRect(0, 0, canvas.width, canvas.height)
      // ctx.clearRect(x, y, maxRadius, maxRadius);
      // 填充颜色
      ctx.fillStyle = color
      //开始填充
      ctx.fill()
      // 绘制线条颜色更改
      ctx.strokeStyle = 'blue'
      // 绘制线条颜色-默认黑色
      ctx.stroke()
    }
    let time = setInterval(function () {
      start()
    }, 20)
  </script>
</html>

Basic use of canvas - picture level problem

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>用canvas图片层级问题</title>
  </head>
  <body>
    <canvas
      id="canvas_1"
      width="1000"
      height="500"
      style="box-shadow: 0px 0px 20px skyblue;"
    >
    </canvas>
    <button></button>
  </body>
​
  <script>
    // 获取画布
    var canvas = document.getElementById('canvas_1')
    // 生成画布
    var ctx = canvas.getContext('2d')
    // 背景
    let background =
      'https://tyunfile.71360.com/UpLoadFile/2019/7/1/14/636975889218136385_shiyugongye_2267571.jpg'
​
    // 目标
    let target =
      'https://img2.baidu.com/it/u=3223764237,2661865711&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'
    
    // 渲染方法
    let rendergraph = function (imgs, x, y, w, h) {
      // 创建一个img标签渲染图片
      let img = new Image()
      // 赋值图片
      img.src = imgs
      // 图片赋值在执行渲染
      img.onload = function () {
        // 渲染目标图片
        // ctx.drawImage(img标签, x坐标, y坐标, 宽度, 高度)
        ctx.drawImage(img, x, y, w, h)
      }
    }
    // 渲染背景图
    rendergraph(background, 0, 0, 1000, 500)
    // 渲染目标图
    rendergraph(target, 415, 80, 50, 50)
​
    // 总结:因为先渲染背景,在渲染篮球,所以篮球在背景之上
    // 总结:canvas图片层级是根据渲染顺序决定的
  </script>
</html>

Basic use of canvas - text - shape level issues

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>canvas-园-文字层级问题</title>
  </head>
  <body>
    <canvas
      id="canvas_1"
      width="1000"
      height="500"
      style="box-shadow: 0px 0px 20px skyblue;"
    >
    </canvas>
    <button></button>
  </body>
​
  <script>
    // 获取画布
    var canvas = document.getElementById('canvas_1')
    // 生成画布
    var ctx = canvas.getContext('2d')
    // 绘制字体-这个数字不会显示,被园遮挡
    ctx.fillStyle = '#fff'
    ctx.font = '20px 黑体'
    ctx.fillText('2', 100, 50, 20)
​
    // 开始绘制 - 这是一个周期-开始结束-只会渲染一个颜色
    ctx.beginPath()
    // 填充颜色
    ctx.fillStyle = '#bc8856'
    // ctx.arc(在画布x坐标,在画布y坐标,园半径,起始位置,结束位置)
    ctx.arc(100, 50, 40, 0, 2 * Math.PI)
​
    // 填充颜色
    ctx.fillStyle = '#437778'
    // ctx.arc(在画布x坐标,在画布y坐标,园半径,起始位置,结束位置)
    ctx.arc(150, 50, 20, 0, 2 * Math.PI)
​
    //开始填充
    ctx.fill()
​
​
    // 开始绘制-第二个周期
    ctx.beginPath()
    // 填充颜色
    ctx.fillStyle = '#bc8856'
    // ctx.arc(在画布x坐标,在画布y坐标,园半径,起始位置,结束位置)
    ctx.arc(100, 200, 40, 0, 2 * Math.PI)
    //开始填充
    ctx.fill()
​
    
    // 绘制字体-会显示-代码执行顺序
    ctx.fillStyle = '#fff'
    ctx.font = '20px 黑体'
    ctx.fillText('2', 150, 50, 20)
​
    ctx.fillStyle = '#fff'
    ctx.font = '20px 黑体'
    ctx.fillText('2', 100, 200, 20)
​
​
    // 总结:圆形默认填充色是黑色
    // 文字和图形的层级问题,取决于代码执行顺序
  </script>
</html>
​

Canvas Precautions-White Screen Phenomenon-Rendering Problem-Solution Homepage Articles

  • There is a way to render the canvas tag, but every time we modify it, a white screen will flash past when we execute the rendering

  • No matter how fast the rendering is, it takes time. You can solve this problem with the help of animation and video frames. The faster the frame rate, the harder it is for the naked eye to see.

  • It means that we need to encapsulate the rendering method, background image, and icon, write a timer to control the number of frames, and keep rendering

  • The advantage is that there will be no white screen phenomenon. You only need to change the background data and icon data to realize the non-inductive refresh of the canvas, which cannot be noticed

  • Disadvantages Because of the use of timers, the timer must be processed when the canvas is destroyed, because the timer will flash the icon on this page for a long time

Canvas Notes - Adaptive Layout - Adapt to Different Resolutions

  • The function can be realized all the time, and the adaptation problem has always been a headache, because we can't control the user's computer model

  • Two points need to be paid attention to when adapting the canvas, control the length and width of the canvas not to exceed the page layout, and control the proportional scaling of the data on the page

  • Most articles on canvas write the length and width directly on the label, in the data, or directly assign values ​​​​in the methed method

  • In this way, we are good on the current page. When we replace it with an old screen, notebook, or mac, the canvas will be deformed immediately, affecting the use

Code implementation - such as the current page canvas 1000*500

1. First adapt the project as a whole - the homepage article has a pc end to adapt to devices with different resolutions

Disadvantages: Inline styles cannot take effect (the width and height written on the label will not take effect either)

2. So we need to put a layer of div outside the canvas tag and set it to 1000*500. When the resolution changes - we have done an overall adaptation - the style of the outer div will also change to the current viewport length in the style Width - Get the length and width of the outer div before the canvas is generated and assign it to the canvas - so that no matter how the resolution changes, the outer div will change accordingly, and the length and width of the canvas will also change accordingly, achieving an adaptive effect

2.1 Canvas tags

<div id="canvas-item">
              <canvas
                ref="canvas"></canvas>
</div>

2.2 style style

 #canvas-item {
        width: 1000px;
        height: 500px;
        // 画布
        canvas {
          width: 100%;
          height: 100%;
        }
      }

2.3 Get the size of the outer div and assign it to the canvas before generating the canvas

      
// 通过id找到canvas标签外层div标签
      let canvasfa = document.getElementById("canvas-item");
      // 获取外层div长宽-除了这种方式其他都获取不到-费老大劲
      let x = window.getComputedStyle(canvasfa).getPropertyValue("width");
      let y = window.getComputedStyle(canvasfa).getPropertyValue("height");
      // 截取结果-去除最后2位单位'px'
      let wx = Number(x.slice(0, -2));
      let wy = Number(y.slice(0, -2));
      // 这是重要判断依据-根据长宽范围判断在什么设备-针对性对画布上数据进行处理
      console.log("长宽", wx, wy);
      // 找到画布标签
      this.canvas = this.$refs.canvas;
      // 设置画布宽高-遮掩画布的长宽就写活了-自适应适配-不会破坏布局
      this.canvas.width = wx;
      this.canvas.height = wy;
      // 生成画布
      this.ctx = this.canvas.getContext("2d");

2.4 According to the length and width range values ​​​​of different resolution devices as judgment conditions - adapt the data on the canvas

Note: Try not to use == to judge the length and width of the condition. It is more reasonable to use <= >= (to avoid some resolutions that cannot be taken care of)

Canvas pays attention to implementation - understand by yourself

  • Canvas technology can realize many functions, such as electronic signature, point mark drag and drop, animation, drawing board, etc.

  • Understand these basic knowledge, basic use, precautions, have ideas when building functions, and have the ability to distinguish the authenticity of articles

  • There will definitely be various problems in actual development, but slowly solving these problems is also a kind of progress. If you have a problem, someone else has, and it can be solved

  • AntV can also achieve similar functions of canvas, but each technology has its advantages and disadvantages, one more is better than none, come on! ! !


Summarize:

After this process, I believe you also have a preliminary deep impression on the basic use and precautions of vue-canvas-animation flickering effect-adaptive adaptation to different resolutions, but the situation we encountered in actual development must be They are different, so we have to understand its principle, and it is always the same. Come on, hit the workers!

Please point out any deficiencies, thank you -- Fengguowuhen

Guess you like

Origin blog.csdn.net/weixin_53579656/article/details/132483087