What’s on our mind?

Collection of articles, design, site, and resources made by designers and publisher @Menu View

** index3
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const cw = (canvas.width = 500);
const ch = (canvas.height = 400);
const rad = Math.PI / 180;
ctx.lineWidth = 0.1;
ctx.lineJoin = "round";

let shapes = [];

let m = {x: 200, y: 200};
const fl = 300;
let vp = {x: cw / 2, y: ch / 8 }; 

let vertices = 4; 
let numShapes = 1020;
let increment = 2 * Math.PI / numShapes;
let R = 100;
let r = 40;

class Shape {
    constructor(points, beta) {
        this.points = points;
        this.beta = beta;
        this.delta = this.beta*3;
        this.stroke = "hsl(" + beta + ",90%,70%)";
    }
    draw() {
        ctx.beginPath();
        ctx.moveTo(this.points[0]._2d.x, this.points[0]._2d.y);
        for (let i = 1; i < this.points.length; i++) {
            ctx.lineTo(this.points[i]._2d.x, this.points[i]._2d.y);
        }
        ctx.closePath();
        ctx.strokeStyle = this.stroke;
        ctx.stroke();
    }

    update(ax, ay) {
        this.points.map(p => {
            p.update(ax, ay);
        });
    }

    getDepth() {
        return Math.min(
            this.points[0]._3d.z,
            this.points[1]._3d.z,
            this.points[2]._3d.z
        );
    }
}

class Dot3d {
    constructor(x, y, z) {
        this._2d = {
            x: 0,
            y: 0
        };
        this._3d = {
            x,
            y,
            z
        };

        this.r = 1;
        this.scaleX = 1;
        this.scaleY = 1;
        this.visible = true;
        this.setPerspective();
    }

    draw() {
        ctx.save();
        ctx.translate(this._2d.x, this._2d.y);
        //ctx.rotate(this.rotation);
        ctx.scale(this.scaleX, this.scaleY);
        ctx.beginPath();
        ctx.arc(0, 0, this.r, 0, 2 * Math.PI);
        ctx.fill();
        ctx.restore();
    }

    rotateX(angle) {
        let cos = Math.cos(angle);
        let sin = Math.sin(angle);
        let y1 = this._3d.y * cos - this._3d.z * sin;
        let z1 = this._3d.z * cos + this._3d.y * sin;
        this._3d.y = y1;
        this._3d.z = z1;
    }

    rotateY(angle) {
        let cos = Math.cos(angle);
        let sin = Math.sin(angle);
        let x1 = this._3d.x * cos - this._3d.z * sin;
        let z1 = this._3d.z * cos + this._3d.x * sin;
        this._3d.x = x1;
        this._3d.z = z1;
    }

    setPerspective() {
        if (this._3d.z > -fl) {
            let scale = fl / (fl + this._3d.z);
            this.scaleX = this.scaleY = scale;
            this._2d.x = vp.x + this._3d.x * scale;
            this._2d.y = vp.y + this._3d.y * scale;
            this.visible = true;
        } else {
            this.visible = false;
        }
    }

    update(ax, ay) {
        this.rotateX(ax);
        this.rotateY(ay);
        this.setPerspective();
    }
}

for (let beta = 0; beta <= 2 * Math.PI; beta += increment) {
    let x = R * Math.cos(beta);
    let y = 0;
    let z = R * Math.sin(beta);
    let delta = beta * 6;
    let sry = []; 

    for (let angle = 0; angle < 2 * Math.PI; angle += 2 * Math.PI / vertices) {
        let cos = r * Math.cos(angle + delta);
        let sin = r * Math.sin(angle + delta);
        sry.push(
            new Dot3d(
                (R + cos) * Math.cos(beta), 
                R + sin,
                (R + cos) * Math.sin(beta)
            )
        );
    }

    shapes.push(new Shape(sry, beta / rad));
}

function Draw() {
    requestId = window.requestAnimationFrame(Draw);
    ctx.clearRect(0, 0, cw, ch);

    let ay = (m.x - vp.x) * 0.0001;
    let ax = 0;

    shapes.sort(depth);

    shapes.map(s => {
        s.update(ax, ay);
        s.draw();
    });
}

Draw();

function depth(triangle_1, triangle_2) {
    return triangle_1.getDepth() - triangle_1.getDepth();
}

function oMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: Math.round(evt.clientX - rect.left),
        y: Math.round(evt.clientY - rect.top)
    };
}

canvas.addEventListener(
    "mousemove",
    function (evt) {
        m = oMousePos(canvas, evt);
    },
    false
);

function depth(triangle_1, triangle_2) {
    return triangle_2.getDepth() - triangle_1.getDepth();
}