ノイズアニメーションをワンタッチで実現する

ノイズアニメーションをワンタッチで実現する:



sample.png

ゾンビランドサガの公式サイト(の一部)でノイズアニメーションが使われているのを見て、「これはライブラリ化できそうだな」と思い立ち、衝動的に作ったのがこちらです。

Noise Maker - デモ
Noise Maker - リポジトリ


ノイズアニメーションのロジック

ゾンビランドサガではこんな画像を別途用意して使っていますが、これを Canvas で動的に生成することで利便性と汎用性を高めることにしました(言い回しが大げさ)。

  1. 仮想 Canvas を作成
  2. 1 ピクセルごとにランダムな RGBA 値を設定
  3. 指定された DOM ノードの背景画像に Data URI として設定
  4. アニメーションループ内で background-position をランダムに設定


NoiseMaker クラスについて

上記のロジックに基づいて作ったのが NoiseMaker クラスです。以下特徴。

  • 複数の DOM ノードに異なるノイズアニメーションを設定可能
  • ノイズアニメーションを削除可能
  • ノイズ画像のサイズを設定可能
  • 各ピクセルの RGBA 値に対して最小乱数値と最大乱数値を設定可能
  • Firefox では若干遅い( background-position の反映が遅い?)
以下コード。

class NoiseMaker { 
  constructor () { 
    this.configs = {}; 
    this.configId = 0; 
    setInterval(() => { 
      for (let key in this.configs) { 
        this.configs[key].target.style['background-position'] = `${this.irandom(0, this.configs[key].width)}px ${this.irandom(0, this.configs[key].height)}px`; 
      } 
    }, 1); 
  } 
  make (config) { 
    const canvas = document.createElement('canvas'); 
    canvas.setAttribute('width', config.width); 
    canvas.setAttribute('height', config.height); 
    const context = canvas.getContext('2d'); 
    const imageData = context.getImageData(0, 0, canvas.width, canvas.height); 
    for (let y = 0; y < imageData.height; y ++) { 
      for (let x = 0; x < imageData.width; x ++) { 
        const index = (imageData.width * y + x) * 4; 
        imageData.data[index] = this.irandom(config.r[0], config.r[1]); 
        imageData.data[index + 1] = this.irandom(config.g[0], config.g[1]); 
        imageData.data[index + 2] = this.irandom(config.b[0], config.b[1]); 
        imageData.data[index + 3] = this.irandom(config.a[0], config.a[1]); 
      } 
    } 
    context.putImageData(imageData, 0, 0, 0, 0, canvas.width, canvas.height); 
    config.target.style['background-image'] = `url(${canvas.toDataURL()})`; 
    this.configs[this.configId.toString()] = config; 
    return this.configId ++; 
  } 
  remove (configId) { 
    this.configs[configId].target.style['background-image'] = null; 
    this.configs[configId].target.style['background-position'] = null; 
    delete this.configs[configId]; 
  } 
  irandom (min, max) { 
    return Math.floor(Math.random() * (max - min + 1)) + min; 
  } 
} 
使い方。

// オブジェクトの作成 
const noiseMaker = new NoiseMaker(); 
// ノイズアニメーションの作成 
let configId = noiseMaker.make({ 
  target: document.querySelector('.target'), 
  width: 320, 
  height: 320, 
  r: [ 0, 255 ], 
  g: [ 0, 255 ], 
  b: [ 0, 255 ], 
  a: [ 0, 255 ] 
}); 
// ノイズアニメーションの削除 
noiseMaker.remove(configId); 
なお、デモでは二箇所に異なるアニメーションを設定しています。


終わりに

即興で書いたので色々アレですが、大体こんな感じで良いと思います。α値を低めに抑えるのがコツですね。あとはアイディア次第で。

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)