精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

PixiJS 源碼解讀:繪制矩形,底層都做了什么?

開發 前端
使用 PixiJS 簡單易用的 API,我們可以在瀏覽器頁面的 Canvas 元素上高性能地繪制圖形,實現流暢的動畫。它的底層是 WebGL。

大家好,我是前端西瓜哥,今天帶大家看一下 PixiJS 的源碼實現。

PixiJS 是一個非常流行的 Canvas 庫,start 數將近 4w。

使用 PixiJS 簡單易用的 API,我們可以在瀏覽器頁面的 Canvas 元素上高性能地繪制圖形,實現流暢的動畫。它的底層是 WebGL。

用 PixiJS 繪制一個矩形,代碼實現為:

const app = new PIXI.Application({
  width: 500,
  height: 300,
});
document.body.appendChild(app.view);

const graph = new PIXI.Graphics();
graph.beginFill(0xff0044); // 填充色
graph.drawRect(10, 10, 100, 80);
graph.endFill();

app.stage.addChild(graph);

渲染結果:

圖片

這些代碼的底層究竟做了什么呢?這次西瓜哥就帶大家來一探究竟。

使用的 PixiJS 版本為 7.2.4。

Application 的初始化

首先是調用 Application 類的構造函數,創建 app 對象。

下面是 Application 構造函數的代碼。

export class Application {
  // 創建 stage
  public stage: Container = new Container();
  // ...
  constructor(options) {
    options = Object.assign(
      {
        // 是否強制使用 Canvas 2D,否則如果支持 WebGL,用 WebGL
        // 默認為 false,且已經廢棄 Canvas 2D,僅 pixi.js-legacy 可用
        forceCanvas: false, 
      },
      options
    );
 
    // 選擇渲染器
    this.renderer = autoDetectRenderer(options);

    // 插件初始化
    Application._plugins.forEach((plugin) => {
      plugin.init.call(this, options);
    });
  }
}

主要做了以下幾件事。

  1. 初始化 this.stage 為一個新的 Container 對象,將其作為根容器,之后我們繪制的矩形會放置于其下。
  2. 選擇渲染器 renderer,有兩種:Renderer(基于 WebGL) 和 CanvasRenderer(基于 Canvas 2D)。最新版 PixiJS 只內置了  Renderer。如果你希望在 WebGL 不可用時回退為 CanvasRenderer,需要改用 pixie.js-legacy 庫。
  3. 調用 Renderer 的構造函數。它的屬性 view 會指向一個 canvas 元素,Application 的 view 通過 getter 的代理方式拿到這個 view。
  4. 調用 Application 中注冊插件的 init 方法,進行初始化。

Application 默認內置兩個插件:

  • TickerPlugin:不停地在繪制下一幀前調用(基于 requestAnimationFrame)傳入的回調函數,PixiJS 會在這里指定下一幀數要繪制的新內容。
  • ResizePlugin:監聽容器尺寸變化,重繪畫布。

圖片

創建圖形

const graph = new PIXI.Graphics();

創建一個 Graphics 對象。這個 Graphics 對象下可以繪制任何圖形,這里我只繪制一個矩形。

graph.beginFill(0xff0044); // 填充色

該方法會給 Graphics 對象的 _fillStyle 設置為指定的顏色值。傳入的顏色值會進行標準化(normalize)。

圖片

Pixijs 實現有自己的風格:喜歡用類似 _varX 的方法保存 “私有” 變量,然后提供對應的 setter 和 getter 去讀寫這個內部變量。

getter 可能不提供,這樣一個屬性就會變成只讀屬性。有些 getter 里會做懶加載,在第一次讀取的時候再初始化,比如 Texture.WHITE。

如果我們不指定顏色,這個 _fillStyle 會使用默認值,且其 visible 屬性為 false,表示圖形沒有填充色,也會在之后的渲染階段跳過填充的邏輯。

然后是創建一個矩形。

graph.drawRect(10, 10, 100, 80);

上面代碼其實調用的是:

return this.drawShape(new PIXI.Rectangle(x, y, width, height));

首先創建一個 Rectangle 對象。

然后基于該 Rectangle 對象、之前設置的 fillStyle、lineStyle、matrix 創建一個 GraphicsData 對象,最后添加到給 rect._geometry.graphicsData 數組上。

圖片

總之就是將這個矩形的數據記錄下來,之后 PixiJS 會基于這些值構造出繪制 WebGL 可以直接使用的數據。

然后是重置填充色。

rect.endFill();

將 rect 的 _fillStyle 設置為默認值:

public reset() {
  this.color = 0xFFFFFF;
  this.alpha = 1;
  this.texture = Texture.WHITE;
  this.matrix = null;
  this.visible = false;
}

最后是把 rect 添加到容器 app.stage 下。

app.stage.addChild(rect);

對應的源碼是:

export class Container extends DisplayObject {
  // ...

  addChild(...children) {
    if (children.length > 1) {
      // 有多個圖形要添加,會遍歷調用當前 addChild 方法
      for (let i = 0; i < children.length; i++) {
        this.addChild(children[i]);
      }
    } else {
      const child = children[0];
      if (child.parent) {
        child.parent.removeChild(child);
      }

      child.parent = this;
      this.sortDirty = true; // 表示沒有排序

      child.transform._parentID = -1;

      this.children.push(child);

      this._boundsID++;

      // 觸發子節點改變的相關事件
      this.onChildrenChange(this.children.length - 1); 
      this.emit("childAdded", child, this, this.children.length - 1);
      child.emit("added", this);
    }
    return children[0];
  }
}

至此,我們的矩形設置好屬性并添加到圖形樹上。

下面是渲染環節。

繪制

還記得我們初始化 Application 時,初始化的兩個插件嗎?

其中一個就是 TickerPlugin,它是 raf(requestAnimationFrame)的封裝,會在頁面繪制下一幀要之前執行回調函數。

Application 初始化時,調用了TickerPlugin.init() 方法,將 renderer 的 render 方法綁定到 Ticker 上。這樣,render 就會不斷地被異步調用。

class TickerPlugin {
  static init(options) {
    Object.defineProperty(this, "ticker", {
      set(ticker) {
        // 將 app.render 函數傳入 ticker 的回調列表
        ticker.add(this.render, this, UPDATE_PRIORITY.LOW);
      },
      // ...
    });
    
    // 觸發 ticker setter
    this.ticker = options.sharedTicker ? Ticker.shared : new Ticker();
  }
  // ...
}

render 方法:

class Application {
  // ...
  public render() {
    this.renderer.render(this.stage);
  }
}

因為渲染的過程非常長,代碼邏輯太多,各種細枝末節,這里只講大致流程,之后會寫一篇文章具體講解。

  1. 遞歸 app.stage 下的子 graph 對象,將其變換矩陣與父容器的做矩陣乘法(父容器的 transfrom 會影響子節點),最終計算出所有節點的最終復合變換矩陣;
  2. 之前創建的 Rectangle 對象,它的 x、y、width、height,轉換為 WebGL 頂點著色器(Vertex Shader)需要的 8 個頂點數據;
  3. 對頂點應用變換矩陣;
  4. 計算好的頂點和顏色的一些中間批量數據。最后在 BatchRenderer.drawBatches() 方法中,調用了  WebGL 的 API:gl.drawElements。

PixiJS 高性能的一個原因是減少 draw call,盡可能一次性批量(batch)提供大量頂點和片元給到 WebGL 去處理,充分利用 GPU 的并發計算能力。

責任編輯:姜華 來源: 前端西瓜哥
相關推薦

2023-10-09 07:49:33

PixiJSWebGL

2023-10-13 07:29:23

PixiJSRunner

2014-08-10 14:35:23

2021-08-06 22:45:09

人工智能AI

2021-01-03 10:37:50

前端開發技術

2023-06-08 08:16:33

TickerPixiJS

2014-11-12 00:01:29

京東

2019-05-14 09:18:18

程序員PythonJava

2017-06-26 14:52:45

微軟智能云合作

2014-03-26 14:23:36

Microsoft AWindows Azu微軟

2017-11-13 15:48:36

架構Spring Clou演進

2017-11-14 09:03:36

Spring Clou架構演進

2019-06-12 09:50:23

selectMySQLSQL

2022-07-29 09:12:14

Springservlet容器

2022-07-26 07:47:09

SpringMVC

2022-08-02 07:55:28

MVCJersey

2022-07-26 07:47:47

SpringMVC

2019-12-09 09:50:18

程序員技能開發者

2023-03-02 07:44:39

pixijsWebGL

2021-01-06 08:24:38

人工智能消費領域AI
點贊
收藏

51CTO技術棧公眾號

一区二区三区四区在线观看视频 | 国产精品一区二区电影| 亚洲久久久久久久| 99精品女人在线观看免费视频| 亚洲私人影院在线观看| 国产日韩欧美一区二区| 天天干天天色综合| 欧美福利影院| 亚洲视频在线观看视频| 在线成人精品视频| 亚洲天堂1区| 亚洲午夜激情网页| 亚洲国产欧洲综合997久久 | 亚洲国产天堂久久综合网| 国产精品欧美激情在线观看| 影音先锋男人资源在线| 91美女精品福利| 亚洲va男人天堂| 国产99久久久| 亚洲欧美亚洲| 综合欧美国产视频二区| 2一3sex性hd| av成人在线网站| 色综合久久九月婷婷色综合| 乱子伦一区二区| 国产一区二区三区福利| 丰满放荡岳乱妇91ww| 国产精品视频一区二区三区四| 久久久国产精华液| 天天揉久久久久亚洲精品| 亚洲精品中文字幕女同| 国产精久久久久| 99久久999| 在线免费观看不卡av| 青青草精品视频在线| 超碰在线观看免费版| 国产日韩欧美精品一区| 久久综合狠狠综合久久综青草 | 国产成人综合在线观看| 国产精品久久久久久久av电影| 日韩高清精品免费观看| 欧美片第1页综合| 久久色在线播放| 在线观看天堂av| 日韩精品1区| 最新的欧美黄色| 夜夜春很很躁夜夜躁| 亚洲午夜久久| 亚洲欧美国产高清va在线播 | 久久精品一区四区| 另类欧美小说| 三级毛片在线免费看| 9l国产精品久久久久麻豆| 成人激情av| 亚洲经典一区二区三区| 国产成人在线视频网址| 91久久精品国产91久久性色tv| 国产精品-色哟哟| 紧缚捆绑精品一区二区| 91久久国产精品91久久性色| 国产男男gay体育生白袜| 另类综合日韩欧美亚洲| 国产美女久久精品香蕉69| 中国一级片黄色一级片黄| 日韩电影免费在线| 国产精品最新在线观看| ,亚洲人成毛片在线播放| 精品一区二区三区免费播放| 一区二区三区四区激情| 日本一区二区三不卡| 成年午夜在线| 中文字幕日韩精品一区| 国产日韩欧美大片| 欧美aaa免费| 婷婷中文字幕综合| 国产在线观看福利| 成人在线视频免费看| 欧美性三三影院| 久久久久久久久久久久久久久国产| 综合久久伊人| 精品国产乱码久久久久久影片| 日本护士做爰视频| 国产欧美日韩在线观看视频| 怡红院精品视频| 亚洲欧美精品久久| 极品中文字幕一区| 日本午夜人人精品| 在线播放亚洲精品| 国产成人av一区二区三区在线| 国产欧美一区二区在线播放| 久久免费看视频| 自拍偷在线精品自拍偷无码专区| 久久国产午夜精品理论片最新版本| 在线播放高清视频www| 在线观看日韩精品| 男生和女生一起差差差视频| 天天做夜夜做人人爱精品| 中文字幕日韩免费视频| 久久精品视频久久| 日本女优在线视频一区二区| 国产精品一区二区a| jizz日韩| 亚洲mv大片欧洲mv大片精品| 色婷婷综合网站| 激情小说亚洲色图| 日韩在线激情视频| 国内精品福利视频| 国产精品99久久久久久久女警 | 国产精品美女在线| 成人免费视频国产| 国产精品护士白丝一区av| 成人毛片一区二区| 国产精品高清一区二区| 亚洲欧美日韩一区二区在线| 久久久全国免费视频| 日本不卡中文字幕| 免费不卡亚洲欧美| 日日夜夜天天综合入口| 欧美日韩免费不卡视频一区二区三区 | 久久久久久激情| 蜜臀91精品一区二区三区| 国产精品一区视频网站| 免费看美女视频在线网站| 欧美日韩精品二区| 国产一精品一aⅴ一免费| 99欧美视频| 国产精品高潮呻吟久久av无限| 日韩一级片免费观看| 一区二区三区成人| 99中文字幕在线| 久久看人人摘| 国产精品久久久av| 蜜桃视频在线观看视频| 激情久久av一区av二区av三区| 少妇性l交大片7724com| 99久久影视| 成人在线播放av| 尤物网址在线观看| 欧美亚洲国产怡红院影院| 老鸭窝一区二区| 国产亚洲精品自拍| 久久精品二区| 最近在线中文字幕| 亚洲精品网站在线播放gif| 日韩欧美一区二区一幕| 成人黄色一级视频| 成人黄色大片网站| a级日韩大片| 午夜免费在线观看精品视频| 国产自产一区二区| 午夜在线电影亚洲一区| av在线播放网址| 最新国产乱人伦偷精品免费网站| 懂色一区二区三区av片| 欧美大胆的人体xxxx| 欧美成人三级电影在线| 久久久久久久九九九九| 成人综合婷婷国产精品久久蜜臀 | 丝袜诱惑亚洲看片| 欧美三日本三级少妇三99| 欧美大电影免费观看| 精品小视频在线| 中文字幕天堂在线| 国产精品国产精品国产专区不片 | 91精品视频一区二区| 久久久91精品国产| 超碰在线播放97| 亚洲成人1区2区| 亚洲永久精品ww.7491进入| 日韩精品三区四区| 精品一区二区成人免费视频 | 91精品国产麻豆| 清纯粉嫩极品夜夜嗨av| av一本久道久久综合久久鬼色| jizzjizzxxxx| 久久精品播放| 不卡日韩av| 极品美女一区| 久久精品久久久久久| 亚洲精品国产精| 欧美性高潮床叫视频| 男人的天堂官网 | 国产精品一区二区三区久久久| 欧洲日本在线| 亚洲成人av中文字幕| 亚洲成熟少妇视频在线观看| 国产精品国产三级国产普通话三级 | 亚洲一区二区在线看| 人人九九精品视频| 情事1991在线| 成年视频在线观看| 亚洲欧美在线一区| 国产探花精品一区二区| 欧美日韩裸体免费视频| 91视频免费看片| 懂色av中文一区二区三区| 超碰影院在线观看| 午夜亚洲福利| 天天综合狠狠精品| 国产精品任我爽爆在线播放| 国产精品久久久久福利| 999福利在线视频| 日韩视频免费中文字幕| 天堂在线中文资源| 欧美久久一区二区| 日韩欧美三级视频| 亚洲免费电影在线| 国产真实乱人偷精品人妻| 丰满岳乱妇一区二区三区| 天天干在线影院| 亚洲神马久久| 在线视频一二三区| 欧美在线色图| 狠狠干一区二区| 看亚洲a级一级毛片| 国产精品狼人色视频一区| 超碰激情在线| 欧美激情aaaa| 在线观看男女av免费网址| 亚洲天堂免费视频| 头脑特工队2在线播放| 日韩三级精品电影久久久| 亚洲天堂国产精品| 91极品美女在线| 国产女同在线观看| 一级日本不卡的影视| 黑人狂躁日本娇小| 亚洲国产经典视频| 丁香激情五月少妇| 久久久噜噜噜久久中文字幕色伊伊| 国产高潮失禁喷水爽到抽搐 | 亚洲国产精品自拍视频| 国产成人综合精品三级| 手机av在线网站| 美女免费视频一区二区| 情侣黄网站免费看| 欧美亚洲三级| 韩国日本在线视频| 国产亚洲综合精品| 久久国产亚洲精品无码| 亚洲美女一区| 免费在线观看亚洲视频| 野花国产精品入口| 人人妻人人添人人爽欧美一区| 亚洲网站视频| 成人网站免费观看入口| 亚洲狠狠婷婷| 亚洲中文字幕无码专区| 亚洲黄色视屏| 黄色片一级视频| 久久综合狠狠| jizzzz日本| 精品制服美女丁香| 亚洲国产综合av| 丰满少妇久久久久久久| 日韩免费高清一区二区| 91片在线免费观看| www.av天天| 欧美激情一区三区| 日韩欧美123区| 亚洲综合激情网| 日韩精品久久久久久久| 精品久久久久久亚洲精品| 天天操天天摸天天干| 91久久精品一区二区三| 中文字幕观看视频| 日韩欧美中文字幕精品| 视频二区在线观看| 亚洲天堂成人在线视频| 免费观看成人高潮| 欧美国产日韩二区| 中文字幕高清在线播放| 国产精品揄拍一区二区| 日韩在线激情| 99电影在线观看| 欧美美乳视频| 中文字幕久久一区| 亚洲第一网站| 无码人妻精品一区二区三区66| 久久国产三级精品| 欧美xxxx黑人| 久久久99久久精品欧美| 三上悠亚作品在线观看| 亚洲成人免费电影| 中文字幕永久在线视频| 日韩美女在线视频| 麻豆影视在线| 欧美日韩xxxxx| 日日av拍夜夜添久久免费| 91传媒视频在线观看| 一道本一区二区三区| www.午夜色| 亚洲欧美日韩视频二区| 1314成人网| 国产欧美一区二区三区在线看蜜臀| 一区视频免费观看| 色国产综合视频| 精品人妻一区二区三区三区四区| 亚洲女同性videos| 日本高清成人vr专区| 日产精品99久久久久久| 无码国模国产在线观看| 水蜜桃亚洲精品| 国产日韩精品视频一区二区三区| 亚洲免费黄色网| 久久久综合视频| 国产亚洲精品久久久久久打不开| 欧美视频三区在线播放| 成人久久久精品国产乱码一区二区| 亚洲色图美腿丝袜| av在线私库| 亚洲一区二区三区乱码aⅴ蜜桃女| 亚洲最大在线| 国产精品久久久久9999爆乳| 美女视频黄频大全不卡视频在线播放| 完美搭档在线观看| 尤物av一区二区| 亚洲无码精品国产| 国产一区二区精品丝袜| 黄色aa久久| 成人自拍爱视频| 久久久久久久久国产一区| 青青草精品视频在线观看| 91网页版在线| 国产成人在线免费观看视频| 日韩欧美国产精品| 国产丝袜在线| 国产日韩欧美电影在线观看| 欧美精选视频在线观看| 欧美日韩在线中文| 99国产精品一区| 国产一级片网址| 欧美岛国在线观看| av毛片在线免费| 成人免费自拍视频| 欧美freesextv| 亚洲欧美aaa| 成人欧美一区二区三区黑人麻豆 | 日本午夜精品电影| 亚洲欧美网站| 大地资源二中文在线影视观看| 亚洲成人自拍网| 熟妇人妻中文av无码| 久久免费精品视频| 国产精品中文字幕制服诱惑| 日韩亚洲欧美视频| 91小视频在线观看| 午夜婷婷在线观看| 亚洲品质视频自拍网| 成人欧美大片| 日本在线播放一区| 日本视频免费一区| 91大神福利视频| 91麻豆精品国产91久久久更新时间| 3p视频在线观看| 成人在线一区二区| 欧美成熟视频| 无码国产69精品久久久久网站 | 1024av视频| 91蜜桃在线观看| 男人天堂视频网| 深夜福利一区二区| 美女久久精品| 日本香蕉视频在线观看| a在线欧美一区| 欧美精品一二三四区| 中文字幕欧美视频在线| 国产电影一区二区| av在线免费观看国产| 久久伊人中文字幕| 中文字幕在线观看高清| 欧美www在线| 日韩系列在线| 亚洲综合激情视频| 亚洲综合久久久| 国产日本在线观看| 91精品在线观| 亚洲另类黄色| 国产精品美女高潮无套| 制服丝袜亚洲精品中文字幕| 青青草视频在线免费直播| 久久久av水蜜桃| 久久99精品国产麻豆婷婷| a级黄色片免费看| 亚洲精品自拍第一页| av在线国产精品| 欧美 日韩 国产一区| 亚洲视频一区在线观看| 无码国产精品高潮久久99| 国产精品日韩在线播放| 欧美色图首页| 国产亚洲精品熟女国产成人| 日韩精品在线一区| 制服诱惑亚洲| 国产成人永久免费视频| 国产拍欧美日韩视频二区| 亚洲第一成年人网站| 国产精品久久不能| 亚洲三级毛片| fc2ppv在线播放|