JavaScriptで画像を大きくしたり、小さくしたりする処理を作る。ゲームでボタンを押した時、押し広がるアニメーションなどに使える。
まず、ボタン画像を表示するクラスを用意。button.jsは画像を読み込んで表示する簡単なクラス。さらに必要最低限のゲッターとセッターを実装。
/**
* ボタン画像を表示
*/
export class Button {
constructor(parent = undefined, x = 0, y = 0) {
if (parent !== undefined) {
this._parent = parent;
}
this._x = x;
this._y = y;
this._scaleX = 1;
this._scaleY = 1;
this._img;
this._init();
}
//////////////////////////////////
// Private and protected
//////////////////////////////////
_init() {
if (this._parent !== undefined) {
this._ctx = this._parent;
}
this._img = new Image();
this._img.src = "./button.png";
this.draw();
}
//////////////////////////////////
// Public
//////////////////////////////////
draw() {
// 現在の描画状態を保存
this._ctx.save();
// コンテキストの座標を変更し、キャンバス中央に移動
this._ctx.translate(this._x, this._y);
// コンテキストのスケールを指定
this._ctx.scale(this._scaleX, this._scaleY);
this._ctx.drawImage(this._img, -(this._img.width / 2), -(this._img.height / 2));
// save()で保存した描画状態を復元
// 変形情報(translate、scale)を描画前に戻している
this._ctx.restore();
}
//////////////////////////////////
// Getters/Setters
//////////////////////////////////
get x() {
return this._x;
}
set x(x) {
this._x = x;
}
get y() {
return this._y;
}
set y(y) {
this._y = y;
}
get scaleX() {
return this._scaleX;
}
set scaleX(scalex) {
this._scaleX = scalex;
}
get scaleY() {
return this._scaleY;
}
set scaleY(scaley) {
this._scaleY = scaley;
}
}
stretch.jsはbuttonクラスを使いボタン画像を表示、タイマーでスケール値を加減して画像を伸縮させる。requestAnimationFrameを使ったゲームループの実装は、「【JavaScript】requestAnimationFrameでゲームループを作る」を参照。
import { Button } from "./button.js";
/**
* stretch.js
*/
export class Stretch {
constructor() {
this._cvs = document.getElementById('canvas');
this._ctx = this._cvs.getContext('2d');
this._button;
this._angle = 0; // 角度
this._centerScale = 1; // 基準となる元のスケール
this._range = 0.5; // 伸縮する範囲
this._speed = 0.05; // 伸縮する速度
// タイマー関連
this._animID;
this._isAnim = 0;
this._FPS = 60;
this._frame = 0;
this._startTime;
this._nowTime;
this._init();
}
//////////////////////////////////
// Private and protected
//////////////////////////////////
_init() {
this._cvs.style.backgroundColor = "#ccc";
this._button = new Button(this._ctx, this._cvs.width / 2, this._cvs.height / 2);
this._startTime = performance.now();
this._mainLoop();
}
_mainLoop() {
this._nowTime = performance.now();
let elapsedTime = this._nowTime - this._startTime;
let idealTime = this._frame * (1000 / this._FPS);
if (idealTime < elapsedTime) {
this._ctx.clearRect(0, 0, this._cvs.width, this._cvs.height);
// ①図形が伸縮する処理部分
this._button.scaleX = this._button.scaleY = this._centerScale + Math.sin(this._angle) * this._range;
this._angle += this._speed;
this._button.draw();
this._frame++;
if (elapsedTime >= 1000) {
this._startTime = this._nowTime;
this._frame = 0;
}
}
this._animID = requestAnimationFrame(this._mainLoop.bind(this));
}
}
画像を伸縮させているのはコード①の箇所。Math.sin()を使い、三角関数のサイン波の動きを伸縮する動きに応用している。
三角関数に関しては「【JavaScript】オブジェクトを回転させる」参照。
以下はhtml。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JavaScriptでcanvasの画像を伸縮させる</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
</body>
<script type="module">
import { Stretch } from "./stretch.js";
window.onload = function () {
let s = new Stretch();
}
</script>
</html>
リンク
リンク

コメント