<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          圖片碎片化渲染特效實(shí)現(xiàn)

          共 7671字,需瀏覽 16分鐘

           ·

          2024-07-24 08:45

              


          寫(xiě)在開(kāi)頭

          最近,小編從玩了兩年多的游戲中退游了??,本來(lái)以為會(huì)一直就這么玩下去,和隊(duì)友們相處很融洽,收獲了很多開(kāi)心快樂(lè)的時(shí)光????上В螒虻囊徊ǜ?.....準(zhǔn)備要開(kāi)始收割韭菜了,只能無(wú)奈選擇棄坑了。

          小編屬于貧民玩家,靠著硬肝與白嫖也將游戲號(hào)整得還不錯(cuò),這兩天把號(hào)給賣(mài)了??。玩了兩年多,竟然還能賺一點(diǎn)小錢(qián),很開(kāi)心??。只是...多少有點(diǎn)舍不得的一起組隊(duì)的隊(duì)友們,唉。??

          記錄一下,希望未來(lái)還有重逢一日吧,也希望各位一切安好!??

          好,回到正題,本文將分享一個(gè)圖片碎片化展示的效果,具體效果如下,請(qǐng)諸君按需食用。

          原理

          這種特效早在幾年前就已經(jīng)出現(xiàn),屬于老演員了??,它最早是經(jīng)常在輪播圖(banner)上應(yīng)用的,那會(huì)追求各種花里胡哨的特效,而現(xiàn)在感覺(jué)有點(diǎn)返璞歸真了,簡(jiǎn)潔實(shí)用就行。

          今天咱們來(lái)看看它的具體實(shí)現(xiàn)原理是如何的,且看圖:

          一圖勝千言,不知道聰明的你是否看明白了???

          大概原理是:通過(guò)容器/圖片大小生成一定數(shù)量的小塊,然后每個(gè)小塊背景也使用相同圖片,再使用 background-sizebackground-position 屬性調(diào)整背景圖片的大小與位置,使小塊又合成一整張大圖片,這操作和使用"精靈圖"的操作是一樣的,最后,我們?cè)俳o每個(gè)小塊增加動(dòng)畫(huà)效果,就大功告成。

          簡(jiǎn)單樸實(shí)??,你可以根據(jù)這個(gè)原理自個(gè)嘗試一下,應(yīng)該能整出來(lái)吧。??

          具體實(shí)現(xiàn)

          布局與樣式:


          <!DOCTYPE html>
          <html>
          <head>
          <style>
          body{
          width: 100%;
          height: 100vh;
          padding: 0;
          margin: 0;
          display: flex;
          justify-content: center;
          align-items: center;
          }
          .box {
          width: var(--width);
          height: var(--height);
          display: flex;
          /* 小塊自動(dòng)換行排列 */
          flex-wrap: wrap;
          justify-content: center;
          }
          .small-box {
          background-image: url('https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/99b070fcb1de471d9af4f4d5d3f71909~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1120&h=1680&s=2088096&e=png&b=d098d0');
          box-sizing: border-box;
          background-repeat: no-repeat;
          }
          </style>
          </head>
          <body>
          <div id="box" class="box"></div>
          </body>
          </html>

          生成無(wú)數(shù)小塊填充:


          <script>
          document.addEventListener('DOMContentLoaded', () => {
          const box = document.getElementById('box');
          const { width, height } = box.getBoundingClientRect();
          // 定義多少個(gè)小塊,由多少行和列決定
          const row = 14;
          const col = 10;
          // 計(jì)算小塊的寬高
          const smallBoxWidth = width / col;
          const smallBoxHeight = height / row;
          /** @name 創(chuàng)建小塊 **/
          function createSmallBox() {
          for (let i = 0; i < row; i++) {
          for (let j = 0; j < col; j++) {
          const smallBox = document.createElement('div');
          smallBox.classList.add('small-box');
          smallBox.style.width = smallBoxWidth + 'px';
          smallBox.style.height = smallBoxHeight + 'px';
          smallBox.style.border = '1px solid red';
          // 插入小塊
          box.appendChild(smallBox);
          }
          }
          }
          createSmallBox();
          });
          </script>

          上面,生成多少個(gè)小塊是由人為規(guī)定行(row)與列(col)來(lái)決定。可能有的場(chǎng)景想用小塊固定的寬高來(lái)決定個(gè)數(shù),這也是可以的,只是需要注意處理一下"邊界"的情況。??

          調(diào)整小塊背景圖片的大小與位置:


          <script>
          document.addEventListener('DOMContentLoaded', () => {
          // ...
          function createSmallBox() {
          for (let i = 0; i < row; i++) {
          for (let j = 0; j < col; j++) {
          // ...
          smallBox.style.border = '1px solid red';

          // 設(shè)置背景偏移量,讓小塊的背景顯示對(duì)應(yīng)圖片的位置,和以前那種精靈圖一樣
          const offsetX = j * smallBoxWidth * -1;
          const offsetY = i * smallBoxHeight * -1;
          smallBox.style.backgroundPosition = `${offsetX}px ${offsetY}px`;
          smallBox.style.backgroundSize = `${width}px ${height}px`;

          box.appendChild(smallBox);
          }
          }
          }
          createSmallBox();
          });
          </script>

          女神拼接成功,到這里就已經(jīng)完成一大步了,是不是沒(méi)什么難度!??

          小塊樣式整好后,接下來(lái),我們需要來(lái)給小塊增加動(dòng)畫(huà),讓它們動(dòng)起來(lái),并且是有規(guī)律的動(dòng)起來(lái)。

          先來(lái)整個(gè)簡(jiǎn)單的透明度動(dòng)畫(huà),且看:


          <!DOCTYPE html>
          <html>
          <head>
          <style>
          /* ... */
          .small-box {
          /* ... */
          opacity: 0;
          animation: smallBoxAnimate 2000ms linear forwards;
          }
          @keyframes smallBoxAnimate {
          0% {
          opacity: 0;
          }
          40% {
          opacity: 0;
          }
          70% {
          opacity: 1;
          }
          100% {
          opacity: 1;
          }
          }
          </style>
          </head>
          <body>
          <script>
          document.addEventListener('DOMContentLoaded', () => {
          // ...
          function createSmallBox() {
          for (let i = 0; i < row; i++) {
          for (let j = 0; j < col; j++) {
          // ...
          // smallBox.style.border = '1px solid red';

          // 給每個(gè)小塊增加不同的延時(shí),讓動(dòng)畫(huà)不同時(shí)間執(zhí)行
          const delay = i * 100; // 延遲時(shí)間為毫秒(ms),注意不要太小了
          smallBox.style.animationDelay = `${delay}ms`;

          box.appendChild(smallBox);
          }
          }
          }
          createSmallBox();
          });
          </script>
          </body>
          </html>

          嘿嘿??,稍微有點(diǎn)意思了吧?


          Em...等等,你發(fā)現(xiàn)沒(méi)有?怎么有一些小白條?這可不是小編添加的,小塊的邊框(border)已經(jīng)是注釋了的。??

          一開(kāi)始小編以為是常見(jiàn)的"圖片底部白邊"問(wèn)題,直接設(shè)置一下 display: block 或者 vertical-align : middle 就能解決,結(jié)果還不是,折騰了很久都沒(méi)有搞掉這個(gè)小白條。??

          最后,竟然通過(guò)設(shè)置 will-change 屬性能解決這個(gè)問(wèn)題?我所知道的 will-change 應(yīng)該是應(yīng)用在性能優(yōu)化上,解決動(dòng)畫(huà)流暢度問(wèn)題上的,想不到這里竟然也能用。

          看來(lái)得去深度學(xué)習(xí)一下?? will-change 屬性的原理過(guò)程才行,這里也推薦倔友寫(xiě)得一篇文章:傳送門(mén)。

          解決相鄰背景圖片白條/白邊間隙問(wèn)題:


          <script>
          document.addEventListener('DOMContentLoaded', () => {
          // ...
          function createSmallBox() {
          for (let i = 0; i < row; i++) {
          for (let j = 0; j < col; j++) {
          // ...

          smallBox.style.willChange = 'transform';
          // 在動(dòng)畫(huà)執(zhí)行后,需要重置will-change
          const timer = setTimeout(() => {
          smallBox.style.willChange = 'initial';
          clearTimeout(timer);
          }, 2000);

          box.appendChild(smallBox);
          }
          }
          }
          createSmallBox();
          });
          </script>

          一定要注意 will-change 不可能被濫用,注意重置回來(lái)?

          這下女神在動(dòng)畫(huà)執(zhí)行后,也清晰可見(jiàn)了,這是全部小塊拼接組成的圖片。

          在上述代碼中,咱們看到,通過(guò) animation-delay 去延遲動(dòng)畫(huà)的執(zhí)行,就能制造一個(gè)從上到下的漸變效果。

          那么,咱們?cè)俑母难舆t時(shí)間,如:


          // const delay = i * 100;
          // 改成 ?
          const delay = j * 100;

          效果:

          這...好像有那么點(diǎn)意思吧。。。

          但是,這漸變...好像還達(dá)不到我們開(kāi)頭 gif 的碎片化效果吧?

          那么,碎片化安排上:


          .small-box {
          /* ... */
          --rotateX: rotateX(0);
          --rotateY: rotateY(0);
          transform: var(--rotateX) var(--rotateY) scale(0.8);
          }
          @keyframes smallBoxAnimate {
          0% {
          opacity: 0;
          transform: var(--rotateX) var(--rotateY) scale(0.8);
          }
          40% {
          opacity: 0;
          transform: var(--rotateX) var(--rotateY) scale(0.8);
          }
          70% {
          opacity: 1;
          transform: rotateX(0) rotateY(0) scale(0.8);
          }
          100% {
          opacity: 1;
          transform: rotateX(0) rotateY(0) scale(1);
          }
          }

          其實(shí)就是增加小塊的樣式動(dòng)畫(huà)而已,再加點(diǎn)旋轉(zhuǎn),再加點(diǎn)縮放,都整上,整上。??

          效果:

          是不是稍微高級(jí)一點(diǎn)?有那味了???

          看到上面旋轉(zhuǎn)所用的"樣式變量"沒(méi)有?


          --rotateX: rotateX(0);
          --rotateY: rotateY(0);

          不可能無(wú)緣無(wú)故突然使用,必然是有深意啦。??

          現(xiàn)在效果還不夠炫,咱們將樣式變量利用起來(lái),讓"相鄰兩個(gè)小塊旋轉(zhuǎn)相反":


          <script>
          document.addEventListener('DOMContentLoaded', () => {
          // ...
          function createSmallBox() {
          for (let i = 0; i < row; i++) {
          for (let j = 0; j < col; j++) {
          // ...

          // 相鄰兩個(gè)小塊旋轉(zhuǎn)相反
          const contrary = (i + j) % 2 === 0;
          smallBox.style.setProperty('--rotateX', `rotateX(${contrary ? -180 : 0}deg)`);
          smallBox.style.setProperty('--rotateY', `rotateY(${contrary ? 0 : -180}deg)`);

          box.appendChild(smallBox);
          }
          }
          }
          createSmallBox();
          });
          </script>

          效果:

          這下對(duì)味了。??

          總的來(lái)說(shuō),我們可以通過(guò)"延遲"執(zhí)行動(dòng)畫(huà)與改變"旋轉(zhuǎn)"行為,讓小塊們呈現(xiàn)不同的動(dòng)畫(huà)效果,或者你只要有足夠多的設(shè)想,你可以給小塊添加不同的動(dòng)畫(huà)效果,相信也能制造出不錯(cuò)的整體效果。

          更多效果

          下面列舉一些通過(guò)"延遲"執(zhí)行動(dòng)畫(huà)產(chǎn)生的效果,可以瞧瞧哈。

          隨機(jī):


          const getRandom = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);
          const delay = getRandom(0, col + row) * 100;

          從左上角到右下角:


          const delay = (i + j) * 100;

          其他的從"右上角到左下角"或者"左下角到右上角"等等的,只要反向調(diào)整一下變量就行了,就靠你自己悟啦,Come On!??

          從中心向四周擴(kuò)散:


          const delay = ((Math.abs(col / 2 - j) + Math.abs(row / 2 - i))) * 100;

          從四周向中心聚齊:


          const delay = (col / 2 - Math.abs(col / 2 - j) + (col / 2 - Math.abs(row / 2 - i))) * 100;

          那么,到這里就差不多了?

          但還有最后一個(gè)問(wèn)題,那就是圖片的大量使用與加載時(shí)長(zhǎng)的情況可能會(huì)導(dǎo)致效果展示不佳,這里你最好進(jìn)行一些防范措施,如:

          • 圖片鏈接設(shè)置緩存,讓瀏覽器緩存到內(nèi)存或硬盤(pán)中。

          • 通過(guò) JS 手動(dòng)將圖片緩存到內(nèi)存,主要就是創(chuàng)建 Image 對(duì)象。

          • 將圖片轉(zhuǎn)成 base64 使用。

          • 直接將圖片放到代碼本地使用。

          • ...

          以上等等吧,反正最好就是要等圖片完整加載后再進(jìn)行效果展示。

          至此,本篇文章就寫(xiě)完啦,撒花撒花。

          原文鏈接:https://juejin.cn/post/7379856289487831074
          作者:橙某人

          瀏覽 86
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲男人69天堂 | 91久久爽无码人妻AⅤ精品蜜桃 | 欧美性成人1819 | 美女国产精品 | 日韩电影无码麻豆 |