LOG

ノードアニメーションその1

デモ

Shape.js

class Shape{
    get SIZE(){ return 3 }
    get COLOR(){ return 0xFFFFFF }
    get MAX_LINE_SIZE(){ return 100 }
    get x(){ return this.graphics.x }
    set x(pos){ this.graphics.x = pos }
    get y(){ return this.graphics.y }
    set y(pos){ this.graphics.y = pos }
    // =========================================================================
    // ライン初期化
    // =========================================================================
    clearLine(){
        this.connected = [];
        this.line.clear();
    }
    // =========================================================================
    // ライン描画
    // =========================================================================
    drawLine(shape){
        let connected  = false;
        let alpha      = 1;
        let alphaRnage = this.MAX_LINE_SIZE * 0.8;
        for(let i=0,l=shape.connected.length; i < l; i++){
            if(shape.connected[i] === this){
                connected = true;
                break;
            }
        }
        if(connected) return;
        this.connected.push(shape);
        let line = this.line;
        let dist = Math.sqrt( (shape.x - this.x) * (shape.x - this.x) + (shape.y - this.y) * (shape.y - this.y) );
        if(dist < this.MAX_LINE_SIZE){
            if(dist > alphaRnage){
                alpha = 1 - (dist / this.MAX_LINE_SIZE);
            }
            line.lineStyle(1,this.COLOR,alpha);
            line.moveTo(this.x,this.y);
            line.lineTo(shape.x,shape.y);
        }
    }
    // =========================================================================
    // 移動アニメーション
    // =========================================================================
    move(){
        this.angle    += this.angleSpeed;
        let angle      = this.angle;
        let moveRangeX = this.moveRangeX;
        let moveRangeY = this.moveRangeY;
        let centerX    = this.centerX;
        let centerY    = this.centerY;
        this.x         = Math.sin(angle) * moveRangeX + centerX;
        this.y         = Math.cos(angle) * moveRangeY + centerY;
    }
    // =========================================================================
    // コンストラクタ
    // =========================================================================
    constructor(_stage,_w,_h,_x=false,_y=false){
        let SIZE  = this.SIZE;
        let COLOR = this.COLOR;
        let x;
        let y;
        let line;
        this.graphics   = new PIXI.Graphics();
        this.centerX    = x = _x ? _x : Math.random() * _w;
        this.centerY    = y = _y ? _y : Math.random() * _h;
        this.angle      = Math.random() * 360;
        this.moveRangeX = 20 + Math.random() * 50;
        this.moveRangeY = 20 + Math.random() * 50;
        this.angleSpeed = (1 + Math.random() * 2) / 100;
        this.line       = new PIXI.Graphics();
        this.connected  = [];
        line            = this.line;
        let g           = this.graphics;
        g.beginFill(COLOR);
        g.drawCircle(0,0,SIZE);
        g.endFill();
        g.x = x;
        g.y = y;
        _stage.addChild(line);
        _stage.addChild(g);
    }
}

script.js

// =============================================================================
// global
// =============================================================================<
let W        = window.innerWidth;
let H        = window.innerHeight;
let shapeNum = 100;
let shapes   = [];
let renderer;
let stage;

// =============================================================================
// events
// =============================================================================
// events:resize
// -----------------------------------------------------------------------------
let resizeObserve = {};
window.addEventListener('resize',(()=>{
    let timer;
    let events  = resizeObserve;
    let observe = (e)=>{
        W = window.innerWidth;
        H = window.innerHeight;
        for(let key in events) events[key](e);
    };
    return ()=>{
        if(timer) clearTimeout(timer);
            timer = setTimeout(observe,250);
        }
    })());
// -----------------------------------------------------------------------------
// events:animation
// -----------------------------------------------------------------------------
let animationObserve = {};
let animate          = function(){
    requestAnimationFrame(animate);
    for(let key in animationObserve) animationObserve[key]();
    renderer.render(stage);
}

// =============================================================================
//
// 実行
//
// =============================================================================
resizeObserve.resizeRenderer = ()=>{
    renderer.resize(W,H);
}
// -----------------------------------------------------------------------------
// 環境の設定
// -----------------------------------------------------------------------------
renderer = PIXI.autoDetectRenderer(800,600,{
    view      : document.querySelector('canvas'),
    antialias : true
});
stage = new PIXI.Container();
// -----------------------------------------------------------------------------
// shape追加
// -----------------------------------------------------------------------------
for(let i=0,l=shapeNum; i < l; i++){
    let shape = new Shape(stage,W,H);
    shapes.push(shape);
}
// -----------------------------------------------------------------------------
// shapeアニメーション
// -----------------------------------------------------------------------------
animationObserve.shape = ()=>{
    let shapeA;
    let shapeB;
    let dist;
    for(let i=0,l=shapes.length; i < l; i++ | 0){
        shapeA = shapes[i];
        shapeA.move();
        shapeA.clearLine();
        for(let ii=0; ii<l; ii++ | 0){
            if(ii === i) continue;
            shapeB = shapes[ii];
            shapeA.drawLine(shapeB);
        }
    }
}

window.addEventListener('click',(e)=>{
    shapes.push(new Shape(stage,W,H,e.clientX,e.clientY));
});

window.dispatchEvent(new Event('resize'));
animate();