iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0

先上demo:
Animation Easing | Fabric.js Demos (fabricjs.com)
animation demo
fabric.js 使用物件的方式來控制,可以讓新增動畫的方式變得很容易,所有要讓物件動的設定,透過 animate() 直接加在物件本體上就好。

基本動畫

Fabric.js 提供了簡單易用的動畫 API,可以輕鬆地為畫布上的對象添加動畫效果。概念跟 css 的 animation 很像,可以對物件的外觀大小、位置、顏色做變化。

基本動畫主要通過在 Canvas.Object 上使用 animate() 方法實現:

object.animate(property, value, options);

參數說明:

  1. property: 要進行動畫的屬性名稱(如 'left', 'top', 'opacity' 等)
  2. value: 動畫結束時該屬性的目標值
  3. options: 一個可選的配置對象,用於設置動畫的詳細參數

options 對象可以加上以下屬性:

  • duration: 動畫持續時間(毫秒)
  • onChange: 每次屬性變化時調用的回調函數
  • onComplete: 動畫完成時調用的回調函數
  • easing: 緩動函數,控制動畫的速度變化

property 可填入的屬性

項目類別 屬性
位置相關 left, top, angle (旋轉角度)
尺寸相關 width, height, scaleX, scaleY
外觀相關 opacity, fill (填充顏色), stroke (邊框顏色), strokeWidth (邊框寬度)
變形相關 skewX, skewY
陰影相關 shadow.offsetX, shadow.offsetY, shadow.blur, shadow.color
邊框相關 rx (矩形圓角半徑,x方向), ry (矩形圓角半徑,y方向)
文本相關(適用於 Text 對象) fontSize, fontWeight, letterSpacing
漸變相關 fill.coords.x1, fill.coords.y1, fill.coords.x2, fill.coords.y2, fill.colorStops[0].offset, fill.colorStops[1].offset, 等
路徑相關(適用於 Path 對象) path[0][1], path[1][1], 等 (改變路徑的具體點)

easing: 緩動函數可填入項目

這些 easing 函數都在 fabric.util.ease 對象中定義。

Easing 函數名 描述
easeInQuad 二次方緩入
easeOutQuad 二次方緩出
easeInOutQuad 二次方緩入緩出
easeInCubic 三次方緩入
easeOutCubic 三次方緩出
easeInOutCubic 三次方緩入緩出
easeInQuart 四次方緩入
easeOutQuart 四次方緩出
easeInOutQuart 四次方緩入緩出
easeInQuint 五次方緩入
easeOutQuint 五次方緩出
easeInOutQuint 五次方緩入緩出
easeInSine 正弦緩入
easeOutSine 正弦緩出
easeInOutSine 正弦緩入緩出
easeInExpo 指數緩入
easeOutExpo 指數緩出
easeInOutExpo 指數緩入緩出
easeInCirc 圓形曲線緩入
easeOutCirc 圓形曲線緩出
easeInOutCirc 圓形曲線緩入緩出
easeInElastic 彈性緩入
easeOutElastic 彈性緩出
easeInOutElastic 彈性緩入緩出
easeInBack 回退緩入
easeOutBack 回退緩出
easeInOutBack 回退緩入緩出
easeInBounce 彈跳緩入
easeOutBounce 彈跳緩出
easeInOutBounce 彈跳緩入緩出

實際例子

製作一個讓紅色矩形在1秒內,從左邊100px的位置移動到300px的位置,使用彈跳效果,並在動畫結束時印出 'Animation completed'

rect.animate('left', 300, {
  duration: 1000,
  onChange: canvas.renderAll.bind(canvas),
  onComplete: function() {
    console.log('Animation completed');
  },
  easing: fabric.util.ease.easeOutBounce
});

複雜動畫

對於更複雜的動畫效果,Fabric.js 提供了更高級的功能:

1. 動畫鏈:

可以將多個動畫串聯在一起,實現連續的動畫效果。

rect.animate('left', 500, {
  onChange: canvas.renderAll.bind(canvas),
  duration: 1000
}).animate('top', 500, {
  onChange: canvas.renderAll.bind(canvas),
  duration: 1000
});

2. (🌟🌟🌟實用) 自定義動畫 fabric.util.animate :

那你可能會問,如果我想要我的物件會同時從圓形變成方形、向左移、顏色從紅色變藍色,要怎麼做?以上的方式都能一次執行一種屬性的變動?

那你可以使用 fabric.util.animate 來創建自定義動畫。
這個方法提供了更靈活的動畫控制,讓我們可以同時改變多個屬性或創建更複雜的動畫效果。

他的架構跟 animate() 有點相似,但多了起始值與結束值,讓你可以跑畫面的迴圈,並且讓你可以對不只一個物件作用。

fabric.util.animate({
  startValue: startValue,
  endValue: endValue,
  duration: duration,
  onChange: function(value) {
    // 在這裡更新對象的屬性
  },
  onComplete: function() {
    // 動畫完成後的回調
  },
  easing: easingFunction
});

參數說明:

  • startValue: 起始值
    這是動畫開始時的值(迴圈起始值)。通常是一個數字,代表動畫的起點。
    例如,如果你要讓物體從左到右移動,這可能是起始的 x 坐標。
  • endValue: 結束值
    這是動畫結束時的值(迴圈起始值)。同樣通常是一個數字,代表動畫的終點。
    繼續上面的例子,這可能是物體最終要到達的 x 坐標。
  • duration: 持續時間
    動畫的持續時間,以毫秒為單位。
    例如,1000 表示動畫將持續 1 秒。
  • onChange: 變化時的回調函數
    這是一個函數,在動畫過程中持續被調用。
    它接收一個參數 value,這個 value 是一個從 startValue 到 endValue 之間的插值。
    在這個函數中,你通常會更新對象的屬性,實現動畫效果。
  • onComplete: 完成時的回調函數
    這是一個函數,在動畫完成後被調用一次。
    你可以在這裡執行一些動畫結束後的操作,比如開始下一個動畫或更新某些狀態。
  • easing: 緩動函數
    這決定了動畫的變化速率。

概念上,把以上參數寫成 for 迴圈會長這樣:

for(let value = startValue; value <= endValue; value ++){
    onChange(value) //做每一次變動畫面要做的事
}

實際例子:

這個例子會同時改變矩形的位置和旋轉角度

var rect = new fabric.Rect({
  left: 100,
  top: 100,
  width: 50,
  height: 50,
  fill: 'red'
});

canvas.add(rect);

fabric.util.animate({
  startValue: 0,
  endValue: 100,
  duration: 1000,
  onChange: function(value) { //迴圈起始的 value 會從上面設定的 startValue 開始,在 endValue 時結束
    rect.set({
      left: 100 + 200 * value,
      top: 100 + 100 * value,
      angle: 360 * value
    });
    canvas.renderAll(); // 每次畫面更變時重新渲染畫布
     //每做完一次 value +1
  },
  onComplete: function() {
    console.log('Animation completed');
  },
  easing: fabric.util.ease.easeInOutQuad
});

3. 群組動畫:

可以同時為多個對象添加動畫效果。一整組一起動。

fabric.util.animate({
  duration: 1000,
  onChange: function(value) {
  // 會需要寫迴圈讓每個群組內物件都被處理到
    group.getObjects().forEach(function(obj) {
      obj.set('opacity', value);
    });
    canvas.renderAll();
  },
  onComplete: function() {
    console.log('Animation completed');
  },
  startValue: 0,
  endValue: 1
});

4. 路徑動畫:

可以讓對象沿著特定的路徑移動。

var path = new fabric.Path('M 0 0 L 300 100 L 200 300 z');
var startPoint = path.getPointAtLength(0);
var endPoint = path.getPointAtLength(path.getTotalLength());

rect.animate('left', endPoint.x, {
  duration: 2000,
  onChange: canvas.renderAll.bind(canvas),
  onComplete: function() {
    console.log('Animation completed');
  },
  easing: function(t, b, c, d) {
    var point = path.getPointAtLength(t * path.getTotalLength());
    rect.set('top', point.y);
    return fabric.util.ease.easeInOutQuad(t, b, c, d);
  }
});

這些動畫效果可以組合使用,創造出更加複雜和吸引人的視覺效果。
Fabric.js 的動畫系統非常靈活,讓我們可以用很能夠滿足各種動畫需求。


延伸想法:

mouse over 動畫例子

其實也可以使用滑鼠事件來觸發動畫

mouse over demo
grow-shrink animation using FabricJS
---from Create grow/shrink animation using FabricJS | by Mandev | Medium


上一篇
Day14-畫布背景處理:設置和操作畫布背景(前景圖背景圖)
下一篇
Day16-fabric.js 進階組合技!自定義控件開發 (control) 實例
系列文
一起來玩圖像編輯器:Fabric.js 的實戰修煉30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言