Udemyセール!最大95%オフ!1,200円~Udemy公式サイト >

この記事にはプロモーションが含まれています。

【コピペOK】背景アニメーション完全ガイド|Javascript【5種類の実装方法】

【コピペOK】背景アニメーション完全ガイド|Javascript【5種類の実装方法】

ケケンタ

背景に美しい粒子アニメーションを実装したい……

ケケンタ

ランディングページをより魅力的にしたい……

今回はこのようなお悩みをお持ちの方へ向けて

Web制作において人気の高いアニメーション効果
パーティクル効果

をご紹介します。

5種類のパーティクル効果を完全網羅した実装なので、いままさに「背景アニメーションを実装しないといけない!」という方は丸っとコピペしてどうぞご活用ください!

この記事で紹介するパーティクル効果
  • 基本的なパーティクル(シンプルで高パフォーマンス)
  • マウス追従パーティクル(インタラクティブな体験)
  • 星空パーティクル(ロマンチックな雰囲気)
  • 爆発パーティクル(インパクト大の演出)
  • 浮遊パーティクル(自然な動き)
ケケンタ

特にランディングページの背景ポートフォリオサイトの装飾には、パーティクル効果が非常に効果的です。この記事のコードをご活用いただきWeb制作の効率化に繋がれば何よりです。

なお、今回ご紹介するアニメーションはCanvas APIを使用した実装なので、高性能で美しいアニメーションが実現できます。

あわせて読みたい




Amazon Kindle日替わりセールバナー


ケケンタ

ケケンタのITブログでは、WebアプリPHPLaravel)やWeb制作WordPressコーディング)について情報を発信しています。
学習中の方や実務をされている方など多くの方にアクセスいただいていますので、ぜひほかの記事も参考にしてみてください!


運動不足、気になっていませんか?

もしプログラミング学習やお仕事で運動不足が気になっているなら

連続屈伸運動がおすすめです!

ボタンにカーソルを合わせるだけ
カウントダウンが始まるタイマーをご用意してみました!

ケケンタ

無理のない範囲で、ぜひ隙間時間に屈伸運動を取り入れてみて下さい!

タイマースタート

3:00

※運動不足だと連続3分で取り組んでもかなり息が切れます
(僕は加えて気分もちょっと悪くなりました……)
絶対にご無理の無い範囲でお取り組みください!



目次

パーティクル効果とは

パーティクル効果は、小さな粒子が画面上で動くアニメーション効果です。背景装飾やインタラクティブな演出として使用され、ページの視覚的な魅力を大幅に向上させます。

効果的な使用場面

適している場面

  • ランディングページの背景
  • ポートフォリオサイトの装飾
  • ゲームの演出効果
  • イベントページの演出
  • プレゼンテーションの背景

避けるべき場面

  • テキストが読みにくくなる場面
  • 重要な情報の表示部分
  • モバイルデバイスでの重い処理
  • アクセシビリティを重視する場面

実装方法の比較

パーティクル効果難易度視覚的インパクトパフォーマンスブラウザ対応
基本的な
パーティクル
⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
マウス追従
パーティクル
⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
星空パーティクル⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
爆発パーティクル⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
浮遊パーティクル⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

基本的なパーティクル

① デモ

See the Pen 基本的なパーティクル by ケケンタ (@lgshifbg-the-looper) on CodePen.

このパーティクルの特徴
  • シンプルで分かりやすい実装
  • 高いパフォーマンス
  • すべてのブラウザで対応

② HTML

<canvas id="particleCanvas"></canvas>
<div class="content">
    <h1>パーティクル効果</h1>
    <p>美しい粒子アニメーション</p>
</div>

Canvas要素を背景に配置し、その上にコンテンツを重ねる構造です。

③ CSS

body {
    margin: 0;
    overflow: hidden;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

canvas {
    display: block;
}

.content {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    color: white;
    z-index: 10;
}

④ JavaScript

class Particle {
    constructor(canvas, options = {}) {
        this.canvas = canvas;
        this.ctx = canvas.getContext('2d');
        this.particles = [];
        this.options = {
            particleCount: options.particleCount || 100,
            particleSize: options.particleSize || 2,
            particleColor: options.particleColor || '#ffffff',
            particleSpeed: options.particleSpeed || 1,
            ...options
        };

        this.init();
    }

    init() {
        this.resize();
        this.createParticles();
        this.animate();

        window.addEventListener('resize', () => this.resize());
    }

    resize() {
        this.canvas.width = window.innerWidth;
        this.canvas.height = window.innerHeight;
    }

    createParticles() {
        for (let i = 0; i < this.options.particleCount; i++) {
            this.particles.push({
                x: Math.random() * this.canvas.width,
                y: Math.random() * this.canvas.height,
                vx: (Math.random() - 0.5) * this.options.particleSpeed,
                vy: (Math.random() - 0.5) * this.options.particleSpeed,
                size: Math.random() * this.options.particleSize + 1
            });
        }
    }

    animate() {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

        this.particles.forEach(particle => {
            // 粒子の移動
            particle.x += particle.vx;
            particle.y += particle.vy;

            // 画面端での跳ね返り
            if (particle.x < 0 || particle.x > this.canvas.width) {
                particle.vx *= -1;
            }
            if (particle.y < 0 || particle.y > this.canvas.height) {
                particle.vy *= -1;
            }

            // 粒子の描画
            this.ctx.beginPath();
            this.ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
            this.ctx.fillStyle = this.options.particleColor;
            this.ctx.fill();
        });

        requestAnimationFrame(() => this.animate());
    }
}

// 初期化
document.addEventListener('DOMContentLoaded', () => {
    const canvas = document.getElementById('particleCanvas');
    new Particle(canvas, {
        particleCount: 100,
        particleSize: 2,
        particleColor: '#ffffff',
        particleSpeed: 1
    });
});

⑤ カスタマイズ例

// カラフルなパーティクル
new Particle(canvas, {
    particleCount: 150,
    particleSize: 3,
    particleColor: '#ff6b6b',
    particleSpeed: 2
});

// 大きなパーティクル
new Particle(canvas, {
    particleCount: 50,
    particleSize: 5,
    particleColor: '#4ecdc4',
    particleSpeed: 0.5
});

// 高速パーティクル
new Particle(canvas, {
    particleCount: 200,
    particleSize: 1,
    particleColor: '#45b7d1',
    particleSpeed: 3
});

マウス追従パーティクル

① デモ

See the Pen マウス追従パーティクル by ケケンタ (@lgshifbg-the-looper) on CodePen.

このパーティクルの特徴
  • マウスカーソルを追従
  • インタラクティブな体験
  • ユーザーの動きに反応

② HTML

<canvas id="particleCanvas"></canvas>
<div class="content">
    <h1>マウス追従パーティクル</h1>
    <p>マウスを動かしてパーティクルを追従させてみてください</p>
</div>

③ CSS

body {
    margin: 0;
    overflow: hidden;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

canvas {
    display: block;
}

.content {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    color: white;
    z-index: 10;
}

④ JavaScript

class MouseParticle {
    constructor(canvas, options = {}) {
        this.canvas = canvas;
        this.ctx = canvas.getContext('2d');
        this.particles = [];
        this.mouse = { x: 0, y: 0 };
        this.options = {
            particleCount: options.particleCount || 50,
            particleSize: options.particleSize || 3,
            particleColor: options.particleColor || '#ffffff',
            particleSpeed: options.particleSpeed || 0.1,
            ...options
        };

        this.init();
    }

    init() {
        this.resize();
        this.createParticles();
        this.animate();

        window.addEventListener('resize', () => this.resize());
        this.canvas.addEventListener('mousemove', (e) => {
            this.mouse.x = e.clientX;
            this.mouse.y = e.clientY;
        });
    }

    resize() {
        this.canvas.width = window.innerWidth;
        this.canvas.height = window.innerHeight;
    }

    createParticles() {
        for (let i = 0; i < this.options.particleCount; i++) {
            this.particles.push({
                x: Math.random() * this.canvas.width,
                y: Math.random() * this.canvas.height,
                size: Math.random() * this.options.particleSize + 1
            });
        }
    }

    animate() {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

        this.particles.forEach(particle => {
            // マウスへの追従
            const dx = this.mouse.x - particle.x;
            const dy = this.mouse.y - particle.y;

            particle.x += dx * this.options.particleSpeed;
            particle.y += dy * this.options.particleSpeed;

            // 粒子の描画
            this.ctx.beginPath();
            this.ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
            this.ctx.fillStyle = this.options.particleColor;
            this.ctx.fill();
        });

        requestAnimationFrame(() => this.animate());
    }
}

// 初期化
document.addEventListener('DOMContentLoaded', () => {
    const canvas = document.getElementById('particleCanvas');
    new MouseParticle(canvas, {
        particleCount: 50,
        particleSize: 3,
        particleColor: '#ff6b6b',
        particleSpeed: 0.1
    });
});

星空パーティクル

① デモ

See the Pen 星空パーティクル by ケケンタ (@lgshifbg-the-looper) on CodePen.

このパーティクルの特徴
  • 星空のような美しい演出
  • 点滅効果付き
  • ロマンチックな雰囲気

② HTML

<canvas id="particleCanvas"></canvas>
<div class="content">
    <h1>星空パーティクル</h1>
    <p>美しい星空のような演出</p>
</div>

③ CSS

body {
    margin: 0;
    overflow: hidden;
    background: linear-gradient(135deg, #0c0c0c 0%, #1a1a2e 50%, #16213e 100%);
}

canvas {
    display: block;
}

.content {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    color: white;
    z-index: 10;
}

④ JavaScript

class StarParticle {
    constructor(canvas, options = {}) {
        this.canvas = canvas;
        this.ctx = canvas.getContext('2d');
        this.particles = [];
        this.options = {
            particleCount: options.particleCount || 200,
            particleSize: options.particleSize || 1,
            particleColor: options.particleColor || '#ffffff',
            twinkleSpeed: options.twinkleSpeed || 0.02,
            ...options
        };

        this.init();
    }

    init() {
        this.resize();
        this.createParticles();
        this.animate();

        window.addEventListener('resize', () => this.resize());
    }

    resize() {
        this.canvas.width = window.innerWidth;
        this.canvas.height = window.innerHeight;
    }

    createParticles() {
        for (let i = 0; i < this.options.particleCount; i++) {
            this.particles.push({
                x: Math.random() * this.canvas.width,
                y: Math.random() * this.canvas.height,
                size: Math.random() * this.options.particleSize + 0.5,
                opacity: Math.random(),
                twinkleDirection: Math.random() > 0.5 ? 1 : -1
            });
        }
    }

    animate() {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

        this.particles.forEach(particle => {
            // 点滅効果
            particle.opacity += this.options.twinkleSpeed * particle.twinkleDirection;

            if (particle.opacity > 1) {
                particle.opacity = 1;
                particle.twinkleDirection = -1;
            } else if (particle.opacity < 0.1) {
                particle.opacity = 0.1;
                particle.twinkleDirection = 1;
            }

            // 粒子の描画
            this.ctx.beginPath();
            this.ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
            this.ctx.fillStyle = `rgba(255, 255, 255, ${particle.opacity})`;
            this.ctx.fill();
        });

        requestAnimationFrame(() => this.animate());
    }
}

// 初期化
document.addEventListener('DOMContentLoaded', () => {
    const canvas = document.getElementById('particleCanvas');
    new StarParticle(canvas, {
        particleCount: 200,
        particleSize: 1,
        particleColor: '#ffffff',
        twinkleSpeed: 0.02
    });
});

爆発パーティクル

① デモ

See the Pen 爆発パーティクル by ケケンタ (@lgshifbg-the-looper) on CodePen.

このパーティクルの特徴
  • クリック時に爆発効果
  • インパクト大の演出
  • ゲーム的な要素

② HTML

<canvas id="particleCanvas"></canvas>
<div class="content">
    <h1>爆発パーティクル</h1>
    <p>画面をクリックして爆発効果を体験してください</p>
</div>

③ CSS

body {
    margin: 0;
    overflow: hidden;
    background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
}

canvas {
    display: block;
}

.content {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    color: white;
    z-index: 10;
}

④ JavaScript

class ExplosionParticle {
    constructor(canvas, options = {}) {
        this.canvas = canvas;
        this.ctx = canvas.getContext('2d');
        this.particles = [];
        this.explosions = [];
        this.options = {
            particleCount: options.particleCount || 30,
            particleSize: options.particleSize || 3,
            particleColor: options.particleColor || '#ff6b6b',
            explosionSpeed: options.explosionSpeed || 5,
            ...options
        };

        this.init();
    }

    init() {
        this.resize();
        this.animate();

        window.addEventListener('resize', () => this.resize());
        this.canvas.addEventListener('click', (e) => {
            this.createExplosion(e.clientX, e.clientY);
        });
    }

    resize() {
        this.canvas.width = window.innerWidth;
        this.canvas.height = window.innerHeight;
    }

    createExplosion(x, y) {
        const particles = [];
        for (let i = 0; i < this.options.particleCount; i++) {
            const angle = (Math.PI * 2 * i) / this.options.particleCount;
            const velocity = Math.random() * this.options.explosionSpeed + 2;

            particles.push({
                x: x,
                y: y,
                vx: Math.cos(angle) * velocity,
                vy: Math.sin(angle) * velocity,
                size: Math.random() * this.options.particleSize + 1,
                life: 1,
                decay: Math.random() * 0.02 + 0.01
            });
        }

        this.explosions.push(particles);
    }

    animate() {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

        // 爆発パーティクルの更新
        this.explosions.forEach((explosion, explosionIndex) => {
            explosion.forEach((particle, particleIndex) => {
                // 重力効果
                particle.vy += 0.1;

                // 位置更新
                particle.x += particle.vx;
                particle.y += particle.vy;

                // 寿命減少
                particle.life -= particle.decay;

                // 粒子の描画
                if (particle.life > 0) {
                    this.ctx.beginPath();
                    this.ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
                    this.ctx.fillStyle = `rgba(255, 107, 107, ${particle.life})`;
                    this.ctx.fill();
                }
            });

            // 寿命が尽きた爆発を削除
            if (explosion.every(particle => particle.life <= 0)) {
                this.explosions.splice(explosionIndex, 1);
            }
        });

        requestAnimationFrame(() => this.animate());
    }
}

// 初期化
document.addEventListener('DOMContentLoaded', () => {
    const canvas = document.getElementById('particleCanvas');
    new ExplosionParticle(canvas, {
        particleCount: 30,
        particleSize: 3,
        particleColor: '#ff6b6b',
        explosionSpeed: 5
    });
});

浮遊パーティクル

① デモ

See the Pen 浮遊パーティクル by ケケンタ (@lgshifbg-the-looper) on CodePen.

このパーティクルの特徴
  • 自然な浮遊運動
  • 波のような動き
  • リラックス効果

② HTML

<canvas id="particleCanvas"></canvas>
<div class="content">
    <h1>浮遊パーティクル</h1>
    <p>自然な浮遊運動を体験してください</p>
</div>

③ CSS

body {
    margin: 0;
    overflow: hidden;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

canvas {
    display: block;
}

.content {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    color: white;
    z-index: 10;
}

④ JavaScript

class FloatingParticle {
    constructor(canvas, options = {}) {
        this.canvas = canvas;
        this.ctx = canvas.getContext('2d');
        this.particles = [];
        this.time = 0;
        this.options = {
            particleCount: options.particleCount || 80,
            particleSize: options.particleSize || 2,
            particleColor: options.particleColor || '#4ecdc4',
            floatSpeed: options.floatSpeed || 0.01,
            ...options
        };

        this.init();
    }

    init() {
        this.resize();
        this.createParticles();
        this.animate();

        window.addEventListener('resize', () => this.resize());
    }

    resize() {
        this.canvas.width = window.innerWidth;
        this.canvas.height = window.innerHeight;
    }

    createParticles() {
        for (let i = 0; i < this.options.particleCount; i++) {
            this.particles.push({
                x: Math.random() * this.canvas.width,
                y: Math.random() * this.canvas.height,
                size: Math.random() * this.options.particleSize + 1,
                angle: Math.random() * Math.PI * 2,
                speed: Math.random() * 0.5 + 0.5,
                amplitude: Math.random() * 50 + 20
            });
        }
    }

    animate() {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

        this.particles.forEach(particle => {
            // 浮遊運動
            particle.angle += this.options.floatSpeed * particle.speed;

            const floatX = Math.sin(particle.angle) * particle.amplitude;
            const floatY = Math.cos(particle.angle * 0.5) * particle.amplitude * 0.5;

            // 位置更新
            particle.x += floatX * 0.01;
            particle.y += floatY * 0.01;

            // 画面端での処理
            if (particle.x < 0) particle.x = this.canvas.width;
            if (particle.x > this.canvas.width) particle.x = 0;
            if (particle.y < 0) particle.y = this.canvas.height;
            if (particle.y > this.canvas.height) particle.y = 0;

            // 粒子の描画
            this.ctx.beginPath();
            this.ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
            this.ctx.fillStyle = this.options.particleColor;
            this.ctx.fill();
        });

        this.time += this.options.floatSpeed;
        requestAnimationFrame(() => this.animate());
    }
}

// 初期化
document.addEventListener('DOMContentLoaded', () => {
    const canvas = document.getElementById('particleCanvas');
    new FloatingParticle(canvas, {
        particleCount: 80,
        particleSize: 2,
        particleColor: '#4ecdc4',
        floatSpeed: 0.01
    });
});

Q&A

基本的なパーティクルと浮遊パーティクルの違いは何ですか?

2つのパーティクル効果には以下のような違いがあります。

動きの違い

基本的なパーティクル

  • 直線的に移動し、画面端で跳ね返る
  • 固定速度(vx, vy)で規則的な動き
  • 機械的で予測可能な軌道

浮遊パーティクル

  • 正弦波と余弦波を使用した波のような浮遊運動
  • 変化する速度で自然な曲線を描く
  • 有機的でリラックス効果のある動き

技術的な違い

項目基本的なパーティクル浮遊パーティクル
動きパターン直線運動 + 跳ね返り正弦波 + 余弦波
速度固定速度(vx, vy)変化する速度(sin/cos)
方向画面端で反転連続的な方向変化
軌道直線的曲線的・波状
自然さ機械的有機的

実装の違い

基本的なパーティクル

// シンプルな物理演算
particles.push({
    x: Math.random() * this.canvas.width,
    y: Math.random() * this.canvas.height,
    vx: (Math.random() - 0.5) * this.options.particleSpeed,  // 固定速度
    vy: (Math.random() - 0.5) * this.options.particleSpeed,  // 固定速度
    size: Math.random() * this.options.particleSize + 1
});

浮遊パーティクル

// 複雑な浮遊パラメータ
particles.push({
    x: Math.random() * this.canvas.width,
    y: Math.random() * this.canvas.height,
    size: Math.random() * this.options.particleSize + 1,
    angle: Math.random() * Math.PI * 2,        // 角度
    speed: Math.random() * 0.5 + 0.5,          // 個別速度
    amplitude: Math.random() * 50 + 20         // 振幅
});

使い分けのポイント

基本的なパーティクルを使う場面

  • シンプルで洗練された印象を出したい
  • パフォーマンスを重視する
  • 規則的で予測可能な動きが求められる
  • ビジネス系サイトの背景

浮遊パーティクルを使う場面

  • 自然で有機的な印象を出したい
  • リラックス効果を求められる
  • 癒し系サイトやアート系サイト
  • より複雑で魅力的な動きが求められる
パーティクル効果のパフォーマンスを最適化するには?

以下のポイントに注意してパフォーマンスを最適化できます。

パーティクル数の調整

  • デスクトップ: 100個以下を推奨
  • モバイル: 50個以下に調整
  • 低スペックデバイス: 30個以下

描画の最適化

// 画面外のパーティクルは描画しない
if (particle.x > 0 && particle.x < this.canvas.width && 
    particle.y > 0 && particle.y < this.canvas.height) {
    // 描画処理
}
パーティクル効果をレスポンシブ対応させるには?

画面サイズに応じてパーティクル数を調整します。

class ResponsiveParticle {
    constructor(canvas, options = {}) {
        this.canvas = canvas;
        this.ctx = canvas.getContext('2d');
        this.particles = [];
        this.options = options;

        this.init();
    }

    init() {
        this.resize();
        this.createParticles();
        this.animate();

        window.addEventListener('resize', () => {
            this.resize();
            this.createParticles(); // パーティクルを再生成
        });
    }

    resize() {
        this.canvas.width = window.innerWidth;
        this.canvas.height = window.innerHeight;

        // 画面サイズに応じてパーティクル数を調整
        const screenArea = this.canvas.width * this.canvas.height;
        const baseCount = 100;
        const mobileCount = 50;

        if (screenArea < 500000) { // モバイル判定
            this.options.particleCount = mobileCount;
        } else {
            this.options.particleCount = baseCount;
        }
    }
}

まとめ

今回ご紹介した5種類のパーティクル効果はいかがでしたでしょうか?

ケケンタ

それぞれのパーティクル効果には特徴があり、用途に応じて使い分けることで、より魅力的なWebサイトを作成できます。

用途別おすすめパーティクル効果

  • ランディングページ: 基本的なパーティクル or 浮遊パーティクル
  • ポートフォリオサイト: マウス追従パーティクル
  • イベントページ: 星空パーティクル
  • ゲームサイト: 爆発パーティクル
  • リラックス系サイト: 浮遊パーティクル

パフォーマンスのポイント

  • パーティクル数は100個以下を推奨
  • モバイルデバイスでは50個以下に調整
  • requestAnimationFrameを使用してスムーズなアニメーション
  • 不要なパーティクルは適切に削除

カスタマイズのコツ

  • 色やサイズを調整してサイトのテーマに合わせる
  • 速度を調整してユーザビリティを確保
  • 透明度を活用して奥行きを表現
  • 重力や風の効果を追加してリアル感を演出
ケケンタ

これらのパーティクル効果を組み合わせることで、さらに魅力的なアニメーションを作成できます。ぜひご自身のプロジェクトに合わせてカスタマイズしてみてください!

このブログではWeb制作やWordpressなどの情報を発信しています。ご興味のある方はほかの記事もご覧いただけるとうれしいです!

それでは、最後までご覧いただきありがとうございました!

あわせて読みたい

【コピペOK】背景アニメーション完全ガイド|Javascript【5種類の実装方法】のアイキャッチ画像

この記事が気に入ったら
フォローしてね!

この記事が良いと思ったらシェアしてね!

コメント

コメントする

CAPTCHA


目次