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)容盲泛。
  • 說明canvas內(nèi)部是不可以嵌套其他dom結(jié)構(gòu)的濒持。
  1. CanvasRenderingContext2D對(duì)象
    所有的繪圖操作都需要通過這個(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元素必須通過width查乒、height設(shè)置寬高禽车。重新設(shè)置widthheight,畫布中任何已繪對(duì)象都將被清除蒋得。
  • 每一個(gè)canvas元素僅有一個(gè)context對(duì)象宁舰,擁有多種繪制路徑、矩形蓖议、圓形虏杰、字符以及添加圖像的方法和屬性。
  • 定義樣式和定義路徑(位置尺寸)的相對(duì)位置可調(diào)整勒虾,但繪制必須在定義樣式和定義路徑(位置尺寸)之后纺阔,否則樣式和路徑無法生效。
  • 若未定義樣式修然,則為默認(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月之后就沒有更新了,且不支持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)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市琉用,隨后出現(xiàn)的幾起案子堕绩,更是在濱河造成了極大的恐慌,老刑警劉巖邑时,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奴紧,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡晶丘,警方通過查閱死者的電腦和手機(jī)黍氮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來浅浮,“玉大人沫浆,你說我怎么就攤上這事」鲋龋” “怎么了专执?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)郁油。 經(jīng)常有香客問我本股,道長(zhǎng)攀痊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任痊末,我火速辦了婚禮蚕苇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凿叠。我一直安慰自己,他們只是感情好嚼吞,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布盒件。 她就那樣靜靜地躺著,像睡著了一般舱禽。 火紅的嫁衣襯著肌膚如雪炒刁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天誊稚,我揣著相機(jī)與錄音翔始,去河邊找鬼。 笑死里伯,一個(gè)胖子當(dāng)著我的面吹牛城瞎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播疾瓮,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼脖镀,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了狼电?” 一聲冷哼從身側(cè)響起蜒灰,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肩碟,沒想到半個(gè)月后强窖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡削祈,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年翅溺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片岩瘦。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡未巫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出启昧,到底是詐尸還是另有隱情叙凡,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布密末,位于F島的核電站握爷,受9級(jí)特大地震影響跛璧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜新啼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一追城、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧燥撞,春花似錦座柱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至冠胯,卻和暖如春火诸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荠察。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工置蜀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人悉盆。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓盯荤,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親舀瓢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子廷雅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354