html5绘制随机,在HTML5 Canvas上绘制随机山脉图

JavaScript

语言:

JaveScriptBabelCoffeeScript

确定

"use strict";

const transform = {

m: [],

minSize: 0.1,

stack: [],

calls: [],

shapes: [],

reset() {

this.m = [1, 0, 0, 1, 0, 0, 0, 0];

this.shapes.length = 0;

this.calls.length = 0;

return this;

},

rotate(v) {

const m = this.m;

const rad = Math.PI * v / 180;

const cos = Math.cos(rad);

const sin = Math.sin(rad);

const r00 = cos * m[0] + sin * m[2];

const r01 = cos * m[1] + sin * m[3];

m[2] = cos * m[2] - sin * m[0];

m[3] = cos * m[3] - sin * m[1];

m[0] = r00;

m[1] = r01;

return this;

},

translate(x, y = 0) {

const m = this.m;

m[4] += x * m[0] + y * m[2];

m[5] += x * m[1] + y * m[3];

return this;

},

scale(x = 1, y = x) {

const m = this.m;

m[0] *= x;

m[1] *= x;

m[2] *= y;

m[3] *= y;

return this;

},

z(v) {

this.m[6] += v;

return this;

},

light(v) {

this.m[7] = v;

return this;

},

exec(fn) {

this.calls.push([fn, this.m.slice()]);

return this;

},

save() {

this.stack.push(this.m.slice());

return this;

},

restore() {

this.m = this.stack.pop();

return this;

},

SQUARE() {

this.shapes.push(this.m.slice());

return this;

},

tooSmall() {

const m = this.m;

const x = m[0] * m[0] + m[1] * m[1];

const y = m[2] * m[2] + m[3] * m[3];

return x < this.minSize || y < this.minSize;

},

render(ctx, w, h) {

do {

const step = this.calls.shift();

this.m = step[1];

step[0]();

} while (this.calls.length);

this.shapes.sort(function(a, b) {

return a[6] - b[6];

});

for (const m of this.shapes) {

ctx.setTransform(

m[0],

m[1],

m[2],

m[3],

m[4] + w * 0.5,

m[5] + h * 0.5

);

ctx.fillStyle = `hsl(0, 0%, ${m[7]}%)`;

ctx.fillRect(-0.5, -0.5, 1, 1);

}

}

};

const canvas = document.querySelector("canvas");

const ctx = canvas.getContext("2d");

const walk = () => {

const r = Math.random() * 5;

switch (true) {

case r <= 1:

transform.translate(0, 0.2);

transform.exec(walk);

break;

case r <= 2:

transform.translate(0.5, 0);

transform.exec(walk);

break;

case r <= 3:

transform.translate(-0.5, 0);

transform.exec(walk);

break;

default:

transform

.save()

.translate(r <= 4 ? -0.2 : 0.2, 1)

.scale(0.9)

.z(-0.1);

if (transform.tooSmall()) return;

transform

.exec(walk)

.restore();

transform

.translate(0, 1)

.exec(sides);

}

};

const sides = () => {

transform

.save()

.rotate([120, 130, 110][(Math.random() * 3) | 0])

.exec(leftside)

.restore();

transform

.save()

.rotate([-120, -130, -110][(Math.random() * 3) | 0])

.exec(rightside)

.restore();

};

const leftside = () => {

transform

.save()

.translate(-0.5, 0.5)

.light(100)

.SQUARE()

.restore();

transform

.save()

.translate(0, 0.5)

.scale(0.1, 1)

.SQUARE()

.restore();

const r = Math.random() * 2.1;

if (r <= 0.1) return;

transform

.translate(0, 1)

.rotate(r <= 1.1 ? 5 : -5)

.exec(leftside);

};

const rightside = () => {

transform

.scale(-1, 1)

.exec(leftside);

};

const start = () => {

const width = (canvas.width = canvas.offsetWidth * 4);

const height = (canvas.height = canvas.offsetHeight * 4);

ctx.clearRect(0, 0, width, height);

const scale = Math.min(width, height) / 100;

transform.reset().scale(scale * 4, -scale * 4).translate(-10, -5);

for (let i = 0; i < 10; i++) {

transform.translate(2, 0).z(-0.01);

transform.exec(walk);

}

transform.render(ctx, width, height);

};

window.addEventListener("resize", start, false);

["click", "touchdown"].forEach(event => {

document.addEventListener(event, start, false);

});

requestAnimationFrame(start);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值