質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.85%

Sketch.jsのパーティクルの実装をbackroundに指定したい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,403

MASA08

score 20

現在以下のサイトを見てsketch.jsのparticleの実装を行なっています。
http://soulwire.github.io/sketch.js/examples/particles.html

基本的にはコードをコピペしているだけです。

このような実装を例えば

<div class="main"></div>


のbackgroundとして表示するやり方を調べているのですが、なかなか答えが見つかりません。

どなたかお教えしていただくことは可能でしょうか?

なお、開発はrailsで行なっており、現在はhtml.erbのファイルにsketch.jsを読み込ませて、上記サイトのhtmlファイルに記述されているscriptをコピペしている状態です。

追記
現在、railsで開発をしていて、index.html.erbは下記のようになっております。

<canvas id="canvas"></canvas>
<section id="body">
// 中身
</section>

<script src="../js/sketch.js"></script>
<script>

    // ---------------------------------------- Particle ----------------------------------------
    function Particle(x, y, radius) {
        this.init(x, y, radius);
    }
    Particle.prototype = {
        init: function (x, y, radius) {
            this.alive = true;
            this.radius = radius || 10;
            this.wander = 0.15;
            this.theta = random(TWO_PI);
            this.drag = 0.92;
            this.color = '#fff';
            this.x = x || 0.0;
            this.y = y || 0.0;
            this.vx = 0.0;
            this.vy = 0.0;
        },
        move: function () {
            this.x += this.vx;
            this.y += this.vy;
            this.vx *= this.drag;
            this.vy *= this.drag;
            this.theta += random(-0.5, 0.5) * this.wander;
            this.vx += sin(this.theta) * 0.1;
            this.vy += cos(this.theta) * 0.1;
            this.radius *= 0.96;
            this.alive = this.radius > 0.5;
        },
        draw: function (ctx) {
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.radius, 0, TWO_PI);
            ctx.fillStyle = this.color;
            ctx.fill();
        }
    };
    // ---------------------------------------- Example ----------------------------------------
    var MAX_PARTICLES = 280;
    var COLOURS = [
        '#69D2E7',
        '#A7DBD8',
        '#E0E4CC',
        '#F38630',
        '#FA6900',
        '#FF4E50',
        '#F9D423'
    ];
    var particles = [];
    var pool = [];
    var demo = Sketch.create({container: document.getElementById('canvas'), retina: 'auto'});
    demo.setup = function () {
        // Set off some initial particles.
        var i,
            x,
            y;
        for (i = 0; i < 20; i++) {
            x = (demo.width * 0.5) + random(-100, 100);
            y = (demo.height * 0.5) + random(-100, 100);
            demo.spawn(x, y);
        }
    };
    demo.spawn = function (x, y) {

        var particle,
            theta,
            force;
        if (particles.length >= MAX_PARTICLES)
            pool.push(particles.shift());
        particle = pool.length
            ? pool.pop()
            : new Particle();
        particle.init(x, y, random(5, 40));
        particle.wander = random(0.5, 2.0);
        particle.color = random(COLOURS);
        particle.drag = random(0.9, 0.99);
        theta = random(TWO_PI);
        force = random(2, 8);
        particle.vx = sin(theta) * force;
        particle.vy = cos(theta) * force;
        particles.push(particle);
    };
    demo.update = function () {
        var i,
            particle;
        for (i = particles.length - 1; i >= 0; i--) {
            particle = particles[i];
            if (particle.alive)
                particle.move();
            else
                pool.push(particles.splice(i, 1)[0]);
            }
        };
    demo.draw = function () {
        demo.globalCompositeOperation = 'lighter';
        for (var i = particles.length - 1; i >= 0; i--) {
            particles[i].draw(demo);
        }
    };
    demo.mousemove = function () {
        var particle,
            theta,
            force,
            touch,
            max,
            i,
            j,
            n;
        for (i = 0, n = demo.touches.length; i < n; i++) {
            touch = demo.touches[i],
            max = random(1, 4);
            for (j = 0; j < max; j++) {
                demo.spawn(touch.x, touch.y);
            }
        }
    };
</script>

ですがスケッチが背景に指定されません。どなたか回答お願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2018/02/02 00:00

    sketch.jsでは?タイトルと本文がSlick.jsになっています。

    キャンセル

  • MASA08

    2018/02/02 00:02

    その通りです!修正します。ご指摘ありがとうございます!

    キャンセル

回答 3

+1

sketch.jsはCanvas要素に描画しているので、直接CSSのbackgroundに設定することはできませんが、下記のような方法があるようです。

【背景をCanvasにする - Qiita】
https://qiita.com/mohayonao/items/e96e68aedc04a37f0c6d

【Canvasを背景に設定する | office606】
https://office606.org/archives/181/


sketch.js の使い方の問題では?

    <div id="canvas"></div><!-- この中にcanvas要素ができる仕様だから失敗していたのでは? -->
    <section id="body">
    /* 実際のbodyはここに書く */
    </section>

https://jsfiddle.net/w2veuL6g/

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/02 12:38

    ご回答ありがとうございます。しかしながらスケッチが背景に表示されません。上記質問に追記します。

    キャンセル

  • 2018/02/02 12:45

    CSSが書かれていませんが・・・。

    キャンセル

  • 2018/02/02 13:37

    あ、すいません。
    CSSは
    #canvas {
    position:fixed;
    top:0;
    left:0;
    width:100%;
    height:100%;
    }

    #body {
    position:absolute;
    top:0;
    left:0;
    }
    を記述しています

    キャンセル

+1

質問の内容が曖昧なため, 勝手に想像して回答します. なおsketch.js利用の有無は考えず, あくまでcanvas要素汎用の内容としています.


要件を下記と仮定します.

  • div要素を用意し, その範囲にcanvas要素のグラフィックを"背景"画像として描画したい.
    "背景"というのはdiv要素が内包しているコンテンツの(z-indexの意味における)最下部を指す.
  • div要素上にカーソルを当てると, その位置に応じてcanvasグラフィックが変化する.

上記のもとで最も簡単なコードを提示します.

<div>
<canvas></canvas>
div要素内のコンテンツ
</div>
div{
    position: relative;
    width: 500px;
    height: 500px;
}
div>canvas{/*canvas要素を背景っぽく配置するスタイル*/
    position: absolute;
    width: 100%;
    height: 100%;
    z-index:-1;
    pointer-events: none;
    background-color: pink;
}
"use strict";
document.addEventListener("DOMContentLoaded", e => {
    const div = document.querySelector("div");
    const canvas = div.querySelector("canvas");
    //canvas要素のサイズをdiv要素に合わせる
    const style = window.getComputedStyle(canvas);
    [canvas.width, canvas.height] = [parseInt(style.width), parseInt(style.height)];
    const ctx = canvas.getContext("2d");

    //(1)イベントはdiv要素で受ける場合
    div.onmousemove = e => {
        //例えばパーティクルの描画処理
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        const [x, y] = [e.offsetX, e.offsetY];
        ctx.fillRect(x - 2, y - 2, 4, 4);
    };

    //--------------------------------------------------------

    //(2)canvas側の処理を触れない場合
    //canvas側の描画処理(元からあるものを触らない)
    canvas.onmousemove = e => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        const [x, y] = [e.offsetX, e.offsetY];
        ctx.fillRect(x - 2, y - 2, 4, 4);
    };
    //div要素で受けたイベントを元にcanvas要素側のイベントをトリガ
    //NOTE:パラメータは必要に応じて追加する
    div.onmousemove = e => {
        canvas.dispatchEvent(new MouseEvent("mousemove", {
            bubbles: false,//これがないと無限ループする
            clientX: e.clientX,
            clientY: e.clientY,
            offsetX: e.offsetX,
            offsetY: e.offsetY
        }));
    };
});

HINT:

  • 既にcanvas要素の描画処理が実装済みの場合は, canvas要素に対するリスナ登録をdiv要素に振り分ける(もしくはdispatchEventメソッドを使ってdiv要素でのイベント発生時にcanvas要素側のイベントをトリガする)ようにします.
  • (ウィンドウリサイズ等により)div要素のサイズが変化する場合は, リサイズ時(resizeイベント), もしくは定期的にcanvas要素のサイズも変更する必要があります.

NOTE:
FireFox/Safari系ブラウザであれば, それぞれ個別のAPIを用いてcanvas要素を任意要素の背景とすることが可能です.(-moz-element,mozSetImageElement/-webkit-canvas,getCSSCanvasContextで調べてみよう)
※Chromeでは機能が廃止されています.

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/02 13:27

    demo.mousemove = function () {
    の部分でsketch.jsのAPIを使っているから, dispatchEventを使うしか無いかな

    キャンセル

check解決した方法

0

色々と回答をしていただいて大変申し訳ないのですが、他のプラグインを使わせていただきました。ありがとうございました。。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/25 12:36

    質問をクローズするのであれば, どのように解決したのか(今回は他のプラグインの詳細)について記述してください.

    キャンセル

  • 2018/02/25 13:03

    defghi1997さん、ご返信ありがとうございます。そして今回は質問にご回答いただきありがとうございました。今回はもともとbackgroundで「お祝い感を出したい」をいう目的でsketchをしようしようと思っていたのですが、力不足で実装ができなかったため、Confetti.js(https://codepen.io/tag/confetti/)を使用させていただきました。色々と丁寧にご回答いただき、またそれにも関わらず失礼なクローズの仕方をしてしまい申し訳ありませんでした。

    キャンセル

  • 2018/02/25 13:15

    なんら解決策を示さずに質問をクローズしてはならない理由は「同じような問題を抱えている人」がこの記事にたどり着いた時を踏まえてのことです. また, 無駄に解決済とすることでかえって真の解決策の提示を妨げる可能性があります.
    要は質問がパブリックなものとなったことでこの質問は既にあなただけのものではないのです.

    キャンセル

  • 2018/02/25 16:00

    確かにその通りですね。
    非常に勉強になりました。考え方を改めます。指摘していただきありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.85%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る