SVG 實現動態模糊動畫效果

2021-03-02 前端大全

(點擊上方公眾號,可快速關注)

英文: Lucas Bebber   譯文: 碼農網/小峰

http://www.codeceo.com/article/svg-motion-blur-effect.html

如果好文章投稿,點擊 → 了解詳情

今天我們將向大家展示如何製作SVG動態模糊效果,並將其應用於HTML元素的常規JS或CSS動畫。

動態模糊是一種廣泛使用於動態影像和動畫的技術,它能使動作看起來更加平滑自然。

在線演示(http://www.html5tricks.com/demo/html5-svg-motion-blur-effect/index.html)

源碼下載(http://www.html5tricks.com/html5-svg-motion-blur-effect.html)

動態模糊是靜止圖像或一系列圖像(如電影或動畫)中快速移動物體的明顯圖像拖尾。當記錄的圖像在單幀記錄期間發生變化時,由於快速移動或長時間曝光從而導致動態模糊的結果。——維基百科上對動態模糊的介紹

在這篇文章中,我們將介紹如何對水平或垂直的轉換製作出類似的動態模糊效果。

注意:這種效果非常實用,但只有一些現代瀏覽器才支持。到目前為止,貌似Chrome具有最佳的性能。

為了對動畫應用動態模糊效果,我們需要在每個幀中根據對象的速度和它移動的方向應用方向模糊。

 

那麼,怎麼才能產生這種效果呢?

設置模糊

由於常規CSS模糊濾鏡不支持定向模糊,所以我們不得不使用SVG濾鏡。

我們已經在《Creative Gooey Effects》這篇文章中介紹過SVG濾鏡的基礎知識。

為此,我們將只使用高斯濾鏡模糊feGaussianBlur原語。

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="filters">

  <defs>

    <filter id="blur">

      <fegaussianblur in="SourceGraphic" stddeviation="0,0"/>

    </filter>

  </defs>

</svg>

stdDeviation屬性用於設置模糊強度,並且可以佔用兩個參數,用於水平和垂直方向的模糊。

將濾鏡應用到一個元素上,就像我們之前看到的那樣,非常簡單:

.selector{

  -webkit-filter: url("#blur");

  filter: url("../index.html#blur");

}

然而,對於動態模糊效果,我們仍得通過JS動態更新每個幀的濾鏡。

首先,我們必須選擇並將濾鏡存儲在一個變量中,以便以後可以訪問它。由於jQuery與SVG元素不兼容,所以我們需要使用本機JS函數選擇元素:

var filters = document.querySelector(".filters"), // the SVG that contains the filters

defs = filters.querySelector("defs"), // the  element inside the SVG

blur = defs.querySelector("#blur"), // the blur filter

blurFilter = blur.firstElementChild; // the feGaussianBlur primitive

然後設置強度,即改變濾鏡原語的stdDeviation屬性。例如,要設置一個水平12px的模糊:

blurFilter.setAttribute("stdDeviation","12,0");

 

記住,此模糊濾鏡只支持X或Y方向上的方向模糊,不能任意角度,因此你需要相應地規劃好動畫效果。

還有,改變模糊濾鏡會影響與其相關聯的所有對象,因此我們需要為將應用此效果的每個對象添加一個新的元素。下面是一種動態創建這些濾鏡的簡單方法:

// go through all the objects that need a blur filter

$(".js-blur").each(function(i){

// clone the filter

var blurClone=blur.cloneNode(true);

 

// create and set a new ID so we can use the filter through CSS

var blurId="blur"+i;

blurClone.setAttribute("id",blurId);

 

defs.appendChild(blurClone);

 

// set the CSS

var filter="url(#"+blurId+")";

$(this)

.css({

webkitFilter:filter,

filter:filter

})

// store the filter reference on the object for practicity

.data("blur",blurClone)

;

});

測量速度

接下來,我們需要能夠計算得到自上一幀以來對象移動的距離。每一幀我們都要計算。實現方法可能會根據設置的不同而不同;例如動畫如何完成方面的設置等等。在本教程中,我們將採用更通用的方法,儘管它可能無法針對所有用例進行優化,但適用於大多數JS和CSS動畫。

為了得到距離結果,我們將使用jQuery的offset函數,這正是我們需要的:它返回元素的坐標,相對於文檔(而不是它的父類)而言,並且將transform屬性考慮在內。

為了能夠檢查改變並更新每一幀,我們將使用requestAnimationFrame。

下面是一個例子:

// the element we want to apply the effect

var $element=$(".selector");

// storing the last position, to be able to measure changes

var lastPos=$element.offset();

// a multiplier, to be able to control the intensity of the effect

var multiplier=0.25;

 

// a helper to simplify setting the blur. 

function setBlur(x,y){

blurFilter.setAttribute("stdDeviation",x+","+y);

}

 

(function updateMotionBlur(){

// get the current position of the element

var currentPos=$element.offset();

 

// calculate the changes from the last frame and apply the multiplier

var xDiff=Math.abs(currentPos.left-lastPos.left)*multiplier;

var yDiff=Math.abs(currentPos.top-lastPos.top)*multiplier;

 

// set the blur

setBlur(xDiff,yDiff);

 

// store current position for the next frame

lastPos=currentPos;

 

// call to update in the next frame

requestAnimationFrame(updateMotionBlur);

})();

結果如下:

這不過是僅考慮一個要素的基本方法。更複雜的可能需要特別為其優化的代碼。對於更複雜的拍攝,你可以考慮將動態模糊效果應用於多個對象,在沒有動畫時禁用模糊和速度計算,等等。

到這裡本教程就結束了! 再說一次,請注意,這種效果可能很耗費資源,所以你應該避免在大型對象上使用它。

覺得本文對你有幫助?請分享給更多人

關注「前端大全」,提升前端技能

相關焦點

  • 【Web動畫】SVG 實現複雜線條動畫
    在上一篇文章中,我們初步實現了一些利用基本圖形就能完成的線條動畫:【Web動畫】SVG 線條動畫入門[1]當然,事物都是朝著熵增焓減的方向發展的,複雜線條也肯定比有序線條要多。獲取 SVG 的 path 路徑OK,最後把剛剛保存的 *.svg 路徑的文件用瀏覽器打開,一片空白是正常的,右鍵查看網頁原始碼:
  • 【Web動畫】SVG 線條動畫
    舉個慄子SVG 線條動畫,在一些特定的場合下可以解決使用 CSS 無法完成的動畫。尤其是在進度條方面,看看最近項目裡的一個小需求,一個這種形狀的進度條:把裡面的進度條單獨拿出來,也就是需要實現這樣一個效果:
  • SVG 線條動畫入門
    尤其是在進度條方面,看看最近項目裡的一個小需求,一個這種形狀的進度條:把裡面的進度條單獨拿出來,也就是需要實現這樣一個效果:掌握了這個技巧後,就可以使用 stroke-dasharray 和 stroke-dashoffset 製作很多不錯的交互場景:SVG 線條動畫實現按鈕交互
  • SVG動畫、CSS3動畫常用知識點全解析
    1" calcMode="spline" keySplines=".5 0 .5 1; 0 0 1 1" /> </text></svg>效果如下:3.animateMotion之前所有動畫功能在css裡都可以用animation實現,但<animateMotion>可以讓父元素沿著指定的路徑運動。也可以使用path指定複雜的路徑,或者可以指定<mpath>元素作為自己的路徑。效果如下:
  • svg 動畫介紹(一)
    今天講svg的動畫屬性 animate、animateTransform、animateMotion(第一節)SVG 動畫元素
  • 一篇文章帶你了解SVG 動畫元素
    > 運行效果:> 運行效果:> 運行效果:> 運行效果:對每一種動畫的效果進行詳細講解。每一種動畫中都採用靜態圖解析的方式來呈現動態運用的效果。通過具體的案例分析,能夠讓讀者更好的理解。歡迎大家積極嘗試,有時候看到別人實現起來很簡單,但是到自己動手實現的時候,總會有各種各樣的問題,切勿眼高手低,勤動手,才可以理解的更加深刻。代碼很簡單,希望對你學習有幫助。
  • 使用 SVG 製作加載動畫
    然後我看了下效果,發現其實用 SVG 動畫來實現應該比較簡單,於是就和設計師要了一下原始的稿子導出成 SVG 後處理了下。將 AE 動效稿子轉成 SVG 動畫的話 Airbnb 有出過一款 Lottie 的工具。通過它的 AE 插件 Bodymovin 能夠以 JSON 的形式導出動畫信息和素材。
  • 線條之美,玩轉SVG線條動畫
    通常來說web前端實現動畫效果主要通過下面幾種方案:css動畫;利用css3的樣式效果可以將dom元素做出動畫的效果來
  • 十分鐘教你用svg做出精美的動畫!
    前言經常在Codepen上看到大俠們用SVG畫出不可思議的動畫,我一直很好奇他們是怎麼運作的,總覺得這需要對SVG有足夠透徹的了解,並且自己畫出那些SVG圖案,才有辦法讓他動起來。但其實不然,今天教大家一個簡單的小技巧,讓你快速實現一個svg動畫!
  • 十分鐘教你用 svg 做出精美的動畫!
    前言經常在Codepen上看到大俠們用 SVG 畫出不可思議的動畫,我一直很好奇他們是怎麼運作的,總覺得這需要對 SVG 有足夠透徹的了解,並且自己畫出那些 SVG 圖案,才有辦法讓他動起來。但其實不然,今天教大家一個簡單的小技巧,讓你快速實現一個 svg 動畫!
  • 「看相」黑科技:SVG 動畫在 H5 項目中的運用
    支持動畫,與現有技術可以互動融合。例如,SVG 技術本身的動態部分(包括時序控制和動畫)就是基於 SMIL 標準。另外,SVG 文件還可嵌入 JavaScript(嚴格地說,應該是ECMAScript)腳本來控制SVG對象。SVG 圖形格式可以方便的創建文字索引,從而實現基於內容的圖像搜索。
  • 使用Anime.js製作火箭升空的動畫效果
    於是我就準備在項目中添加動畫元素。             動畫效果展示  經過搜尋引擎的內容索引,我發現現在這個階段可以實現動畫效果有幾種方式:gif, css3, openGL,canvas,Javascript等。我首先排除了gif這種方式,原因很簡單這種動畫方式會隨著網頁的縮放失真,我們無法預期用戶展開網站之後的尺寸所以就先pass掉了。
  • 【效果高能】你不知道的 Animation 動畫技巧
    引言—在 web 應用中,前端同學在實現動畫效果時往往常用的幾種方案:css3 transition / animation - 實現過渡動畫setInterval / setTimeout - 通過設置一個間隔時間來不斷的改變圖像的位置requestAnimationFrame - 通過一個回調函數來改變圖像位置,由系統來決定這個回調函數的執行時機
  • Svg和CSS的結合--打勾動畫
    我們常常會在一些APP和網頁上看到這樣的動畫--當我們點擊某個按鈕時會看到頁面彈出或者顯示出一個提交成功等提示動畫。
  • lottie-web 動畫實現原理
    設計師使用 AE 製作動畫。通過 Lottie 提供的 AE 插件 Bodymovin 把動畫導出 JSON 數據文件。加載 Lottie 庫結合 JSON 文件和下面幾行代碼就可以實現一個 Lottie 動畫。<!
  • 如何用一行代碼實現網頁變灰效果?
    官方介紹內容如下:filter CSS 屬性將模糊或顏色偏移等圖形效果應用於元素。濾鏡通常用於調整圖像,背景和邊框的渲染。CSS 標準裡包含了一些已實現預定義效果的函數。你也可以參考一個 SVG 濾鏡,通過一個 URL 連結到 SVG 濾鏡元素 (SVG filter element[1])。
  • 如何用PS打造動態光影模糊效果?優秀攝影講師惠繼清與你娓娓道來
    今天成都王老師攝影培訓學校優秀攝影講師惠繼清老師,給大家分享的是,如何用PS打造動態光影模糊效果?相當於人為的打造風吹過樹林的效果。其實,前期也能拍出來,只要你有足夠的耐心。如果前期沒有那麼多時間,我們不妨試試後期。
  • 「長曝光效果」兩步就可以實現,很簡單
    先給大家看一組照片:大家看完上面這組照片肯定會以為這是用三腳架搭配慢速快門來拍的,其實不是,上面這些效果都是通過後期實現的。今天給大家分享一下如何後期實現這種長曝光效果,希望對大家有幫助。選擇「濾鏡-模糊-徑向模糊」:進入徑向模糊界面後,調整好數量、模糊方式、模糊角度等,然後點擊確定執行:最終效果就會是下面這個樣子,地面也被模糊了:所以我要先摳圖,把天空和地面分離開來,對天空進行模糊操作,地面就不會受影響了。
  • 用pygame實現動畫效果
    養馬時覺得那個3D效果不卡頓實現好像有點厲害,看到想到那麼就來分享一期用pygame做出一個動畫效果吧,我只會二維的不是3D啦。
  • 動畫開篇之蒙皮 | 如何實現動畫效果
    動畫引擎Update之後,每一個關節都會得到一個最新的局部姿勢。這個時候可以進行一些額外的插值計算、程序式動畫、IK等後處理過程。因為局部姿勢一般保存為SQT格式,所以需要在這時轉換成矩陣。然後我們開始計算每個關節的全局姿勢矩陣,計算方法是依次連接關節本身及其所有父節點的局部姿勢矩陣。最後IBP乘上全局姿勢矩陣,就得到了蒙皮矩陣。