HTML + CSS
画面幅いっぱいに表示させたいのでcanvasをdivで囲んでます。
canvas-txtにcanvasの上に表示されるコンテンツを配置します。
html
- <div id="canvas-wrap">
- <canvas id="canvas-container"></canvas>
- <div id="canvas-txt"><p>CONTENTS</p></div>
- </div>
CSSです。
今回はwidth,heightとも100%を指定してますが、pxで数値を指定しても問題ありません。
css
- html,body {
- height: 100%;
- }
- #canvas-wrap {
- width: 100%;
- height: 100%;
- position: relative;
- }
- #canvas-txt {
- font-size: 60px;
- display: flex;
- justify-content: center;
- align-items: center;
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- }
画面サイズいっぱいにCanvasを配置する
単純にcanvasを100%にすると、比率が崩れてしまいます。
一旦親のサイズを取得して設定することで100%表示にすることができます。
javascript
- var canvasWrap = document.querySelector('#canvas-wrap');
- var canvas = document.querySelector('#canvas-container');
- var ctx = canvas.getContext('2d');
- canvas.setAttribute('width', canvasWrap.offsetWidth);
- canvas.setAttribute('height', canvasWrap.offsetHeight);
ランダムな方向に移動するパーティクル
ランダムにパーティクルを配置して、ランダムな方向に移動させてみます。
javascript
- window.requestAnimFrame = (function () {
- return window.requestAnimationFrame ||
- window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- window.oRequestAnimationFrame ||
- window.msRequestAnimationFrame ||
- function (callback) {
- window.setTimeout(callback, 1000 / 60);
- };
- })();
- window.onload = function() {
- var canvasWrap = document.querySelector('#canvas-wrap');
- var canvas = document.querySelector('#canvas-container');
- var ctx = canvas.getContext('2d');
- var center = {}; // Canvas中央
- var dots = []; // パーティクル配列
- var density = 70; //パーティクルの数
- var colors = ['#eeb900', '#6DD0A5', '#f799db'];
- var baseSize = 3; // 大きさ
- var baseSpeed = 10; // スピード
- var Dot = function () {
- this.size = Math.floor( Math.random() * 6 ) + baseSize; //大きさ
- this.color = colors[~~(Math.random() * 3)]; //色
- this.speed = this.size / baseSpeed; // 大きさによって速度変更
- this.pos = { // 位置
- x: Math.random() * canvas.width,
- y: Math.random() * canvas.height
- };
- var rot = Math.random() * 360; // ランダムな角度
- var angle = rot * Math.PI / 180;
- this.vec = { // 移動方向
- x: Math.cos(angle) * this.speed,
- y: Math.sin(angle) * this.speed
- };
- };
- Dot.prototype = {
- update: function() {
- this.draw();
- this.pos.x += this.vec.x;
- this.pos.y += this.vec.y;
- // 画面外に出たら反対へ再配置
- if(this.pos.x > canvas.width + 10) {
- this.pos.x = -5;
- } else if(this.pos.x < 0 - 10) {
- this.pos.x = canvas.width + 5;
- } else if(this.pos.y > canvas.height + 10) {
- this.pos.y = -5;
- } else if(this.pos.y < 0 - 10) {
- this.pos.y = canvas.height + 5;
- }
- },
- draw: function() {
- ctx.fillStyle = this.color;
- ctx.beginPath();
- ctx.arc(this.pos.x, this.pos.y, this.size, 0, 2 * Math.PI, false);
- ctx.fill();
- }
- };
- function update() {
- requestAnimFrame(update);
- // 描画をクリアー
- ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
- for (var i = 0; i < density; i++) {
- dots[i].update();
- }
- }
- function init() {
- // canvasにコンテンツサイズをセット
- canvas.setAttribute("width", canvasWrap.offsetWidth);
- canvas.setAttribute("height", canvasWrap.offsetHeight);
- // canvas中央をセット
- center.x = canvas.width / 2;
- center.y = canvas.height / 2;
- // densityの数だけパーティクルを生成
- for (var i = 0; i < density; i++) {
- dots.push(new Dot());
- }
- update();
- }
- init();
- }
ほとんどがCanvasアニメーションの基本的な部分になりますが、重要なところは32行目あたりからです。
横方向の場合単純にx軸の値を変更していけばよかったのですが、斜めに移動させたいときはy軸も変動させる必要があります。
角度から移動方向のx、yを決めるには三角関数で結果がでます。
実際は難しい事考える必要はなく、例えば45度に移動したいときは下記のようなコードになります。
- var angle = 45 * Math.PI / 180;
- this.vec = {
- x: Math.cos(angle),
- y: Math.sin(angle)
- };
vec
が移動方向になりますので、update
のときにこと値を足す事で指定した方向へ移動することができます。
- this.pos.x += this.vec.x;
- this.pos.y += this.vec.y;
中央から拡散するパーティクル
中央から外側に拡散するような動きをしてみます。
Dot
部分のみ変更します。
javascript
- var Dot = function () {
- this.size = Math.floor( Math.random() * 6 ) + baseSize; //大きさ
- this.color = colors[~~(Math.random() * 3)]; //色
- this.speed = this.size / baseSpeed; // 大きさによって速度変更
- this.pos = { // 位置
- x: canvas.width / 2,
- y: canvas.height / 2
- };
- var rot = Math.random() * 360; // ランダムな角度
- var angle = rot * Math.PI / 180;
- this.vec = { // 移動方向
- x: Math.cos(angle) * this.speed,
- y: Math.sin(angle) * this.speed
- };
- // ランダムに配置
- var startRandom = Math.random();
- this.pos.x += this.vec.x * (startRandom * center.x);
- this.pos.y += this.vec.y * (startRandom * center.y);
- };
- Dot.prototype = {
- update: function() {
- this.pos.x += this.vec.x;
- this.pos.y += this.vec.y;
- if(this.pos.x > canvas.width + baseSize
- || this.pos.x < 0 - baseSize
- || this.pos.y > canvas.height + baseSize
- || this.pos.y < 0 - baseSize) {
- this.pos.x = center.x;
- this.pos.y = center.y;
- }
- },
- draw: function() {
- ctx.fillStyle = this.color;
- ctx.beginPath();
- ctx.arc(this.pos.x, this.pos.y, this.size, 0, 2 * Math.PI, false);
- ctx.fill();
- }
- };
開始位置のpos
をcanvas中央に指定して、画面外に出た時も再配置も同じくcanvas中央にしているだけですね。
この作りだとパーティクルの数を直接指定しているので、画面サイズによって密度が変わってきてしまいます。
この部分は画面サイズによって変動させるなどの処理が必要になってくると思います。