依据processing的代码在P5.js上实现类似的结果
一、代码本色0章——Perlin噪声生成起伏地形
【参考例子】
【实现结果】
[代码]
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var c = {}
var cw = canvas.width = 600;
c.x = cw / 2;
var ch = canvas.height = 600;
c.y = ch / 2;
ctx.lineJoin = "round";
ctx.strokeStyle = "#fff";
ctx.fillStyle = "rgba(0,0,0,1)";
var rad = Math.PI / 180;
var x, y;
var amplitude = 5;
var frequency = .02;
var phi = 0;
var increment = 0.05;
var lines = [];
function SquigglyLine(y) {
this.y = y;
this.xoff = Math.random() * 10000;
this.Xoff = this.xoff;
this.phi = Math.random() * 10000;
this.draw = function(i) {
ctx.beginPath();
this.xoff = this.Xoff; // reset xoff;
for (var x = -2; x < cw + 2; x++) {
if (x > cw / 3 && x < 2 * cw / 3) {
var k = map(x, cw / 3, 2 * cw / 3, 0, 180);
} else {
k = 0;
}
var y = -Math.abs(Math.sin((x + noise(this.xoff) * 100) * frequency + this.phi) * (amplitude + Math.sin(k * rad) * 50)) + this.y;
ctx.lineTo(x, y);
this.xoff += increment;
}
ctx.lineTo(cw + 2, ch + 2);
ctx.lineTo(-2, ch + 2);
ctx.closePath();
ctx.fill();
ctx.stroke();
}
}
for (var y = 60; y < ch; y += 16) {
var line = new SquigglyLine(y);
lines.push(line);
}
function Draw() {
requestId = window.requestAnimationFrame(Draw);
ctx.fillRect(0, 0, cw, ch);
noiseDetail(2, .5);
for (var i = 0; i < lines.length; i++) {
lines[i].phi += 1 / 30;
lines[i].draw(i);
}
}
requestId = window.requestAnimationFrame(Draw);
function map(n, a, b, _a, _b) {
var d = b - a;
var _d = _b - _a;
var u = _d / d;
return _a + (n - a) * u;
}
[效果图]
二、向量
【参考例子】
【实验结果】
[实验代码]
var x=0;
var y=0;
var targetX=0;
var targetY=0;
var easing=0.1;
function setup() {
createCanvas(400, 400);
x=mouseX;
y=mouseY;
}
function draw() {
background(220);
targetX=mouseX;
targetY=mouseY;
x+=(targetX-x)*easing;
y+=(targetY-y)*easing;
ellipse(x,y,20,20);
}
[实验效果图]
三、力学
【参考例子】
【实验结果】
[代码]
function Mover(loc, c) {
this.loc = createVector(width / 2, height / 2);
this.vel = createVector();
this.acc = createVector();
this.r = random(3, 7);
this.c = c;
this.alpha = 1;
if (typeof loc !== "undefined") {
this.loc = createVector(loc.x, loc.y);
}
this.applyForce = function(a) {
this.acc.add(a);
}
this.update = function() {
this.vel.add(this.acc);
this.acc.mult(0);
this.alpha *= .98;
if (this.loc.x < 0 || this.loc.x > width) {
this.vel.x *= -.8;
if (this.loc.x < 0) this.loc.x = 0;
if (this.loc.x > width) this.loc.x = width;
}
if (this.loc.y < 0 || this.loc.y > height) {
this.vel.y *= -.8;
if (this.loc.y < 0) this.loc.y = 0;
if (this.loc.y > height) this.loc.y = height;
}
this.loc.add(this.vel);
}
this.display = function() {
fill(this.c, 255, 255, this.alpha);
noStroke();
ellipse(this.loc.x, this.loc.y, this.r + (1 / this.alpha), this.r + (1 / this.alpha));
}
}
var movers = [];
function setup() {
colorMode(HSB);
createCanvas(window.innerWidth, window.innerHeight);
background(50);
}
function draw() {
background(20);
if (mouseDown || frameCount % 3 == 0) {
for (var x = 0; x < (mouseDown ? 2 : 1); x++) {
var m = new Mover(createVector(mouseX, mouseY), ((frameCount + 128) / 1 % 360));
m.applyForce(createVector(random(-1, 1), random(-1, 1)).mult(.5));
movers.push(m);
}
}
for (var x = movers.length - 1; x >= 0; x--) {
var mov = movers[x];
if (mov.alpha < .001) {
movers.shift(x);
} else {
// randomize movement a bit:
mov.applyForce(createVector(random(-1, 1), random(-1, 1)).mult(.1));
// enables gravity:
//mov.applyForce(createVector(0,.25));
mov.update();
mov.display();
}
}
}
var mouseDown = false;
function mousePressed() {
mouseDown = true;
}
function mouseReleased() {
mouseDown = false;
}
[实验结果]
四、振荡
[参考例子]
【实验结果】
[实验代码]
function setup() {
createCanvas(windowWidth - 100, windowHeight - 100);
frameRate(30);
pixelDensity(2);
}
var print = function(msg) {
console.log(msg);
}
r = 2;
function draw() {
if (frameCount * 5 <= windowWidth - 100)
ellipse(frameCount * 5, (height / 2), r, r);
else {
var wave = sin(radians(frameCount) * 30) * 20 + (height / 2);
fill('#ffffff');
ellipse(frameCount * 5 % (windowWidth - 100), (height / 2), r, r);
fill('#000000');
ellipse(frameCount * 5 % (windowWidth - 100), wave, r, r);
}
}
[实验结果]
五、粒子
【参考例子】
【实验结果】
[实验代码]
var stars = [], // Array that contains the stars
WIDTH = window.innerWidth,
HEIGHT = window.innerHeight,
FPS = 15, // Frames per second
NUM_STARS = WIDTH * 2; // Number of stars
function setup() {
createCanvas(WIDTH, HEIGHT);
// Push stars to array
for (var i = 0; i < NUM_STARS; i++) {
stars.push({
x: 0,
y: 0,
offset: Math.random() * 360,
// Weight orbit a little to be outside origin
orbit: (Math.random() + 0.01) * max(WIDTH, HEIGHT),
radius: Math.random() * 2,
vx: Math.floor(Math.random() * 10) - 5,
vy: Math.floor(Math.random() * 10) - 5
});
}
frameRate(FPS);
loop();
}
function draw() {
background(24, 24, 24);
push();
noFill();
colorMode(RGB, 255, 255, 255, 1);
stroke(255, 255, 255, 1);
strokeCap(1);
strokeWeight(2);
for (var i = 0, x = stars.length; i < x; i++) {
var s = stars[i];
ellipse(s.x, s.y, s.radius, 0);
}
pop();
update();
}
function update() {
var originX = WIDTH / 2;
var originY = HEIGHT / 2;
for (var i = 0, x = stars.length; i < x; i++) {
var s = stars[i];
var rad = (frameCount * (1 / (s.orbit * 2 + s.offset)) + s.offset) % TAU;
s.x = (originX + cos(rad) * (s.orbit * 2));
s.y = (originY + sin(rad) * (s.orbit));
}
}
[实验结果]