JavaScript >> Javascript 文檔 >  >> Tags >> API

JavaScript Web 動畫 API 入門

向 Web 界面添加動畫可以使頁面和應用程序感覺更具響應性和交互性。平滑滑出視圖的側邊菜單提供了比關閉時消失的菜單更好的用戶體驗。

到目前為止,創建 Web 動畫是通過 CSS 過渡、CSS 關鍵幀或外部庫(如 Animate.css 或 Velocity)完成的。多虧了新的原生 JavaScript API,我們現在可以自由地為任何 HTML 元素製作動畫,而無需離開我們的 .js 文件。

創建動畫

為了展示新 API 的精彩之處,讓我們構建一個超級簡單的示例,先是老式的 CSS 方式,然後是 JavaScript Web Animations。

下面的編輯器包含兩個 HTML div,單擊它們時向右移動,然後更改它們的顏色。正方形通過 CSS 代碼>@keyframes 進行動畫處理,圓形通過 Web Animations API 進行動畫處理。

<h4>Click on the shapes to animate them.</h4>

<p>CSS keyframes</p>
<div id="square"></div>

<p>JS Web Animation API</p>
<div id="circle"></div>
#square,
#circle {
    width: 100px;
    height: 100px;
    margin: 10px 10px 30px;
    background-color: #2196F3;
}

#circle {
    border-radius: 50%;
}

.animate {
    animation-name: move-and-change-color;   
    animation-duration: 0.4s;
    animation-fill-mode: forwards;
}

@keyframes move-and-change-color {
    0% {
        transform: translateX(0);
    }

    80% {
        transform: translateX(100px);
        background-color: #2196F3;
    }

    100% {
        transform: translateX(100px);
        background-color: #EF5350;
    }
}
var square = document.getElementById('square');

square.addEventListener('click', function() {
    square.className += " animate";
});

var moveAndChangeColor = [
    { 
        transform: 'translateX(0)',
        background: '#2196F3'    // blue
    },
    { 
        offset: 0.8,
        transform: 'translateX(100px)', 
        background: '#2196F3'    // blue
    },
    {
        transform: 'translateX(100px)',
        background: '#EF5350'    // red
    }
];

var circle = document.getElementById('circle');

circle.addEventListener('click', function() {
    circle.animate(moveAndChangeColor, {
        duration: 400,
        fill: 'forwards'
    });
});

代碼>@keyframes 動畫對於大多數開發者來說應該很熟悉,所以讓我們先來看看。

CSS 方法

我們的 CSS 動畫在 code>@keyframes 塊中定義,該塊代表所有轉換的時間線。一旦我們定義了我們的編排,我們可以通過動畫屬性和它的選項將它映射到一個選擇器。

.animate {
    animation-name: move-and-change-color;   
    animation-duration: 0.4s;
    animation-fill-mode: forwards;
}

@keyframes move-and-change-color {
    0% {
        transform: translateX(0);
    }

    80% {
        transform: translateX(100px);
        background-color: #2196F3;
    }

    100% {
        transform: translateX(100px);
        background-color: #EF5350;
    }
}

我們希望動畫在用戶交互時開始,因此我們還必須創建一個單擊事件偵聽器,將 CSS 類添加到所需元素:

var square = document.getElementById('square');

square.addEventListener('click', function() {
    square.className += " animate";
});

雖然它工作得很好,但 CSS 方法似乎相當不直觀,因為我們定義了樣式表中發生的事情,但實際上是在 JavaScript 中開始的。一旦動畫被調用,我們對動畫的控制也非常有限。這兩個問題都可以通過切換到 Web Animation API 來解決。

JavaScript 方法

我們可以使用我們在 CSS 示例中使用的幾乎完全相同的轉換來描述我們的 JavaScript 動畫:

var moveAndChangeColor = [
    { 
        transform: 'translateX(0)',
        background: '#2196F3'    // blue
    },
    { 
        offset: 0.8,
        transform: 'translateX(100px)', 
        background: '#2196F3'    // blue
    },
    {
        transform: 'translateX(100px)',
        background: '#EF5350'    // red
    }
];

數組中的每個對像都代表動畫的一個狀態。除非我們使用 offset 更改時間,否則狀態會在時間上均勻分佈(3 個狀態 - 0%、50%、100%) 選項,就像我們對中間狀態所做的那樣。

在我們定義了動畫數組之後,我們可以使用 animate() 方法來調用它。它接受一個與 CSS 動畫屬性具有相同選項的對像作為第二個參數,儘管名稱略有不同(例如 animation-fill-modefill , animation-iteration-countiteration 等)。

var circle = document.getElementById('circle');

circle.addEventListener('click', function() {
    circle.animate(moveAndChangeColor, {
        duration: 400,
        fill: 'forwards'
    });
});

如您所見,JavaScript 方法更有條理,動畫存儲在變量中,animate() 用於在需要時調用它的方法。

控制動畫

Web Animation API 還可以通過多種方式輕鬆控制動畫的播放。 animate() 方法返回一個 Animation 對象,我們可以將其保存在一個變量中,並在以後用於引用該動畫。

var animation = elem.animate(transitions, options);

該接口為我們提供了以下方法:

  • pause() - 將動畫凍結在當前狀態。
  • play() - 恢復動畫,如果動畫完成則重新開始。
  • reverse() - 向後播放過渡。
  • finish() - 轉到動畫的結尾(或者如果反轉則開始)。
  • cancel() - 停止播放並返回開始狀態。

下面是一個帶有無限循環加載指示器的小演示。我們為不同的事件設置了按鈕,以便您試用:

var spinner = document.getElementById('spinner');
var spinnerAnimation = spinner.animate([
    {
        transform: 'rotate(0)'
    },
    {
        transform: 'rotate(359deg)'
    }
], {
    duration: 1000,
    iterations: Infinity
});

document.getElementById('pause').addEventListener('click', function() { 
  spinnerAnimation.pause();
});
document.getElementById('play').addEventListener('click', function() { 
  spinnerAnimation.play(); 
});
document.getElementById('reverse').addEventListener('click', function() { 
  spinnerAnimation.reverse(); 
});
document.getElementById('cancel').addEventListener('click', function() { 
  spinnerAnimation.cancel(); 
});
<div id="spinner"></div>

<p>Try controlling the animation:</p>
<button id="pause">Pause</button>
<button id="play">Play</button>
<button id="reverse">Reverse</button>
<button id="cancel">Cancel</button>
#spinner {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 3px solid #e2e2e2;
    border-top-color: #186aab;
    margin: 50px;
}

屬性和事件監聽器

animate() 返回的 Animation 對象 擁有幾個有用的屬性,可以讓我們訪問當前時間、播放速率等選項。雖然有些是只讀的,但大部分屬性都可以用作 setter 和 getter。

您可以在下面的編輯器中查看 JS 代碼,以了解它們是如何工作的。有關屬性的完整列表,請訪問 MDN。

var spinner = document.getElementById('spinner');
var spinnerAnimation = spinner.animate([
    {
        transform: 'rotate(0)'
    },
    {
        transform: 'rotate(359deg)'
    }
], {
    duration: 1000,
    iterations: Infinity
});

document.getElementById('half').addEventListener('click', function() { 
  spinnerAnimation.playbackRate = 0.5; 
});
document.getElementById('normal').addEventListener('click', function() { 
  spinnerAnimation.playbackRate = 1; 
});
document.getElementById('double').addEventListener('click', function() { 
  spinnerAnimation.playbackRate = 2; 
});
document.getElementById('triple').addEventListener('click', function() { 
  spinnerAnimation.playbackRate = 3; 
});
<div id="spinner"></div>

<p>Set Playback Speed:</p>
<button id="half">0.5</button>
<button id="normal">Normal</button>
<button id="double">2</button>
<button id="triple">3</button>
#spinner {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 3px solid #e2e2e2;
    border-top-color: #186aab;
    margin: 50px;
}

除此之外,Web Animation API 還為我們提供了兩個有用的事件處理程序,用於處理動畫完成或取消的時間:

spinnerAnimation.addEventListener('finish', function() {
    // Animation has completed or .finish() has been called.
    doSomething();
});

spinnerAnimation.addEventListener('cancel', function() {
    // Animation has been canceled.    
    doSomething();
});

支持和性能

大多數 Web 動畫功能在 Chrome 和 Firefox 中免費提供,Edge 和 Safari 實現正在運行(caniuse)。還有一個維護良好的開源 polyfill,可以在等待瀏覽器完全覆蓋時使用。

在性能方面,與常規 CSS 轉換相比應該沒有任何區別,因為瀏覽器對兩者使用相同的引擎。如果您堅持只為不會導致重繪的屬性設置動畫,例如 transformopacity , 動畫應保持穩定的 60fps 速率。

結論

Web Animation API 為開發人員提供了一種非常棒的新方法來創建和控制僅使用純 JavaScript 的 Web 動畫。對於在用戶交互或其他動態事件中調用的動畫,這是個好消息,因為整個動畫可以在控制器代碼中完成,而無需跳轉到 CSS 文件進行實際轉換。

本文介紹了新 API 的大部分功能,但如果您想了解更多信息,我們強烈推薦以下幾個優秀資源:

  • 使用 MDN 上的 Web 動畫 API
  • Animatelo - 使用 Web 動畫 API 對 Animate.css 的改造
  • 讓我們談談 Web Animations API - Daniel C. Wilson 的 5 部分教程

Tutorial JavaScript 教程
  1. 僅顯示 JavaScript 禁用消息 [關閉]

  2. 有沒有辦法鏈接到其他人的頁面中間,即使他們沒有錨?

  3. 使用 git subtree 部署到 gh 頁面

  4. 為什麼回調地獄有效而 async/await 無效? (在我正在測試的這種特殊情況下)

  5. 002/100 天的代碼:Git

  6. 使用 Formik 反應原生表單

  7. Node Hero——你的第一個 Node.js HTTP 服務器

  1. 將返回的 JSON 對象屬性轉換為(較低的第一個)camelCase

  2. 嘗試從 chrome 擴展中的 URL 播放音頻時出錯

  3. 在服務器的 html 文件中添加 .js 文件作為源

  4. 重構我的 JavaScript 代碼以刪除更多而不僅僅是空格

  5. 如何在 Next.js 中使用 ESLint 和 Prettier

  6. 如何將標籤的文本作為數據屬性插入其父元素?

  7. 反饋給 Tech_ed

  1. React 中的複合組件和佈局組件

  2. 用於無服務器集成測試的快速 CI

  3. Docker 的底層

  4. 角管字符計數器