動態條漫實戰

前言

不知道你有沒有見過這種typescript

或者api

以上兩案例來自於網易噠噠團隊開發的爆款H5markdown

這種條漫形式的H5是否是帶給你們眼前一亮的感受,這篇文章主要帶你們揭祕如何製做這種動態條漫框架

你們能夠掃碼體驗條漫:工具

框架選型

在進入內容介紹前,先來介紹一下框架選型,爲何選擇了Egret引擎來作動態條漫oop

why Egret開發工具

從上面的一張主流遊戲框架引擎對照表,能夠很明顯的找到Egret相對於其餘遊戲動畫引擎的優勢:動畫

  • 渲染模式上更加普遍
  • 支持中英文檔,案例充足
  • 周邊產品豐富,提供一套完整的開發工具
  • 社區活躍

工具流ui

動畫基礎知識回顧

在Egret中動畫主要分爲三類:this

  • 逐幀動畫
    • 在時間幀上逐幀繪製幀內容,每一幀帶有不一樣的圖
    • 適用於表演很細膩的動畫
    • 有很是大的靈活性,表現任何想表現的內容
    • 逐幀動畫輸出文件較大
  • 補間動畫
    • 只需第一個關鍵幀和最後一個關鍵幀建立內容,兩個關鍵幀之間幀的內容自動生成
    • 過渡更爲天然連貫
    • 補間動畫輸出文件較小
  • 龍骨動畫
    • 模擬骨骼運動的機制而製做的動畫
    • 實現原理與補間動畫同樣,添加初始關鍵幀,結束關鍵幀
    • 增長了骨骼約束

在Egret中建立逐幀動畫和補間

在Egret周邊工具中經過Egret DragonBones生成動畫

製做逐幀動畫

步驟:

  • 打開DragonBones工具,點擊建立項目
  • 選擇逐幀動畫,點擊建立
  • 資源面板,導入逐幀資源,將圖片拖入畫布中
  • 調整圖片順序,幀頻

製做補間動畫

步驟:

  • 打開DragonBones工具,點擊建立項目
  • 選擇補間動畫,點擊建立
  • 資源面板,導入逐幀資源,將圖片拖入畫布中
  • 在指定幀,選擇圖片位置,結束幀,圖片到結束位置

動態條漫實現思路

核心思路

一圖勝千文

動畫原理

  • 大部分動畫都是,補間動畫+逐幀動畫的混合
  • 全部動畫都放在時間軸上按照先按照滑動的順序移動變化。
  • 只須要經過用戶滑動,改變更畫播放的幀數便可
  • 接二連三的滑動便可,實現條漫形式的動畫

看完上面的動畫分析,下面咱們注重要解決的即是:

  • 如何控制動畫按照咱們預期的形式播放
  • 在動畫播放到指定幀時,播放音效
  • 如何實現慣性滾動

滑動控制

原理

  • 在動畫場景上蓋上蒙層
  • 監聽蒙層滾動事件,蒙層滾動的距離來切換動畫的幀數

對應Api

核心步驟:

  • 獲取龍骨資源、並建立dragonBones實例對象。將龍骨場景對象添加至畫布
  • 構建一個滾動容器,容器的高度爲視窗大小,設置寬度設置爲視窗寬度
  • 在滾動容器中內增長蒙層,蒙層的高度=總的幀數 * 滾動一幀的距離 * 時間縮放 + 視窗高度
  • 建立eui.scroller對象,將其設置爲視窗大小,設置滾動容器對象爲eui.scroller的視域組件組件
  • 使用eui.scroller監聽滾動高度,計算當前滾動條佔總可滾動高度的百分比=已滾動高度/(蒙層高度-視窗高度)
  • 獲取dragonBones場景一共擁有多少幀,經過總幀數*當前百分比,獲得用戶滑動到當前所在幀數

具體實現代碼:

private timeScale: number = 2;  // 時間縮放倍數,爲2時代表幀數切換放慢兩倍
private frameFactor: number = 26; // 滾動一幀須要耗費的距離
private totalFrames: number = 1672; // 總得幀數
private totalPrgress: number = this.timeScale * this.frameFactor * this.totalFrames; // 總的滾動長度
private dragonBones: Common.DragonParse; // 獲取動畫
private music: Common.Music;
private audioKeys: audioKey[] = [{
    start: 98,
    end: 138,
    key: 'audio_sewing_mp3', // 縫紉機
    isPlayed: false,
    shouldStop: true,
    isLoop: false,
    volume: 1
}];

constructor () {
    // 龍骨腳手架中已添加COMMON公共方法,用來解析龍骨資源
    this.dragonBones = Common.DragonParse.getDragonParseInstance();
    this.egretFactory = this.dragonBones.getEgretFactory();
    
    // 獲取龍骨資源
    this.armatureDisplay = this.egretFactory.buildArmatureDisplay('listen_mother');
    this.addView();
}

private addView () :void {
   // 獲取視窗寬、高
   const { stageWidth, stageHeight } = this.stage;
   
   // 建立滾動容器和填充塊
   const group = new eui.Group();
   const placeHolder = new eui.Group();

   placeHolder.width = stageWidth;
   placeHolder.height = this.totalPrgress + stageHeight;
   group.addChild(placeHolder);

   //建立一個Scroller
   this.scroller = new eui.Scroller();
   this.scroller.bounces = false;
   this.scroller.width = stageWidth;
   this.scroller.height = stageHeight;
   // 將group做爲滾動的視域組件
   this.scroller.viewport = group;
   this.addChild(this.scroller);
   
   // 監聽滾動變化
    this.scroller.addEventListener(egret.Event.CHANGE, this.onScroll, this);
    
}

private onScroll () :void {
   // 獲取滾動距離,並計算滾動百分比
   const scrollV: number = this.scroller.viewport.scrollV;
   const progress: number = scrollV / this.totalPrgress;
   let curRateValue = ~~(this.totalFrames * progress);

   this.setSwipeAndButton(curRateValue);
   this.prevFrames = curRateValue;
   
   // 將設置龍骨動畫播放到指定幀數
   this.setProgress(progress);
   // 播放指定音效
   this.setMusic(progress)
}

private setProgress (progress: number) :void {
   this.armatureDisplay.animation.gotoAndStopByProgress(this.animationName, progress)
}

private setMusic(curRateValue: number): void {
    this.audioKeys.forEach((item) => {
        if (curRateValue >= item.start && curRateValue <= item.end) {
            if (!item.isPlayed && !this.musicIsMuted) {
                this.music = Common.Music.getMusic(item.key);
                this.music.play(0, item.isLoop ? 0 : 1);
                this.music.setVolumn(item.volume);
                item.isPlayed = true;
            }
        } else {
            if (item.isPlayed) {
                item.shouldStop && this.music.stop();
                item.isPlayed = false;
            }
        }
    });
}
複製代碼

一屏動畫設計原則

  • 構建一個基本場景骨架,後續骨架放置基本骨架上,方便總體移動
  • 物件退場須要與背景反方向運動,形成錯落感。或順方向退場,避免致使認爲物品或人與背景不分離
  • 龍骨動畫設計時以最小十幀爲單位,場景轉換預留30~50幀,後續方便調整
  • 幀動畫設計圖片以致少三幀不一樣動畫,能夠形成連續感
  • 開始龍骨動畫製做前,先肯定好場景高度和寬度不會有大的變化,不然後續修改會形成總體調整
  • 文字動畫放置物品後
  • 動畫效果放置980像素內,不然在小屏幕手機上沒法展現全面
  • 幀動畫切換中間過分銜接透明度變化

若是以爲本文還不錯,不要吝嗇您的贊哦~

相關文章
相關標籤/搜索