日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

canvas 动画库 CreateJs 之 EaselJS(上篇)

發布時間:2023/12/10 javascript 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 canvas 动画库 CreateJs 之 EaselJS(上篇) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文來自網易云社區

作者:田亞楠


須知

本文主要是根據 createjs 中的 EaselJS 在 github 上的 tutorials 目錄下的文章整理而來 (原文鏈接),同時也包含了很多本人的理解,如過有敘述不當的地方,請聯系我 :-D?

本文對原文中的一些知識點的解釋進行了刪減,對另外一些進行了擴展,同時對文中的 demo 進行了改寫,如果感到閱讀困難的話請參考原文(本文中有對應的原文鏈接)

如果文中提供的 demo 無法打開,可以參考原文中的 demo。


從一個簡單例子開始

對應原文:Getting Started

EaselJS 類的結構:


我們把上圖所有的類都稱作「元件」

上圖列出了 createjs 的主要類結構,如圖可以得到如下信息:

  • 所有元件的基類都是 DisplayObject,所有元件都是一個構造函數(類)

  • Container 可以包含其他(任何)元件。由于它本身也是一個元件,所以不同的 Container 之間可以相互包含

  • 舞臺 Stage 是一個特殊的 Container ,也是一個 DisplayObject,它內部封裝了 canvas 對象

  • Sprite 元件用來表現幀動畫(類似 gif)

  • Bitmap 元件用來表現純靜態的圖片

  • Shape 元件用來表現矢量圖形,它的實例包含一個 Graphics 元件,用來描述圖形

  • Filter 和 Shadow 則是濾鏡分支,可以針對任意元件實現顏色變換、模糊、陰影等效果。 使用濾鏡的方式跟 Flash 一致,需要新建 Filter 實例,添加到目標元件的 FilterList 中,Createjs 框架在下一幀就會把該元件加上濾鏡效果

  • 另外圖中沒有畫的元件還有:Text 元件用來表現文本、DOMElement 元件用來控制 HTML DOM 元素


  • 在一個應用中,各個元件類的實例之間的關系類似下面這張圖:



    每個類都有各自的靜態方法,如:createjs.Ticker.setFPS(20) ,同時也可以用來初始化一個對象,如:new createjs.Stage('myCanvas')


    參考:

  • 博客園 kenkofox 的文章

  • API doc


  • Container 容器

    如果不太好理解,可以先大概看一看,對閱讀后面的部分沒有影響

    首先所有可以繪制到畫布上的對象(圖形、圖片等)都稱作「顯示對象」,而「容器」可以容納一個顯示對象列表。

    例如你可以將頭、四肢、軀干 3 個顯示對象容納到一個 person 容器中,通過:

    //var?head?=?..,?body?=?..,?arm?=?..//實例化一個容器對象var?person?=?new?createjs.Container();//將顯示對象放入容器中person.addChild(head,?body,?arm);

    這樣你可以將 person 對象作為一個整體進行圖形變換,也可以單獨的將每一部分進行圖形變換。即人可以整體向前移動,而他的頭部也可以同時左右擺動。


    Stage 舞臺

    舞臺(Stage)對象指向我們的 canvas 元素 ,它是一個特殊的 Container 對象,它包含了所有我們希望繪制到 canvas 上的圖形/圖片,即 任何一個希望展示在畫布上的圖形/圖片都必須包含在 Stage 對象中。

    例如一個圖形 s1 希望繪制到 canvas 上,則必須先 stage.addChild(s1

    Stage 對象的實例化過程入下:

    <canvas?id=canvasId?width=400?height=400></canvas>//...?balabala?...//參數為?canvas?id?或者?canvas?DOMElementvar?stage?=?new?createjs.Stage('canvasId');


    Shape

    shape 對象幫助我們在 canvas 上繪制矢量圖形(vector graphics)

    注:canvas 繪制的圖形都是位圖,createjs 應該是通過計算繪制出類似矢量圖的效果

    shape 對象有一個 graphics 屬性,它指向一個 Graphics 實例,它擁有所有有關定義矢量圖形的方法。

    所有「顯示對象」(可以在畫布上看到的對象,類似 shape 矢量圖形),都擁有統一的 位置 和 圖形變換 屬性,如 x y(位置屬性)、rotation(旋轉屬性)、scaleX scaleY(縮放屬性)等。

    繪制一個紅色的圓形,如下:

    var?circle?=?new?createjs.Shape();//紅色的半徑為50的圓形,它位于(0,?0)點坐標//?-?注意:(0,?0)點是相對于?circle?對象來說的,是相對坐標circle.graphics.beginFill("red").drawCircle(0,?0,?50);//所有「顯示對象」通用的「位置」屬性circle.x?=?100; circle.y?=?100;//只有添加到?stage?舞臺之后,才可以顯示stage.addChild(circle);//返回值為?circle?本身

    以上代碼也可以簡寫如下:

    stage.addChild(new?createjs.Shape()).set({x:?100,?y:?100}).graphics.f('red').dc(0,?0,?50);


    update

    雖然我們已經將 circle 矢量圖添加到 stage 的顯示列表中了,但只有我們在 update 之后才會繪制到 canvas 上。

    stage.update();

    update 函數會先將畫布清空(通過 clearRect ),然后執行 stage 中所有 children 的繪制方法,最終將他們繪制在畫布上。

    最終的 DEMO


    動畫 & Ticker

    對應原文:Animation and Ticker


    動畫基礎

    canvas 2d 的原生基本動畫實現請參考另一篇文章的第一部分:canvas 學習總結

    除了直接使用 setTimeout、requestAnimationFrame 等方法,以某個固定間隔循環以實現動畫效果之外,createjs 還提供了 Ticker 類用來更方便實現動畫效果。

    使用 Ticker ,你可以暫停,或修改循環頻率。還可以有選擇的使用 setTimeout 或 requestAnimationFrame。

    Ticker 是 createjs 上的靜態接口,不需要 new instance。

    默認幀率為 20FPS。有 3 種修改方法:

    //方法一:createjs.Ticker.setFPS(40);//方法二:createjs.Ticker.framerate?=?40;//方法三:單位?ms,(修改的是時間間隔?regular?interval)//?-?25ms?與前兩個方法等價,因為:1000ms?/?25ms?=?40fpscreatejs.Ticker.interval?=?25;

    基本使用:

    //?on?也可以改成?addEventListener。用來監聽?tick?事件(最終綁定在?window?對象上)createjs.Ticker.on('tick',?function(event){circle.x?+=?5;stage.update(event); });

    參考:DEMO;


    基于時間的動畫(而非刷新頻率)

    問題

    請耐心看完 :z

    ?

    使用 requestAnimationFrame 的動畫都存在一個問題,當運行在性能較差的設備上的時候,瀏覽器的刷新頻率會降低。

    如果動畫的位移是根據頻率計算的。也就是說:我們是根據頻率(假設為 60fps)計算的每一次循環的時間間隔,假設為 1000 / 60 = 16.667 毫秒,即一次循環時間間隔為 16.667 毫秒, 然后可以通過這個時間得出對應的位移量:

    假設我們希望小球 1秒 位移 500px,那么 16.667ms 需要位移 500/60 = 8.333px,由此計算出位移量為 8.333px。

    那么當瀏覽器的刷新頻率降低,我們預期的 60fps 沒有達到,可能變為 40fps ,那么每次循環時間間隔變為 1000 / 40 = 25ms, 因為我們設置的每次循環的位移量還是 8.333px,那么 1s 的位移量就變為了 333.333px,其結果就是在看起來小球的移動速度降低了。

    另外,在代碼中動態修改設置的 FPS 值的時候,所有的位移值都需要重新計算,也會遇到上述問題。


    解決

    Ticker 可以將動畫與幀率解耦,通過保證動畫的執行是基于時間(而非頻率), 來實現動態的改變FPS(無論是因為設備性能差,還是代碼中進行了修改)時不會影響動畫的速率。

    也就是說,「位移量」取決于時間,而不是變來變去的幀率。當幀率下降的時候,每次循環中的位移量會相應變大。

    它的實現方式很簡單:
    在 tick 事件的回調函數的中增加參數 delta。 delta 的值是上一次觸發 tick 事件到現在(兩次 tick 事件之間)的時間間隔。如果代碼運行在一個性能很差的設備上時,delta 的值將明顯比預期的 1000/FPS 大。 我們可以根據 delta 來計算當前 tick 的位移。

    var?fps?=?60; createjs.Ticker.setFPS(fps);createjs.Ticker.on('tick',?function?(evt)?{????//?為方便計算,循環體中的所有位移,均認為是?1s?中的位移,只要乘以?delta?參數,即可得到真正的位移//??-?「真實時間」相對于?1000ms?「縮放」的倍數evt.delta?=?evt.delta?/?1000;????//?500?表示位移速度為:500px/s,所有的位移均乘以?delta?縮放倍數,換算成「真實時間」的位移circle.x?+=?500?*?evt.delta;????//...其他代碼stage.update(evt); });

    參考:DEMO,在例子中,切換幀率不影響小球的運動速率

    注意:必須在 update 的時候將 evt 作為參數傳入 stage.update(evt);,才能正確的獲取 evt.delta 值

    另外 Ticker 還會暴露一個 getTime 方法,可以獲取到從 Ticker 初始化(監聽 tick 事件開始)到現在的總時間。

    createjs.Ticker.getTime();

    同時,使用精靈圖實現 gif 圖片效果的時候,也可以使用基于時間的動畫。涉及API:Sprite、SpriteSheet等。


    TIMING MODE

    較新的瀏覽器都開始支持 requestAnimationFrame, 它能帶來很多好處,包括動畫的平滑運行、減少 CPU 和電量的消耗等。 然而 createjs 默認不啟用它,而是使用 setTimeout。

    我們可以通過 Ticker.timingMode 來啟用 requestAnimationFrame。

    它的默認值為 Ticker.TIMEOUT 從而使用的 setTimeout ,它兼容所有瀏覽器,并提供了可預期的、靈活的幀率(見上一小節), 然而拋棄了 requestAnimationFrame 的各種好處。不過你可以通過減少幀率來降低 CPU/GPU 的消耗。

    有兩種模式可以啟用 requestAnimationFrame,它們都會在瀏覽器不支持 requestAnimationFrame 的時候,自動回退到 setTimeout:

  • Ticker.RAF 模式會單純的使用 RAF ,忽略掉設置的幀速率等值(3種設置幀率的方式全部失效)。
    因為 RAF 的頻率是不確定的(由瀏覽器和當前運行環境決定)。如果使用了這種模式,建議一定要使用前面提到的「基于時間的動畫」來確保動畫速率的一致。


  • Ticker.RAF_SYNCHED 模式試圖協調 RAF 和你設置的幀率,這種方式結合了 setTimeout 和 RAF 的優點, 但會在幀周期中造成極大的差異(無法理解原文的含義),因此這種模式在幀率為 60 的因子時運行的最好,如:10、12、15、30、60。


    createjs.Ticker.timingMode?=?createjs.Ticker.RAF_SYNCHED; createjs.Ticker.framerate?=?30;


    暫停

    所有的 Ticker 都是可以暫停的,如果設置

    Ticker.paused?=?true;//或者createjs.Ticker.setPaused(true);

    那么 createjs.Ticker.getPaused() 的返回值為 true,在循環 tick 中,我們可以通過這個返回值判斷需要跳過執行的代碼:

    function?tick?(evt){????if(!createjs.Ticker.getPaused()){????????//...這段代碼當?paused?的時候不會執行}stage.update(evt); }

    另外,createjs.Ticker.getTime(true) 返回除去暫停的時間的真正運行的總時長。

    參考:DEMO


    Tick

    當調用 stage.update(event) 方法的時候,每一個 stage 的 children 都會觸發它本身暴露的 tick 事件。

    通過這些 children 的 tick 事件,我們可以靈活的處理每一個顯示對象,且上下文為它本身:

    //原來的寫法createjs.Ticker.on('tick',?function?(evt)?{circle.x?+=?5;stage.update(evt); });//現在可以寫成createjs.Ticker.on('tick',?function?(evt)?{stage.update(evt);?//會觸發?circle?的?'tick'?事件}); circle.on('tick',?function(){?this.x?+=?5?});?//上下文為?circle


    性能

    注意高的幀率不一定意味著更好的流暢度,較低的幀率會減少 CPU/GPU 的使用,并提供始終如一的體驗。 請為你的項目選擇一個適合的幀率。

    可以通過 createjs.Ticker.getMeasuredFPS() 獲取到過去一秒鐘的平均幀率。
    或者通過 createjs.Ticker.getMeasuredTickTime() 獲取到過去一秒鐘,每一次 tick 循環的平均時間

    如果 getMeasuredFPS 接近設定的 FPS 值,說明性能良好。

    getMeasuredTickTime 的值表示一次循環中,執行動畫函數消耗的時間, 比 1000 / fps 越小,說明在一次循環中有更多的時間冗余,剩余更充足的時間提供給瀏覽器進行渲染等其他工作。

    參考:DEMO


    TWEENJS

    通過緩動函數創建動畫或動畫序列。

    createjs.Tween.get(txt).to({x:300},?1000).to({x:0},?0).call(onAnimationCompleteFn);


    文本

    有關字體的一點知識

    如果瀏覽器無法再本機中找到 css 要求的字體,那么會自動匹配類似的字體(主要是英文),如下:

    serif,襯線體,在字的主要線條后面會有一個小尾巴,常見:Georgia、Times、Times New Roman

    sans-serif,無襯線體,沒有小尾巴更清爽,常見:Arial、Verdana、Helvetica

    monospace,等寬字體,顧名思義(反義:non-monospace),常見:Courier、Courier New

    cursive,手寫體,例如:Comic Sans、Monotype Corsiva

    fantasy,裝飾用的字體,常用來表示標題等少量文本,不適宜文章主體使用,例如:Impact、Haettenschweiler


    展示文本

    var?text?=?new?createjs.Text("Hello?World",?"bold?86px?Arial",?"#ff7700");

    或者:

    var?text?=?new?createjs.Text(); text.text?=?"Hello?World!"; text.font?=?"bold?96px?Dorsa"; text.color?=?"#000000";

    其他的參數還有:(與 canvas 2d 中 context 關于文本的屬性含義相同)

    text.lineHeight?=?15; text.textAlign?=?'center'; text.textBaseline?=?'top';

    初始化的第二個參數,跟 css 中 font 的格式完全一致。

    另外如果要顯示在畫布上,不要忘記寫:

    stage.addChild(text); stage.update();

    還是上一個DEMO


    網易云免費體驗館,0成本體驗20+款云產品!?

    更多網易研發、產品、運營經驗分享請訪問網易云社區。


    ? ?


    相關文章:
    【推薦】?責任鏈模式的使用-NettyChannelPipeline和MinaIoFilterChain分析
    【推薦】?防不勝防這些游戲被外掛活生生地毀了
    【推薦】?Kylin性能調優記——業務技術兩手抓

    轉載于:https://www.cnblogs.com/163yun/p/9717314.html

    總結

    以上是生活随笔為你收集整理的canvas 动画库 CreateJs 之 EaselJS(上篇)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。