溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何使用JS前端技術(shù)實現(xiàn)靜態(tài)圖片局部流動效果

發(fā)布時間:2022-08-05 09:53:27 來源:億速云 閱讀:286 作者:iii 欄目:開發(fā)技術(shù)

本文小編為大家詳細介紹“如何使用JS前端技術(shù)實現(xiàn)靜態(tài)圖片局部流動效果”,內(nèi)容詳細,步驟清晰,細節(jié)處理妥當,希望這篇“如何使用JS前端技術(shù)實現(xiàn)靜態(tài)圖片局部流動效果”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。

    實現(xiàn)

    頁面主要由 2 部分構(gòu)成,頂部用于加載圖片 ,并且可以通過按住鼠標劃動的方式繪制熱點路徑,給圖片添加流動效果;底部是控制區(qū)域,點擊按鈕  清除畫布,可以清除繪制的流動動畫效果、點擊按鈕 切換圖片可以加載本地的圖片。

    如何使用JS前端技術(shù)實現(xiàn)靜態(tài)圖片局部流動效果

    注意,還有一個隱形的功能,當你繪制完成時,可以點擊鼠標右鍵,然后選擇保存圖片,保存的這張圖片就是我們繪制流體動畫路徑的熱點圖,利用這張熱點圖,使用本文的 CSS 知識,就能把靜態(tài)圖片轉(zhuǎn)化成動態(tài)圖啦!

    HTML 頁面結(jié)構(gòu)

    #sketch 元素主要是用于繪制和加載流動效果熱點圖的畫板;#button_container 是頁面底部的按鈕控制區(qū)域;svg 元素用于利用其 filter 濾鏡實現(xiàn)液態(tài)流動動畫效果,包括 feTurbulencefeDisplacementMap 濾鏡。

    <main id="sketch">
      <canvas id="canvas" data-img=""></canvas>
      <div class="mask">
        <div id="maskInner" class="mask-inner"></div>
      </div>
    </main>
    <section class="button_container">
      <button class="button">清除畫布</button>
      <button class="button"><input class="input" type="file" id="upload">上傳圖片</button>
    </section>
    <svg>
      <filter id="heat" filterUnits="objectBoundingBox" x="0" y="0" width="100%" height="100%">
        <feTurbulence id="heatturb" type="fractalNoise" numOctaves="1" seed="2" />
        <feDisplacementMap xChannelSelector="G" yChannelSelector="B" scale="22" in="SourceGraphic" />
      </filter>
    </svg>
    feTurbulence 和 feDisplacementMap
    • feTurbulence:濾鏡利用 Perlin 噪聲函數(shù)創(chuàng)建了一個圖像,利用它可以實現(xiàn)人造紋理比如說云紋、大理石紋等模擬濾鏡效果。

    • feDisplacementMap:映射置換濾鏡,該濾鏡用來自圖像中從 in2 到空間的像素值置換圖像從 in 到空間的像素值。即它可以改變元素和圖形的像素位置,通過遍歷原圖形的所有像素點,feDisplacementMap 重新映射替換一個新的位置,形成一個新的圖形。該濾鏡在業(yè)界的主流應(yīng)用是對圖形進行形變,扭曲,液化。

    CSS 樣式

    接著看看樣式的實現(xiàn),main 元素作為主容器并將主圖案作為背景圖片;canvas 作為畫布占據(jù) 100% 的空間位置;.mask.mask-inner 用于生成如下圖所示熱點路徑與背景圖相溶的效果,這種效果是借助 mask-image 實現(xiàn)的。最后,為了生成動態(tài)流動效果,.mask-inner 通過 filter: url(#heat) 將前面生成的 svg 作為濾鏡來源,后續(xù)即將在 JavaScript 中通過不間斷修改 svg 濾鏡的屬性,來生成液態(tài)流動動畫。

    main {
      position: relative;
      background-image: url('bg.jpg');
      background-size: cover;
      background-position: 100% 50%;
    }
    canvas {
      opacity: 0;
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }
    .mask {
      display: none;
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      mask-mode: luminance;
      mask-size: 100% 100%;
      backdrop-filter: hard-light;
      mask-image: url('mask.png');
    }
    .mask-inner {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: url('bg.jpg') 0% 0% repeat;
      background-size: cover;
      background-position: 100% 50%;
      filter: url(#heat);
      mask-image: url('mask.png')
    }

    如何使用JS前端技術(shù)實現(xiàn)靜態(tài)圖片局部流動效果

    mask-image

    mask-image CSS 屬性用于設(shè)置元素上遮罩層的圖像。

    語法:

    // 默認值,透明的黑色圖像層,也就是沒有遮罩層。
    mask-image: none;
    // <mask-source><mask>或CSS圖像的url的值
    mask-image: url(masks.svg#mask1);
    // <image> 圖片作為遮罩層
    mask-image: linear-gradient(rgba(0, 0, 0, 1.0), transparent);
    mask-image: image(url(mask.png), skyblue);
    // 多個值
    mask-image: image(url(mask.png), skyblue), linear-gradient(rgba(0, 0, 0, 1.0), transparent);
    // 全局值
    mask-image: inherit;
    mask-image: initial;
    mask-image: unset;

    兼容性:

    如何使用JS前端技術(shù)實現(xiàn)靜態(tài)圖片局部流動效果

    ? 此功能某些瀏覽器尚在開發(fā)中,需要使用瀏覽器前綴以兼容不同瀏覽器。

    JavaScript 方法

    ① 繪制熱點圖

    監(jiān)聽鼠標移動和點擊事件,在 canvas 上繪制波動路徑熱點。

    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var sketch = document.getElementById('sketch');
    var sketchStyle = window.getComputedStyle(sketch);
    var mouse = { x: 0, y: 0 };
    
    canvas.width = parseInt(sketchStyle.getPropertyValue('width'));
    canvas.height = parseInt(sketchStyle.getPropertyValue('height'));
    canvas.addEventListener('mousemove', e => {
      mouse.x = e.pageX - canvas.getBoundingClientRect().left;
      mouse.y = e.pageY - canvas.getBoundingClientRect().top;
    }, false);
    
    ctx.lineWidth = 40;
    ctx.lineJoin = 'round';
    ctx.lineCap = 'round';
    ctx.strokeStyle = 'black';
    
    canvas.addEventListener('mousedown', () => {
      ctx.beginPath();
      ctx.moveTo(mouse.x, mouse.y);
      canvas.addEventListener('mousemove', onPaint, false);
    }, false);
    
    canvas.addEventListener('mouseup', () => {
      canvas.removeEventListener('mousemove', onPaint, false);
    }, false);
    
    var onPaint = () => {
      ctx.lineTo(mouse.x, mouse.y);
      ctx.stroke();
      var url = canvas.toDataURL();
      document.querySelectorAll('div').forEach(item => {
        item.style.cssText += `
          display: initial;
          -webkit-mask-image: url(${url});
          mask-image: url(${url});
        `;
      });
    };

    繪制完成后,可以在頁面中右鍵保存生成的波動路徑熱點圖,直接將繪制滿意的熱點圖放到 CSS 中,就能給喜歡的圖片添加局部波動效果了,下面這張圖片就是本示例頁面使用的波動的熱點路徑圖。

    如何使用JS前端技術(shù)實現(xiàn)靜態(tài)圖片局部流動效果

    ② 生成動畫

    為了生成實時更新的波動效果,本文使用了 TweenMax 來通過改變 feTurbulencebaseFrequency 屬性值來實現(xiàn),使用其他動畫庫或使用 requestAnimationFrame 也是可以實現(xiàn)相同的功能。

    feTurb = document.querySelector('#heatturb');
    var timeline = new TimelineMax({
      repeat: -1,
      yoyo: true
    }),
    timeline.add(
      new TweenMax.to(feTurb, 8, {
        onUpdate: () => {
          var bfX = this.progress() * 0.01 + 0.025,
            bfY = this.progress() * 0.003 + 0.01,
            bfStr = bfX.toString() + ' ' + bfY.toString();
          feTurb.setAttribute('baseFrequency', bfStr);
        }
      }),
    0);
    ③ 清除畫布

    點擊清除畫布按鈕,可以清空已經(jīng)繪制的波動路徑,主要是通過清除頁面元素 mask-image 的屬性值以及清 canvas 畫布來實現(xiàn)的。

    function clear() {
      document.querySelectorAll('div').forEach(item => {
        item.style.cssText += `
          display: none;
          -webkit-mask-image: none;
          mask-image: none;
        `;
      });
    }
    
    document.querySelectorAll('.button').forEach(item => {
      item.addEventListener('click', () => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        clear();
      })
    });
    ④ 切換圖片

    點擊切換圖片,可以加載本地的一張圖片作為繪制底圖,該功能是通過 input[type=file] 來實現(xiàn)圖片資源的獲取,然后通過修改 CSS 將它設(shè)置成新的畫布背景。

    document.getElementById('upload').onchange = function () {
      var imageFile = this.files[0];
      var newImg = window.URL.createObjectURL(imageFile);
      clear();
      document.getElementById('sketch').style.cssText += `
        background: url(${newImg});
        background-size: cover;
        background-position: center;
      `;
      document.getElementById('maskInner').style.cssText += `
        background: url(${newImg});
        background-size: cover;
        background-position: center;
      `;
    };

    讀到這里,這篇“如何使用JS前端技術(shù)實現(xiàn)靜態(tài)圖片局部流動效果”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

    向AI問一下細節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    js
    AI