整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          前端干貨之隨機圖庫 Lorem Picsum

          前端干貨之隨機圖庫 Lorem Picsum

          者:MrWang

          轉發鏈接:https://segmentfault.com/a/1190000023102193

          eb Animation API 介紹

          當我們談及網頁動畫時,自然聯想到的是 CSS3 動畫、JS 動畫、SVG 動畫 等技術以及 jQuery.animate() 等動畫封裝庫,根據實際動畫內容設計去選擇不同的實現方式,然而,每個現行的動畫技術都存在一定的缺點,如 CSS3動畫必須通過JS去獲取動態改變的值,一個動畫效果分散在css文件和js文件里不好維護,setInterval 的時間往往是不精確的而且還會卡頓,引入額外的動畫封裝庫也并非對性能敏感的業務適用。

          Web Animation API 的歷史也應該有幾年了,但是每當做動畫效果時,筆者就是依賴各種庫,很少想著去原生實現,最終造成了我們的項目各種依賴庫,體積也不斷變大,性能如何也不得而知,作為前端開發的我們多么希望原生的JS去支持通用的動畫解決方案, Web Animation API 可能就是一個不錯的解決方案。

          W3C 提出 Web Animation API(簡稱 WAAPI)正緣于此,它致力于集合 CSS3 動畫的性能、JavaScript 的靈活、動畫庫的豐富等各家所長,將盡可能多的動畫控制由原生瀏覽器實現,并添加許多 CSS 不具備的變量、控制以及或調的選項。它為我們提供了一種通用語言來描述DOM元素的動畫,主要方法有:Animation,KeyframeEffect,AnimationEvent,DocumentTimeline,EffectTiming。關于這個API的詳細介紹,可以參照MDN的這篇文檔,鏈接地址:https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API。

          使用Web Animations API,我們可以將交互式動畫從樣式表移動到JavaScript,將表示與行為分開。我們不再需要依賴DOM的技術,例如編寫CSS屬性作用于元素以控制方向。為了構建自定義動畫庫和創建交互式動畫,Web Animations API可能是完成工作的完美工具,你無需借助第三方動畫庫,就可以輕松實現一個效果不錯的動畫。

          為了讓大家對這個API有個清晰的認識,筆者在接下來的系列文章里,用五六個例子讓大家理解這個API,今天筆者將用此API實現一個隨機移動的圖片開始進行介紹,比如用這個效果我們可以制作一個隨機飄浮移動的廣告位,游戲里隨機走動的怪物等等,本例中的特點就是為了體現Web Animation API的靈活性和強大性,我沒有引用任何第三方類庫,比如(JQ)以及也沒有使用setTimeout和requestAnimationFrame()函數。

          本篇文章預計時間 5 分鐘

          動畫效果

          開始前,我們先來看看完成后的動畫效果,示例如下效果:

          頁面布局

          無論圖片怎么隨機移動,我們都希望在指定的容器里,而不是漫無邊際,首先我們在html頁面定義容器:

          <div id="container">
          </div>
          

          接下來定義容器的樣式:

          body {
           margin: 0;
          }
          div#container {
           height:500px;
           width:100%;
           background: #C6CEF7;
          }
          #target {
           position: absolute;
           filter: drop-shadow(-12px 12px 7px rgba(0,0,0,0.5));
          }
          

          腳本部分

          獲取容器

          var container=document.getElementById("container");
          

          加載動畫

          為了更加直觀性,我選擇一個走動的gif圖片,由于圖片的加載需要一些時間,為了不破壞動畫的連貫性,確保圖片加載完了我們在執行動畫,相關代碼如下:

          var target=document.createElement("img");
          target.id="target";
          target.onload=function() {
           floatHead();
          }
          target.src="walk.gif";
          container.appendChild(target);
          

          大家都看到了,onload部分我們加載了floatHead()函數,接下來我們來進行相關實現,此函數主要包含以下功能:創建一個隨機位置,計算移動時間,封裝移動動畫。

          隨機位置

          我們利用Math.floor函數實現了其隨機位置的變化,示例代碼如下:

          function makeNewPosition() {
           var containerVspace=container.offsetHeight - target.offsetHeight,
           containerHspace=container.offsetWidth - target.offsetWidth,
           newX=Math.floor(Math.random() * containerVspace),
           newY=Math.floor(Math.random() * containerHspace);
           return [newX, newY];
          }
          

          這里的隨機位置,我們返回了一個數組,描述的是圖片相對容器的位置,即top,left。這里你需要理解offsetHeight,offsetWidth,可理解為div的可視高度或寬度,樣式的height或Width+上下padding或左右padding+上下border-width或左右border-width。

          計算時間

          動畫是有時間屬性的,我們進行位置的移動,需要花多久時間,假設運動速度為0.1個單位/毫秒。這個函數包含兩個數組:prev為當前目標的原始X和Y位置,next為移動目標的位置。此函數沒有進行進行精確的距離計算,只是判斷了x和y軸上移動的距離大小用最大的距離除以速度,示例代碼如下:

          function velocity(prev, next) { 
           var x=Math.abs(prev[1] - next[1]),
           y=Math.abs(prev[0] - next[0]),
           larger=x > y ? x : y,
           speedModifier=0.1,
           time=Math.ceil(larger / speedModifier);
           return time; 
          }
          

          封裝移動動畫

          接下來是我們Web Animations API的核心部分,我們使用其核心API在加上上述我們完成的兩個函數讓其動起來,示例代碼如下:

          function floatHead() {
           var newPos=makeNewPosition(),
           oldTop=target.offsetTop,
           oldLeft=target.offsetLeft,
           target.animate([
           { top: oldTop+"px", left: oldLeft+"px" },
           { top: newPos[0]+"px", left: newPos[1]+"px" }
           ], {
           duration: velocity([oldTop, oldLeft],newPos),
           fill: "forwards"
           }).onfinish=function() {
           floatHead();
           }
          }
          

          該Animation的animate函數有兩個參數,一個是KeyframeEffects數組和AnimationEffectTimingPropertiesoptions 的對象?;旧?,第一個參數映射到您將放入CSS中的內容@keyframes,你可以想象成css中的@keyframes內容,比如以下代碼:

          @keyframes emphasis {
           0% {
           transform: scale(1); 
           opacity: 1; 
           }
           30% {
           transform: scale(.5); 
           opacity: .5; 
           }
           78.75% {
           transform: scale(.667); 
           opacity: .667; 
           }
           100% {
           transform: scale(.6);
           opacity: .6; 
           }
          }
          

          你可以將“{}”里的信息順序依次放到一個數組里;第二個參數是時間控制 timing,包括有 duration 持續時間、iterations 執行次數、direction 動畫方向、easing 緩動函數等屬性。比如以下代碼:

          #toAnimate {
           animation: emphasis 700ms ease-in-out 10ms infinite alternate forwards;
          }
          

          你還可能注意到我們使用了onfinish事件完成了floatHead函數的反復調用,其是Animation的屬性,監聽動畫完成事件,如果動畫完成繼續執行floatHead(),相當不斷的遞歸調用。

          最終完成的代碼

          <!DOCTYPE html>
          <html lang="en">
          <head>
           <style>
           body {
           margin: 0;
           }
           div#container {
           height:500px;
           width:100%;
           background: #C6CEF7;
           }
           #target {
           position: absolute;
           filter: drop-shadow(-12px 12px 7px rgba(0,0,0,0.5));
           }
           </style>
           <meta charset="UTF-8">
           <title>前端達人示例展示——圖片隨機移動</title>
          </head>
          <body>
          <div id="container"></div>
          <script>
           function makeNewPosition() {
           var containerVspace=container.offsetHeight - target.offsetHeight,
           containerHspace=container.offsetWidth - target.offsetWidth,
           newX=Math.floor(Math.random() * containerVspace),
           newY=Math.floor(Math.random() * containerHspace);
           return [newX, newY];
           }
           function velocity(prev, next) {
           var x=Math.abs(prev[1] - next[1]),
           y=Math.abs(prev[0] - next[0]),
           larger=x > y ? x : y,
           speedModifier=0.2,
           time=Math.ceil(larger / speedModifier);
           return time;
           }
           function floatHead() {
           var newPos=makeNewPosition(),
           oldTop=target.offsetTop,
           oldLeft=target.offsetLeft;
           target.animate([
           { top: oldTop+"px", left: oldLeft+"px" },
           { top: newPos[0]+"px", left: newPos[1]+"px" }
           ], {
           duration: velocity([oldTop, oldLeft],newPos),
           fill: 'forwards'
           }).onfinish=function() {
           floatHead();
           }
           }
           var container=document.getElementById("container"),
           target=document.createElement("img");
           target.id="target";
           target.onload=function() {
           floatHead();
           }
           target.src="walk.gif";
           target.width="200";
           container.appendChild(target);
          </script>
          </body>
          </html>
          

          兼容情況

          最后聊聊你關心的各瀏覽器兼容問題,如下所示顯示了各個瀏覽器的兼容情況:

          看來好多都是部分支持,沒有完全支持,筆者也親自測試了下,在pc端最新版的谷歌瀏覽器和Firefox是沒有任何問題的可以完美運行,筆者的safari還是運行不起來,在iPhone XS Max無法運行。

          作為一名前端開發者,在移動端大行其道怎么能容忍在手機端沒有效果,為了在現代瀏覽器廠商還沒完全跟進到位的時候搶先用上 WAAPI(Web Animation API簡稱),我們可以選擇引入針對 Web Animation API 的 Polyfill 庫 [https://github.com/web-animations/web-animations-js],從而在 IE/Firefox/Safari 等瀏覽器上體驗到 WAAPI 的精彩。

          因此我們只需要文件里引入以下js,就可以完美體驗:

          <script src="https://cdn.jsdelivr.net/web-animations/latest/web-animations.min.js"></script>
          

          移動端瀏覽器,Android 5.0 以上的 Android Browser 和 Chrome for Android 本身就已經支持 WAAPI 了,加上 Polyfill 之后,筆者的手機終于可以看到運行效果了,微信里的QQ內核瀏覽器也能完美運行,pc端的safari也可以完美運行。可以說是全平臺支持了,有了這個庫你可以放心大膽的使用了。

          小節

          好了今天的代碼擼完了,js代碼還不到50行(注:為了在手機端運行,引入了web-animations.min.js),您可以點擊"https://www.qianduandaren.com/demo/walk/"行預覽,筆者親測在iPhone XS Max運行良好,其他手機沒有,有待親們的測試,歡迎到留言區告知。下一篇文章我們用不到20行的原生js代碼純手工擼一個漂亮的時鐘,敬請期待。

          更多精彩內容,請微信關注“前端達人”公眾號

          eb Animation API 介紹

          當我們談及網頁動畫時,自然聯想到的是 CSS3 動畫、JS 動畫、SVG 動畫 等技術以及 jQuery.animate() 等動畫封裝庫,根據實際動畫內容設計去選擇不同的實現方式,然而,每個現行的動畫技術都存在一定的缺點,如 CSS3動畫必須通過JS去獲取動態改變的值,一個動畫效果分散在css文件和js文件里不好維護,setInterval 的時間往往是不精確的而且還會卡頓,引入額外的動畫封裝庫也并非對性能敏感的業務適用。

          Web Animation API 的歷史也應該有幾年了,但是每當做動畫效果時,筆者就是依賴各種庫,很少想著去原生實現,最終造成了我們的項目各種依賴庫,體積也不斷變大,性能如何也不得而知,作為前端開發的我們多么希望原生的JS去支持通用的動畫解決方案, Web Animation API 可能就是一個不錯的解決方案。

          W3C 提出 Web Animation API(簡稱 WAAPI)正緣于此,它致力于集合 CSS3 動畫的性能、JavaScript 的靈活、動畫庫的豐富等各家所長,將盡可能多的動畫控制由原生瀏覽器實現,并添加許多 CSS 不具備的變量、控制以及或調的選項。它為我們提供了一種通用語言來描述DOM元素的動畫,主要方法有:Animation,KeyframeEffect,AnimationEvent,DocumentTimeline,EffectTiming。關于這個API的詳細介紹,可以參照MDN的這篇文檔,鏈接地址:https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API。

          使用Web Animations API,我們可以將交互式動畫從樣式表移動到JavaScript,將表示與行為分開。我們不再需要依賴DOM的技術,例如編寫CSS屬性作用于元素以控制方向。為了構建自定義動畫庫和創建交互式動畫,Web Animations API可能是完成工作的完美工具,你無需借助第三方動畫庫,就可以輕松實現一個效果不錯的動畫。

          為了讓大家對這個API有個清晰的認識,筆者在接下來的系列文章里,用五六個例子讓大家理解這個API,今天筆者將用此API實現一個隨機移動的圖片開始進行介紹,比如用這個效果我們可以制作一個隨機飄浮移動的廣告位,游戲里隨機走動的怪物等等,本例中的特點就是為了體現Web Animation API的靈活性和強大性,我沒有引用任何第三方類庫,比如(JQ)以及也沒有使用setTimeout和requestAnimationFrame()函數。

          本篇文章預計時間 5 分鐘

          動畫效果

          開始前,我們先來看看完成后的動畫效果,示例如下效果:

          頁面布局

          無論圖片怎么隨機移動,我們都希望在指定的容器里,而不是漫無邊際,首先我們在html頁面定義容器:

          <div id="container">
          </div>
          

          接下來定義容器的樣式:

          body {
           margin: 0;
          }
          div#container {
           height:500px;
           width:100%;
           background: #C6CEF7;
          }
          #target {
           position: absolute;
           filter: drop-shadow(-12px 12px 7px rgba(0,0,0,0.5));
          }
          

          腳本部分

          獲取容器

          var container=document.getElementById("container");
          

          加載動畫

          為了更加直觀性,我選擇一個走動的gif圖片,由于圖片的加載需要一些時間,為了不破壞動畫的連貫性,確保圖片加載完了我們在執行動畫,相關代碼如下:

          var target=document.createElement("img");
          target.id="target";
          target.onload=function() {
           floatHead();
          }
          target.src="walk.gif";
          container.appendChild(target);
          

          大家都看到了,onload部分我們加載了floatHead()函數,接下來我們來進行相關實現,此函數主要包含以下功能:創建一個隨機位置,計算移動時間,封裝移動動畫。

          隨機位置

          我們利用Math.floor函數實現了其隨機位置的變化,示例代碼如下:

          function makeNewPosition() {
           var containerVspace=container.offsetHeight - target.offsetHeight,
           containerHspace=container.offsetWidth - target.offsetWidth,
           newX=Math.floor(Math.random() * containerVspace),
           newY=Math.floor(Math.random() * containerHspace);
           return [newX, newY];
          }
          

          這里的隨機位置,我們返回了一個數組,描述的是圖片相對容器的位置,即top,left。這里你需要理解offsetHeight,offsetWidth,可理解為div的可視高度或寬度,樣式的height或Width+上下padding或左右padding+上下border-width或左右border-width。

          計算時間

          動畫是有時間屬性的,我們進行位置的移動,需要花多久時間,假設運動速度為0.1個單位/毫秒。這個函數包含兩個數組:prev為當前目標的原始X和Y位置,next為移動目標的位置。此函數沒有進行進行精確的距離計算,只是判斷了x和y軸上移動的距離大小用最大的距離除以速度,示例代碼如下:

          function velocity(prev, next) { 
           var x=Math.abs(prev[1] - next[1]),
           y=Math.abs(prev[0] - next[0]),
           larger=x > y ? x : y,
           speedModifier=0.1,
           time=Math.ceil(larger / speedModifier);
           return time; 
          }
          

          封裝移動動畫

          接下來是我們Web Animations API的核心部分,我們使用其核心API在加上上述我們完成的兩個函數讓其動起來,示例代碼如下:

          function floatHead() {
           var newPos=makeNewPosition(),
           oldTop=target.offsetTop,
           oldLeft=target.offsetLeft,
           target.animate([
           { top: oldTop+"px", left: oldLeft+"px" },
           { top: newPos[0]+"px", left: newPos[1]+"px" }
           ], {
           duration: velocity([oldTop, oldLeft],newPos),
           fill: "forwards"
           }).onfinish=function() {
           floatHead();
           }
          }
          

          該Animation的animate函數有兩個參數,一個是KeyframeEffects數組和AnimationEffectTimingPropertiesoptions 的對象?;旧?,第一個參數映射到您將放入CSS中的內容@keyframes,你可以想象成css中的@keyframes內容,比如以下代碼:

          @keyframes emphasis {
           0% {
           transform: scale(1); 
           opacity: 1; 
           }
           30% {
           transform: scale(.5); 
           opacity: .5; 
           }
           78.75% {
           transform: scale(.667); 
           opacity: .667; 
           }
           100% {
           transform: scale(.6);
           opacity: .6; 
           }
          }
          

          你可以將“{}”里的信息順序依次放到一個數組里;第二個參數是時間控制 timing,包括有 duration 持續時間、iterations 執行次數、direction 動畫方向、easing 緩動函數等屬性。比如以下代碼:

          #toAnimate {
           animation: emphasis 700ms ease-in-out 10ms infinite alternate forwards;
          }
          

          你還可能注意到我們使用了onfinish事件完成了floatHead函數的反復調用,其是Animation的屬性,監聽動畫完成事件,如果動畫完成繼續執行floatHead(),相當不斷的遞歸調用。

          最終完成的代碼

          <!DOCTYPE html>
          <html lang="en">
          <head>
           <style>
           body {
           margin: 0;
           }
           div#container {
           height:500px;
           width:100%;
           background: #C6CEF7;
           }
           #target {
           position: absolute;
           filter: drop-shadow(-12px 12px 7px rgba(0,0,0,0.5));
           }
           </style>
           <meta charset="UTF-8">
           <title>前端達人示例展示——圖片隨機移動</title>
          </head>
          <body>
          <div id="container"></div>
          <script>
           function makeNewPosition() {
           var containerVspace=container.offsetHeight - target.offsetHeight,
           containerHspace=container.offsetWidth - target.offsetWidth,
           newX=Math.floor(Math.random() * containerVspace),
           newY=Math.floor(Math.random() * containerHspace);
           return [newX, newY];
           }
           function velocity(prev, next) {
           var x=Math.abs(prev[1] - next[1]),
           y=Math.abs(prev[0] - next[0]),
           larger=x > y ? x : y,
           speedModifier=0.2,
           time=Math.ceil(larger / speedModifier);
           return time;
           }
           function floatHead() {
           var newPos=makeNewPosition(),
           oldTop=target.offsetTop,
           oldLeft=target.offsetLeft;
           target.animate([
           { top: oldTop+"px", left: oldLeft+"px" },
           { top: newPos[0]+"px", left: newPos[1]+"px" }
           ], {
           duration: velocity([oldTop, oldLeft],newPos),
           fill: 'forwards'
           }).onfinish=function() {
           floatHead();
           }
           }
           var container=document.getElementById("container"),
           target=document.createElement("img");
           target.id="target";
           target.onload=function() {
           floatHead();
           }
           target.src="walk.gif";
           target.width="200";
           container.appendChild(target);
          </script>
          </body>
          </html>
          

          兼容情況

          最后聊聊你關心的各瀏覽器兼容問題,如下所示顯示了各個瀏覽器的兼容情況:

          看來好多都是部分支持,沒有完全支持,筆者也親自測試了下,在pc端最新版的谷歌瀏覽器和Firefox是沒有任何問題的可以完美運行,筆者的safari還是運行不起來,在iPhone XS Max無法運行。

          作為一名前端開發者,在移動端大行其道怎么能容忍在手機端沒有效果,為了在現代瀏覽器廠商還沒完全跟進到位的時候搶先用上 WAAPI(Web Animation API簡稱),我們可以選擇引入針對 Web Animation API 的 Polyfill 庫 [https://github.com/web-animations/web-animations-js],從而在 IE/Firefox/Safari 等瀏覽器上體驗到 WAAPI 的精彩。

          因此我們只需要文件里引入以下js,就可以完美體驗:

          <script src="https://cdn.jsdelivr.net/web-animations/latest/web-animations.min.js"></script>
          

          移動端瀏覽器,Android 5.0 以上的 Android Browser 和 Chrome for Android 本身就已經支持 WAAPI 了,加上 Polyfill 之后,筆者的手機終于可以看到運行效果了,微信里的QQ內核瀏覽器也能完美運行,pc端的safari也可以完美運行??梢哉f是全平臺支持了,有了這個庫你可以放心大膽的使用了。

          小節

          好了今天的代碼擼完了,js代碼還不到50行(注:為了在手機端運行,引入了web-animations.min.js),您可以點擊"https://www.qianduandaren.com/demo/walk/"行預覽,筆者親測在iPhone XS Max運行良好,其他手機沒有,有待親們的測試,歡迎到留言區告知。下一篇文章我們用不到20行的原生js代碼純手工擼一個漂亮的時鐘,敬請期待。

          更多精彩內容,請微信關注“前端達人”公眾號


          主站蜘蛛池模板: 国产精品综合一区二区| 高清一区二区在线观看| 无码国产精品一区二区免费16| 国产精品美女一区二区视频 | 无码毛片一区二区三区视频免费播放| 久久久久国产一区二区| 国产精品一区二区三区久久| 国产精品香蕉一区二区三区| 亚洲日韩精品一区二区三区无码| 成人在线一区二区| 精品无码中出一区二区| 人妻视频一区二区三区免费| 精品一区二区三区无码免费视频| 日韩精品成人一区二区三区| 国产在线精品一区二区三区不卡 | 精品国产a∨无码一区二区三区| 中文字幕一区二区三区日韩精品| 一区二区高清在线| 无码精品久久一区二区三区 | 精品人妻少妇一区二区三区在线 | 亚洲免费一区二区| 亚洲国产激情一区二区三区| 一区二区三区四区精品| 一区二区三区精品高清视频免费在线播放| 亚洲.国产.欧美一区二区三区 | 国产99视频精品一区| 久久久无码一区二区三区| 91在线一区二区| 国产精品揄拍一区二区| 亚洲一区二区三区国产精华液| 国产成人亚洲综合一区| 色窝窝免费一区二区三区| 国产日韩精品一区二区在线观看 | 亚洲AV无码一区二区三区DV| 亚洲电影国产一区| 精品欧美一区二区在线观看| 国产人妖视频一区在线观看| 国产精品一区12p| 一区二区三区日韩| 乱码人妻一区二区三区| 琪琪see色原网一区二区|