HTML5およびEaselJSで3月8日のグリーティングカードを作成する



(写真はクリック可能で祝福的です)

一般的なアイデア :美しい写真の背景に飛び回る蝶と春の音楽。 ( 1年前に行ったSilverlightバージョンのハガキもあったことをすぐに認めます。Silverlightの 蝶アニメーションのレッスン

標準のCSSツールに加えて、HTML5 CanvasとEaselJSアニメーションライブラリを使用して、ポストカードレンダリングます

バタフライアニメーション



あなたはすでに蝶を準備しており、対応する絵の形で個々の翼を持っているという仮定から始めます。



ステップ1.翼を描く

ほんの数枚の翼を描くことから始めましょう。 それぞれの翼を描くには、ダウンロードした画像に基づいて作成するオブジェクトであるBitmapクラスが必要です。 翼をまとめるには、 Containerクラスが必要です。 EaselJSでシーンをレンダリングするためのStageクラスがあります。

画像をアップロードする
イメージをダウンロードするには、対応するイベントをハングアップして標準イメージを使用する必要があります。

// loading left wing
leftImg = new Image();
leftImg.src = leftSrc;
leftImg.onload = onWingImageLoaded;

// loading right wing
rightImg = new Image();
rightImg.src = rightSrc;
rightImg.onload = onWingImageLoaded;


(理想的には、ブートエラーでイベントをハングアップして、正しく処理する必要もあります。)

バタフライアセンブリ
両方のウィングがロードされた後、それらを1つのコンテナに組み立てる必要があり、全体として操作できます。

// create a new container for butterfly wings
var butterfly = new Container();
// create wings
var lWing = new Bitmap(leftImg);
var rWing = new Bitmap(rightImg);

// assemble a batterfly
butterfly.addChild(lWing);
butterfly.addChild(rWing);


それぞれの翼のコンテナ内で、基準点を移動する必要があります。基準点を基準にして、それらを配置してから回転します。

// change wings registration point inside container
lWing.regX = lWing.image.width;
lWing.regY = lWing.image.height / 2;
rWing.regX = 0;
rWing.regY = rWing.image.height / 2;


バタフライ配置
次に、蝶をシーンに追加し、適切な場所に配置して、シーンのレンダリングを開始します。

// add butterfly to stage
stage.addChild(butterfly);

// change batterfly position
butterfly.x = canvas.width * Math.random() | 0;
butterfly.y = canvas.height * Math.random() | 0;

// redraw stage
stage.update();


共通コード
var leftSrc = "../images/Cypres 1.png" ;
var rightSrc = "../images/Cypres 2.png" ;
var leftImg;
var rightImg;
var loadedWings = 0;

function init() {
// create a new stage and point it at our canvas:
canvas = document .getElementById( "canvas" );
stage = new Stage(canvas);

// loading left wing
leftImg = new Image();
leftImg.src = leftSrc;
leftImg.onload = onWingImageLoaded;

// loading right wing
rightImg = new Image();
rightImg.src = rightSrc;
rightImg.onload = onWingImageLoaded;
}

function onWingImageLoaded( event ) {
loadedWings++;
if (loadedWings == 2)
onButterflyReady();
}

function onButterflyReady() {
// create a new container for butterfly wings
var butterfly = new Container();
// create wings
var lWing = new Bitmap(leftImg);
var rWing = new Bitmap(rightImg);

// assemble a batterfly
butterfly.addChild(lWing);
butterfly.addChild(rWing);

// change wings registration point inside container
lWing.regX = lWing.image.width;
lWing.regY = lWing.image.height / 2;
rWing.regX = 0;
rWing.regY = rWing.image.height / 2;


// add butterfly to stage
stage.addChild(butterfly);

// change batterfly position
butterfly.x = canvas.width * Math.random() | 0;
butterfly.y = canvas.height * Math.random() | 0;

// redraw stage
stage.update();
}




完成した例はここにあります: 例1

ステップ2.羽ばたく

タイマー
さまざまな方法でアニメーションまたは順次イベントを実行できます。 EaselJSでは、シーン更新タイマーをサブスクライブして、すべてのステップで変更を加えることができます。 (これは、シーンがタイマーに描画されるゲーム状態更新サイクルに似ています。)

まず、タイマーをサブスクライブする必要があります(応答頻度も設定できます)。

Ticker.addListener(window);


次に、ウィンドウのスコープでtick関数を定義する必要があります。その中で、シーンの状態を更新し、レンダリングを開始する必要があります。

// update scene on each tick
function tick() {
butterfly.move()
stage.update();
}


翼の段階的なアニメーション
蝶のアニメーションを説明するには、羽ばたく翼と動きをすべて別々のステップに分割する必要があります。 しかし、最初に、蝶の初期状態を決定する別のパラメーター-初期スケールを設定しましょう(原則として、異なるサイズの蝶を作成する予定がない場合、スケール= 1.0に設定できません):

// initial scale
butterfly.scale = butterfly.lWing.scaleX
= butterfly.lWing.scaleY = butterfly.rWing.scaleX
= butterfly.rWing.scaleY = 0.5 + 0.2 * Math.random();


水平方向(X方向)のスケーリングを介して翼のアニメーションを行うのが適切であり、周期性に三角関数を使用できます。

アニメーションのステップ数を設定しましょう:

// animation steps
butterfly.step = butterfly.steps = 40 + 60 * Math.random();


ここで、各ウェーブを説明する必要があります。

butterfly.move = function () {
var wingAngle = (butterfly.steps - butterfly.step) / butterfly.steps * Math.PI;
butterfly.lWing.scaleX = butterfly.rWing.scaleX
= butterfly.scale * (0.4 + 0.6 * Math.abs(Math.cos(wingAngle * 4)));

butterfly.step--;
}


共通コード
var leftSrc = "../images/Cypres 1.png" ;
var rightSrc = "../images/Cypres 2.png" ;
var leftImg;
var rightImg;
var loadedWings = 0;
var butterfly;
var butterflyLoaded = false ;

function init() {
// create a new stage and point it at our canvas:
canvas = document .getElementById( "canvas" );
stage = new Stage(canvas);

// loading left wing
leftImg = new Image();
leftImg.src = leftSrc;
leftImg.onload = onWingImageLoaded;

// loading right wing
rightImg = new Image();
rightImg.src = rightSrc;
rightImg.onload = onWingImageLoaded;

// subscribe to Ticker
Ticker.addListener(window);
}

function onWingImageLoaded( event ) {
loadedWings++;
if (loadedWings == 2)
onButterflyReady();
}

function onButterflyReady() {
// create a new container for butterfly wings
butterfly = new Container();
// create wings
butterfly.lWing = new Bitmap(leftImg);
butterfly.rWing = new Bitmap(rightImg);

// assemble a batterfly
butterfly.addChild(butterfly.lWing);
butterfly.addChild(butterfly.rWing);

// change wings registration point inside container
butterfly.lWing.regX = butterfly.lWing.image.width;
butterfly.lWing.regY = butterfly.lWing.image.height / 2;
butterfly.rWing.regX = 0;
butterfly.rWing.regY = butterfly.rWing.image.height / 2;


// add butterfly to stage
stage.addChild(butterfly);

// change batterfly position
butterfly.x = canvas.width * Math.random() | 0;
butterfly.y = canvas.height * Math.random() | 0;

// initial rotation
butterfly.lWing.rotation = butterfly.rWing.rotation
= butterfly.angle = 360 * Math.random() | 0;

// initial scale
butterfly.scale = butterfly.lWing.scaleX
= butterfly.lWing.scaleY = butterfly.rWing.scaleX
= butterfly.rWing.scaleY = 0.5 + 0.2 * Math.random();

// animation steps
butterfly.step = butterfly.steps = 40 + 60 * Math.random();

// move butterfly
butterfly.move = function () {
var wingAngle = (butterfly.steps - butterfly.step) / butterfly.steps * Math.PI;
butterfly.lWing.scaleX = butterfly.rWing.scaleX
= butterfly.scale * (0.4 + 0.6 * Math.abs(Math.cos(wingAngle * 4)));

butterfly.step--;
}

butterflyLoaded = true ;

// redraw stage
stage.update();
}

// update scene on each tick
function tick() {
if (butterflyLoaded && butterfly.step >= 0) {
butterfly.move()
}
stage.update();
}




完成した例は、 例2にあり ます。

ステップ3.バタフライを移動する

蝶に羽ばたきを教えるようになったので、蝶を動かしてみましょう。 これを行うには、回転角度と移動の方向と速度を考慮する必要があります。

// initial rotation
butterfly.lWing.rotation = butterfly.rWing.rotation
= butterfly.angle = 360 * Math.random() | 0;
// movement direction
butterfly.direction = 8 * Math.random() - 4.0;
// movement speed
butterfly.speed = 5 * Math.random() + 5;


butterfly.move関数内では、回転角度の変更を追加するために残ります。

butterfly.angle += butterfly.direction + (5.0 * Math.random() - 2.5);
butterfly.lWing.rotation = butterfly.rWing.rotation = butterfly.angle;


および移動の増分:

butterfly.x += (butterfly.speed * Math.sin((butterfly.angle) / 180.0 * Math.PI));
butterfly.y -= (butterfly.speed * Math.cos((butterfly.angle) / 180.0 * Math.PI));


蝶が飛ぶはずです。



完成した例はここにあります: 例3

ステップ4.コードを作成する

その後、蝶のコレクション全体を処理する必要があるため、別のブロックで蝶の作業の説明を含むコードを選択するのが論理的です(マウスに対する追加の反応も青色で強調表示されます)。

( function (window) {

Butterfly = function (leftImg, rightImg) {
this .initialize();
this .initButterfly(leftImg, rightImg);
}

var p = Butterfly.prototype = new Container();

p.lWing = null ;
p.rWing = null ;
p.angle = 0;
p.direction = 0;
p.speed = 0;

p.steps = 0;
p.step = -1;

p.initButterfly = function (leftImg, rightImg) {
// create wings
this .lWing = new Bitmap(leftImg);
this .rWing = new Bitmap(rightImg);

// change wings registration point inside container
this .lWing.regX = this .lWing.image.width;
this .lWing.regY = this .lWing.image.height / 2;
this .rWing.regX = 0;
this .rWing.regY = this .rWing.image.height / 2;

// initial rotation
this .lWing.rotation = this .rWing.rotation = this .angle = 360 * Math.random() | 0;

// initial scale
this .scale = this .lWing.scaleX = this .lWing.scaleY = this .rWing.scaleX = this .rWing.scaleY = 0.5 + 0.2 * Math.random();

// assembling batterfly
this .addChild( this .lWing);
this .addChild( this .rWing);

this .mouseEnabled = true ;
this .onMouseOver = function (e) { this .reset(); };
};

p.reset = function () {
// animation steps
this .step = this .steps = 40 + 60 * Math.random();
// movement direction
this .direction = 8 * Math.random() - 4.0;
// movement speed
this .speed = 5 * Math.random() + 5;
};

p.move = function () {
// update rotation
this .angle += this .direction + (5.0 * Math.random() - 2.5);
this .lWing.rotation = this .rWing.rotation = this .angle;

// update wings
var wingAngle = ( this .steps - this .step) / this .steps * Math.PI;
this .lWing.scaleX = this .rWing.scaleX = this .scale * (0.4 + 0.6 * Math.abs(Math.cos(wingAngle * 4)));

// update position
this .x += ( this .speed * Math.sin(( this .angle) / 180.0 * Math.PI));
this .y -= ( this .speed * Math.cos(( this .angle) / 180.0 * Math.PI));
this .step--;
};

p.isActive = function () {
return this .step >= 0;
};

window.Butterfly = Butterfly;
} (window));


残りのコードは少し簡略化されていますが、マウスからのイベントトラッキングを有効にする必要もあります。

var leftSrc = "../images/Cypres 1.png" ;
var rightSrc = "../images/Cypres 2.png" ;
var leftImg;
var rightImg;
var loadedWings = 0;
var butterfly;
var butterflyLoaded = false ;

function init() {
// create a new stage and point it at our canvas:
canvas = document .getElementById( "canvas" );
stage = new Stage(canvas);
stage.enableMouseOver(10);

// loading left wing
leftImg = new Image();
leftImg.src = leftSrc;
leftImg.onload = onWingImageLoaded;

// loading right wing
rightImg = new Image();
rightImg.src = rightSrc;
rightImg.onload = onWingImageLoaded;

// subscribe to Ticker
Ticker.addListener(window);
}

function onWingImageLoaded( event ) {
loadedWings++;
if (loadedWings == 2)
onButterflyImagesReady();
}

function onButterflyImagesReady() {
// create a new container for butterfly wings
var butterfly = new Butterfly(leftImg, rightImg);

// add butterfly to stage
stage.addChild(butterfly);

// change batterfly position
butterfly.x = canvas.width * Math.random() | 0;
butterfly.y = canvas.height * Math.random() | 0;

butterfly.reset();
butterflyLoaded = true ;

// redraw stage
stage.update();
}

// update scene on each tick
function tick() {
if (butterflyLoaded && butterfly.step >= 0) {
butterfly.move()
}
stage.update();
}


完成した例はここにあります: 例4

たくさんの蝶


さらに蝶を追加しましょう。 翼の画像アドレスの配列が必要です:

var bfimgsrc = [{ left: "../images/Didius 1.png" , right: "../images/Didius 2.png" },
{ left: "../images/Amphitrion 1.png" , right: "../images/Amphitrion 2.png" },
{ left: "../images/Catenarius 1.png" , right: "../images/Catenarius 2.png" },
{ left: "../images/Cyanides 1.png" , right: "../images/Cyanides 2.png" },
{ left: "../images/Cypres 1.png" , right: "../images/Cypres 2.png" },
{ left: "../images/Diana 1.png" , right: "../images/Diana 2.png" },
{ left: "../images/Hecuba 1.png" , right: "../images/Hecuba 2.png" },
{ left: "../images/Peleides 1.png" , right: "../images/Peleides 2.png" },
{ left: "../images/Polyphemus 1.png" , right: "../images/Polyphemus 2.png" },
{ left: "../images/Sulkowski 1.png" , right: "../images/Sulkowski 2.png" }];


別の関数loadButterflyisで蝶を作成し、マウスをクリックしてさらに蝶を起動します。

function init() {
// create a new stage and point it at our canvas:
canvas = document .getElementById( "canvas" );
stage = new Stage(canvas);
stage.enableMouseOver(10);

loadButterflyis(18);

canvas.onclick = function () {
loadButterflyis(5);
};

// subscribe to Ticker
Ticker.addListener(window);
}

function loadButterflyis(count) {
for ( var k = 0; k < count; k++) {
var i = Math.floor(bfimgsrc.length * Math.random());

var bfimages = {
left: new Image(),
right: new Image(),
loadedWings: 0,
onready: onButterflyImagesReady
};

// loading left wing
bfimages.left.src = bfimgsrc[i].left;
bfimages.left.onload = onWingImageLoaded;
bfimages.left.butterfly = bfimages;

// loading right wing
bfimages.right.src = bfimgsrc[i].right;
bfimages.right.onload = onWingImageLoaded;
bfimages.right.butterfly = bfimages;
}
}


更新されたティック

// update scene on each tick
function tick() {
for ( var i = 0; i < bfs.length; i++) {
var butterfly = bfs[i];
if (butterfly.isActive()) {
butterfly.move();
}
else if (Math.random() > 0.999) {
butterfly.reset();
}
}
stage.update();
}




完成した例はここにあります: 例5


特殊効果


追加の効果は非常に簡単です。 テーマの背景:



バックグラウンドでの音声:

< audio src ="audio/ArrivalForest.mp3" autoplay loop />

(モーグル愛好家は、他のオーディオ形式のサポートを簡単に追加できます。)

最終バージョンも利用可能です

更新しました。


ホスティングの問題を解決し、一時的にテスト用駐車場に置き、別々に:中間例と最終バージョンを1つのファイル-narod.ru/disk/6923480001/March8.zip.htmlに入れます

Source code was highlighted with Source Code Highlighter .

Source: https://habr.com/ru/post/J115030/


All Articles