DIR : /home/kozerus/public_html/jkwii/js/jsdoit/fireworks_dragon/index.jsx
/home/kozerus/public_html/jkwii/js/jsdoit/fireworks_dragon
// #! jsx
// forked from Event's "Web Creator's Contest Q the 2nd【vol.1】エントリー用コード" http://jsdo.it/Event/frf8
import 'js/web.jsx';
import 'timer.jsx';
class Config {
static const COUNT = 750;
static const GRAVITY = 1.2;
static const ALPHA = 0.15;
static const WIND = 0.25;
static const LIFE = 32;
static const SPARK_LIFE = 8;
}
class _Main {
static function main(args:string[]):void {
var canvas = dom.window.document.getElementById('c') as HTMLCanvasElement;
var b = dom.window.document.body;
var d = dom.window.document.documentElement;
canvas.width = Math.max(b.clientWidth , b.scrollWidth, d.scrollWidth, d.clientWidth);
canvas.height = Math.max(b.clientHeight , b.scrollHeight, d.scrollHeight, d.clientHeight);
var dragon = new Dragon(canvas.width, canvas.height);
dragon.context = canvas.getContext('2d') as CanvasRenderingContext2D;
dragon.context.lineWidth = 0.8;
dragon.context.strokeStyle = 'hsla(21, 100%, 80%, 0.9)';
dragon.context.globalCompositeOperation = 'lighter';
dom.window.document.addEventListener('click', function(e:Event):void {
if (dragon.power > 0.8) dragon.power = 0;
else if (dragon.power == 0) dragon.power = 0.3;
}, false);
Timer.setInterval(function():void {
dragon.update();
dragon.draw();
}, 1000 / 60);
}
}
/**
* Dragon
*/
class Dragon {
var width:int = 0;
var height:int = 0;
var particles:Particle[];
var sparks:Spark[];
var power = 0.3;
var currentWind = 0;
var targetWind = 0;
var context:CanvasRenderingContext2D;
function constructor(width:number, height:number) {
this.width = width;
this.height = height;
this.particles = []:Particle[];
for (var i = 0, len = Config.COUNT, p:Particle; i < len; i++) {
p = new Particle();
this._reborn(p);
this.particles.push(p);
}
this.sparks = []:Spark[];
this.targetWind = Math.random() * Config.WIND * 2 - Config.WIND;
}
function _reborn(p:Particle):void {
p.x = p.px = this.width * 0.5 | 0;
p.y = p.py = this.height;
var t = Math.random() * 0.08 - 0.04;
var s = 1 - Math.abs(t) * 5;
var c = Math.PI * (1.5 + t);
var l = (Math.random() * 15 + 25) * s;
p.vx = l * Math.cos(c) * this.power;
p.vy = l * Math.sin(c) * this.power;
p.age = 0;
p.life = Config.LIFE * (Math.random() * 0.5 + 0.5) * this.power;
}
function update():void {
if (this.power != 1) {
if (this.power < 1) this.power *= 1.02;
if (this.power > 1) this.power = 1;
}
// 風
this.currentWind += (this.targetWind - this.currentWind) * 0.03;
if (Math.abs(this.targetWind - this.currentWind) < 0.005) {
this.targetWind = Math.random() * Config.WIND * 2 - Config.WIND;
}
var wind = this.currentWind * this.power;
var sparked = false;
var s:Spark, sx:number, sy:number;
for (var i = 0, len = this.particles.length, p:Particle; i < len; i++) {
p = this.particles[i];
p.vx += wind;
p.vy += Config.GRAVITY;
p.px = p.x;
p.py = p.y;
p.x += p.vx;
p.y += p.vy;
p.age += 1;
if (p.age > p.life || p.x > this.width || p.x < 0 || p.y > this.height) {
this._reborn(p);
continue;
}
//火花をランダムに生成
if (Math.random() < 0.0008 && p.age > p.life * 0.5 && this.power > 0.8 && !sparked) {
s = Spark.get();
sx = p.x + Math.random() * 200 - 100;
sy = p.y + Math.random() * 100 - 50;
s.init(sx, sy);
this.sparks.push(s);
sparked = true;
}
}
// 火花を更新
var sparks = this.sparks;
if ((len = sparks.length)) {
var s:Spark;
for (i = 0; i < len; i++) {
s = sparks[i];
s.update();
if (s.completed) {
Spark.release(s);
sparks.splice(i, 1);
len--;
i--;
}
}
}
}
function draw():void {
var ctx = this.context;
ctx.save();
ctx.globalCompositeOperation = 'source-over';
ctx.fillStyle = 'rgba(0, 0, 0, ' + Config.ALPHA as string + ')';
ctx.fillRect(0, 0, this.width, this.height);
ctx.restore();
var particles = this.particles;
var sparks = this.sparks;
var i:int, len:int, p:Particle;
// Line
ctx.beginPath();
for (i = 0, len = particles.length; i < len; ++i) {
p = particles[i];
ctx.moveTo(p.px, p.py);
ctx.lineTo(p.x, p.y);
}
if ((len = sparks.length)) { // 火花
for (i = 0; i < len; i++) sparks[i].drawLine(ctx);
}
ctx.stroke();
// Blur
ctx.save();
ctx.beginPath();
ctx.shadowBlur = 24;
ctx.shadowColor = 'hsla(36, 100%, 70%, 0.35)';
for (i = 0, len = particles.length; i < len; ++i) {
p = particles[i];
if (p.age > Config.LIFE * 0.5) {
ctx.moveTo(p.x + 3, p.y);
ctx.arc(p.x, p.y, 3, 0, Math.PI * 2, false);
}
}
if ((len = sparks.length)) { // 火花
for (i = 0; i < len; i++) sparks[i].drawBlur(ctx);
}
ctx.fill();
ctx.restore();
}
}
/**
* Spark
*/
class Spark {
static var _pool = []:Spark[];
static function get():Spark {
return Spark._pool.length ? Spark._pool.shift() : new Spark();
}
static function release(s:Spark):void {
Spark._pool.push(s);
}
var x = 0;
var y = 0;
var particles:Particle[];
var completed = false;
function constructor() {
this.particles = []:Particle[];
var num = Math.floor(Math.random() * 16) + 10;
for (var i = 0, p:Particle; i < num; i++) {
p = new Particle();
this.particles.push(p);
}
}
function init(x:number, y:number):void {
this.x = x;
this.y = y;
var particles = this.particles;
for (var i = 0, len = particles.length, p:Particle; i < len; i++) {
p = particles[i];
this._reborn(p);
}
this.completed = false;
}
function _reborn(p:Particle):void {
p.x = p.px = this.x;
p.y = p.py = this.y;
var c = Math.PI * 2 * Math.random();
var l = Math.random() * 10 + 5;
p.vx = l * Math.cos(c);
p.vy = l * Math.sin(c);
p.age = 0;
p.life = Config.SPARK_LIFE * (Math.random() * 0.5 + 0.5);
}
function update():void {
var particles = this.particles;
var len = particles.length;
if (!len) {
this.completed = true;
return;
}
var allCompleted = true;
for (var i = 0, p:Particle; i < len; i++) {
p = particles[i];
if (p.age > p.life) continue;
p.vy += Config.GRAVITY;
p.px = p.x;
p.py = p.y;
p.x += p.vx;
p.y += p.vy;
p.age += 1;
allCompleted = false;
}
this.completed = allCompleted;
}
function drawLine(ctx:CanvasRenderingContext2D):void {
var particles = this.particles;
for (var i = 0, len = particles.length, p:Particle; i < len; ++i) {
p = particles[i];
if (p.age > p.life) continue;
ctx.moveTo(p.px, p.py);
ctx.lineTo(p.x, p.y);
}
}
function drawBlur(ctx:CanvasRenderingContext2D):void {
var particles = this.particles;
for (var i = 0, len = particles.length, p:Particle; i < len; ++i) {
p = particles[i];
if (p.age > p.life) continue;
ctx.moveTo(p.x + 3, p.y);
ctx.arc(p.x, p.y, 3, 0, Math.PI * 2, false);
}
}
}
/**
* Particle
*/
class Particle {
var x = 0;
var y = 0;
var px = 0;
var py = 0;
var vx = 0;
var vy = 0;
var life = 0;
var age = 0;
}
//
koh5_pano
Drag mouse to navigate.
Navigation
- Left/Right Mouse drag: Changes camera heading.
- Up/Sown Mouse drag: Changes camera pitch.
- Scroll wheel: Changes camera field of view.
- I-Key: Displays Info panel with canvas size, image size and FPS.
17.Aug.2010, Martin Wengenmayer