React中使用Canvas

1. Canvas

  1. Canvas是HTML5新增的組件,它就像一塊幕布,可以用JavaScript在上面繪制各種圖表、動(dòng)畫等。
    只能夠js腳本驅(qū)動(dòng)是Canvas的特點(diǎn)。
  2. canvas元素
<canvas id='mycanvas' width=400 height=400>
    Your browser does not support the canvas element.
</canvas>
  • 支持canvas的瀏覽器會(huì)只渲染canvas標(biāo)簽,而忽略其中的替代內(nèi)容。不支持 canvas的瀏覽器則會(huì)直接渲染替代內(nèi)容。
  • 說(shuō)明canvas內(nèi)部是不可以嵌套其他dom結(jié)構(gòu)的。
  1. CanvasRenderingContext2D對(duì)象
    所有的繪圖操作都需要通過(guò)這個(gè)對(duì)象完成。
    image.png
  2. 繪制折線路徑
//canvas元素
var c=document.getElementById('mycanvas');
//context對(duì)象
var ctx=c.getContext('2d');
ctx.beginPath();
//①定義樣式
ctx.strokeStyle='green';        //顏色
ctx.lineWidth=20;               //線寬
ctx.lineCap='square';           //端點(diǎn)
ctx.lineJoin='round';           //拐點(diǎn)
//②定義路徑
ctx.moveTo(50,50);      //起點(diǎn)
ctx.lineTo(100,100);        //拐點(diǎn)
ctx.lineTo(50,200);     //終點(diǎn)
ctx.closePath();                //閉合
//③繪制
ctx.stroke();
image.png
  • canvas元素必須通過(guò)width、height設(shè)置寬高。重新設(shè)置widthheight,畫布中任何已繪對(duì)象都將被清除。
  • 每一個(gè)canvas元素僅有一個(gè)context對(duì)象,擁有多種繪制路徑、矩形、圓形、字符以及添加圖像的方法和屬性。
  • 定義樣式和定義路徑(位置尺寸)的相對(duì)位置可調(diào)整,但繪制必須在定義樣式和定義路徑(位置尺寸)之后,否則樣式和路徑無(wú)法生效。
  • 若未定義樣式,則為默認(rèn)樣式;若未修改樣式,則為上次樣式。
  1. 繪制其它路徑
//矩形路徑
//位置(50,20),尺寸(200,200)
ctx.rect(50,20,200,200);
//③繪制
ctx.stroke();

//原型路徑
//②定義位置尺寸
//中心點(diǎn)坐標(biāo)(100,70),半徑50,開始角180度,結(jié)束角0度,逆時(shí)針。
ctx.arc(100,70,50,Math.PI,0,true);
//③繪制
ctx.stroke();
  1. 繪制笑臉
ctx.clearRect(0, 0, 200, 200); // 擦除(0,0)位置大小為200x200的矩形,擦除的意思是把該區(qū)域變?yōu)橥该?ctx.fillStyle = '#dddddd'; // 設(shè)置顏色
ctx.fillRect(10, 10, 130, 130); // 把(10,10)位置大小為130x130的矩形涂色
// 利用Path繪制復(fù)雜路徑:
var path=new Path2D();
path.arc(75, 75, 50, 0, Math.PI*2, true);
path.moveTo(110,75);
path.arc(75, 75, 35, 0, Math.PI, false);
path.moveTo(65, 65);
path.arc(60, 65, 5, 0, Math.PI*2, true);
path.moveTo(95, 65);
path.arc(90, 65, 5, 0, Math.PI*2, true);
ctx.strokeStyle = '#0000ff';
ctx.stroke(path);
image.png
  1. 繪制圖片
var img = new Image()
img.src = src
img.onload=function(){
    //剪切位置(0,0),剪切尺寸(600,600),
    //放置位置(0,0),放置尺寸(100,100);
    ctx.drawImage(img,0,0,600,600,0,0,100,100);
}
image.png
  1. canvas動(dòng)畫
var walk = require('../assets/1.jpg');
var img=document.createElement('img');
document.body.appendChild(img)
img.src=walk
img.onload=function(){
    var x=0;
    setInterval(function(){
        ctx.clearRect(0,0,500,500);
        ctx.drawImage(img, x,0,180,400,0,0,180,400);
        x+= 180;
        if (x>=900) {
            x=0
        };
    },100)
};
  1. SVG vs canvas:如何選擇
對(duì)比 Canvas SVG
操作對(duì)象 基于像素 基于圖形元素
元素 單個(gè)HTML元素 多種圖形元素(Rect,Path,Line...)
驅(qū)動(dòng) 腳本驅(qū)動(dòng) 支持腳本和CSS
交互粒度 用戶交互到像素點(diǎn)(x, y) 用戶交互到圖形元素
性能 適合較小面積,較多的對(duì)象 適合較少的對(duì)象,較大的面積
image.png

2. react-konva

  1. react-konvareact-canvasgithub上星星比較多的react相關(guān)canvas第三方庫(kù)。由于react-canvas173月之后就沒(méi)有更新了,且不支持react 16,因此不再考慮。這里主要介紹react-konva的使用。
  2. React Konva是一個(gè)JavaScript庫(kù),用于使用React繪制復(fù)雜的畫布圖形。
  3. 基本概念
    把整個(gè)視圖看做一個(gè)舞臺(tái)stage。而舞臺(tái)中的每一層,看做layer。layer層中有許多group組。在group中繪制畫圖、圖片等shape。
               Stage
                |
         +------+------+
         |             |
       Layer         Layer
         |             |
   +-----+-----+     Shape
   |           |
 Group       Group
   |           |
   +       +---+---+
   |       |       |
Shape   Group    Shape
           |
           +
           |
         Shape
  1. 示例
import React, { Component } from "react";
import Konva from "konva";
import { render } from "react-dom";
import { Stage, Layer, Rect, Text } from "react-konva";

class ColoredRect extends React.Component {
  state = {
    color: "green"
  };
  handleClick = () => {
    this.setState({
      color: Konva.Util.getRandomColor()
    });
  };
  render() {
    return (
      <Rect
        x={20}
        y={20}
        width={50}
        height={50}
        fill={this.state.color}
        shadowBlur={5}
        onClick={this.handleClick}
      />
    );
  }
}

class App extends Component {
  render() {
    return (
      <Stage width={window.innerWidth} height={window.innerHeight}>
        <Layer>
          <Text text="Try click on rect" />
          <ColoredRect />
        </Layer>
      </Stage>
    );
  }
}

render(<App />, document.getElementById("root"));

參考

學(xué)習(xí)HTML5 Canvas這一篇文章就夠了
Konva入門教程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容