如何在 P5JS 中反转绘图的动画(post 中有更多详细信息)
How do I reverse the animation of a drawing in P5JS (more details in post)
源代码:https://editor.p5js.org/theruantan/sketches/aFXKo_s86
基本上我正在尝试做一个我预先设计好的pseudo generative poster that swaps between 3 artworks。我们的想法是加载一件艺术品,等待几秒钟然后反转(基本上将其擦除)绘图为空白 canvas 然后加载下一件并无限重复。
我只是想重现我在这里看到的反转动画:https://www.reddit.com/r/generative/comments/q6krwj/lines_p5js/
没有像这样自动倒回动画的方法。您可以做一些非常占用内存的事情,例如将动画的每一帧都保存为图像,然后向后播放整个动画,但这会占用大量内存。相反,您可以反转为各种形状设置动画的逻辑:
let masks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // Create Masks for Artwork Background
let switches = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // To switch on each background line
let mainMask = 400; // Create Main mask to reveal artwork
let cityActiveState = 0; // To determine if the current artwork is active or erased -- either 0 or 1.
let sunXPos = 0; // To Move the sun around
let sunYPos = -100;
let rods = -100; // Animate lightning rods for city
function setup() {
createCanvas(180, 216);
frameRate(60);
console.log(`${switches.length} Swithces`);
console.log(`${masks.length} Masks`);
}
function draw() {
let beige = color(251, 242, 224);
let red = color(245, 105, 96);
let blue = color(96, 152, 190);
let green = color(124, 167, 122);
let headBlack = color(60, 60, 59);
let textBlack = color(112, 111, 111);
background(beige);
push();
scale(0.2);
translate(50, 240);
citySkyline(red, beige);
pop();
}
function citySkyline(color1, color2) {
// Animate artwork
if (cityActiveState == 0) {
sunXPos = 650;
if (!switches[0]) {
switches[0] = 1;
}
let animating = false;
for (let i = 0; i < switches.length; i++) {
if (switches[i] == 1) {
if (masks[i] < 800) {
masks[i] += 20;
animating = true;
}
if (masks[i] >= 300) {
if (i + 1 < switches.length) {
switches[i + 1] = 1;
}
if (i == 12) {
// Only increase these once masks[12] reaches 300
if (mainMask < 1500) {
mainMask += 10;
animating = true;
}
if (rods < 371) {
rods += 15;
animating = true;
}
if (sunYPos < 140) {
sunYPos += 7.5;
animating = true;
}
}
}
}
}
if (!animating) {
console.log("city is now active");
cityActiveState = 1;
}
} else if (cityActiveState == 1) {
// Reverse animation
let animating = false;
if (mainMask > 400 || rods > -100 || sunYPos > -100) {
animating = true;
if (mainMask > 400) {
mainMask -= 10;
}
if (rods > -100) {
rods -= 15;
}
if (sunYPos > -100) {
sunYPos -= 7.5;
}
} else {
if (switches[switches.length - 1]) {
switches[switches.length - 1] = 0;
}
for (let i = switches.length - 1; i >= 0; i--) {
if (switches[i] == 0) {
if (masks[i] > 0) {
masks[i] -= 20;
animating = true;
}
if (masks[i] <= 300) {
// Begin reversing the next bar
switches[i - 1] = 0;
}
}
}
}
if (!animating) {
console.log("city is now inactive");
cityActiveState = 0;
}
}
// draw actual artwork
push();
noStroke();
fill(color1);
translate(225, 285);
rect(50, 0, 250, 20);
rect(0, 55, 350, 10);
rect(0, 95, 350, 10);
rect(0, 135, 350, 50);
rect(0, 215, 350, 30);
rect(0, 275, 350, 10);
rect(0, 315, 350, 40);
rect(0, 385, 350, 60);
rect(0, 475, 350, 40);
pop();
// reveal artwork
push();
noStroke();
fill(color2);
rectMode(RADIUS);
rect(mainMask, 400, 400, 400);
pop();
push();
noStroke();
fill(color1);
rect(0, 0, masks[0], 100);
rect(0, 110, masks[1], 70);
rect(0, 190, masks[2], 50);
rect(0, 250, masks[3], 35);
rect(0, 315, masks[4], 25);
rect(0, 370, masks[5], 10);
rect(0, 410, masks[6], 10);
rect(0, 490, masks[7], 10);
rect(0, 550, masks[8], 10);
rect(0, 590, masks[9], 10);
rect(0, 660, masks[10], 10);
rect(0, 750, masks[11], 10);
pop();
// draw lighting rods
push();
noStroke();
fill(color2);
translate(0, 100);
rect(rods + 30, 0, 20, 140);
translate(0, 40);
rect(rods, 0, 10, 100);
pop();
// draw sun
push();
noStroke();
fill(color2);
circle(sunXPos, sunYPos, 143);
pop();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
我精简了代码,不得不 fiddle 解决了一些错误才能完成这项工作。希望基本概念清楚。
源代码:https://editor.p5js.org/theruantan/sketches/aFXKo_s86
基本上我正在尝试做一个我预先设计好的pseudo generative poster that swaps between 3 artworks。我们的想法是加载一件艺术品,等待几秒钟然后反转(基本上将其擦除)绘图为空白 canvas 然后加载下一件并无限重复。
我只是想重现我在这里看到的反转动画:https://www.reddit.com/r/generative/comments/q6krwj/lines_p5js/
没有像这样自动倒回动画的方法。您可以做一些非常占用内存的事情,例如将动画的每一帧都保存为图像,然后向后播放整个动画,但这会占用大量内存。相反,您可以反转为各种形状设置动画的逻辑:
let masks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // Create Masks for Artwork Background
let switches = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // To switch on each background line
let mainMask = 400; // Create Main mask to reveal artwork
let cityActiveState = 0; // To determine if the current artwork is active or erased -- either 0 or 1.
let sunXPos = 0; // To Move the sun around
let sunYPos = -100;
let rods = -100; // Animate lightning rods for city
function setup() {
createCanvas(180, 216);
frameRate(60);
console.log(`${switches.length} Swithces`);
console.log(`${masks.length} Masks`);
}
function draw() {
let beige = color(251, 242, 224);
let red = color(245, 105, 96);
let blue = color(96, 152, 190);
let green = color(124, 167, 122);
let headBlack = color(60, 60, 59);
let textBlack = color(112, 111, 111);
background(beige);
push();
scale(0.2);
translate(50, 240);
citySkyline(red, beige);
pop();
}
function citySkyline(color1, color2) {
// Animate artwork
if (cityActiveState == 0) {
sunXPos = 650;
if (!switches[0]) {
switches[0] = 1;
}
let animating = false;
for (let i = 0; i < switches.length; i++) {
if (switches[i] == 1) {
if (masks[i] < 800) {
masks[i] += 20;
animating = true;
}
if (masks[i] >= 300) {
if (i + 1 < switches.length) {
switches[i + 1] = 1;
}
if (i == 12) {
// Only increase these once masks[12] reaches 300
if (mainMask < 1500) {
mainMask += 10;
animating = true;
}
if (rods < 371) {
rods += 15;
animating = true;
}
if (sunYPos < 140) {
sunYPos += 7.5;
animating = true;
}
}
}
}
}
if (!animating) {
console.log("city is now active");
cityActiveState = 1;
}
} else if (cityActiveState == 1) {
// Reverse animation
let animating = false;
if (mainMask > 400 || rods > -100 || sunYPos > -100) {
animating = true;
if (mainMask > 400) {
mainMask -= 10;
}
if (rods > -100) {
rods -= 15;
}
if (sunYPos > -100) {
sunYPos -= 7.5;
}
} else {
if (switches[switches.length - 1]) {
switches[switches.length - 1] = 0;
}
for (let i = switches.length - 1; i >= 0; i--) {
if (switches[i] == 0) {
if (masks[i] > 0) {
masks[i] -= 20;
animating = true;
}
if (masks[i] <= 300) {
// Begin reversing the next bar
switches[i - 1] = 0;
}
}
}
}
if (!animating) {
console.log("city is now inactive");
cityActiveState = 0;
}
}
// draw actual artwork
push();
noStroke();
fill(color1);
translate(225, 285);
rect(50, 0, 250, 20);
rect(0, 55, 350, 10);
rect(0, 95, 350, 10);
rect(0, 135, 350, 50);
rect(0, 215, 350, 30);
rect(0, 275, 350, 10);
rect(0, 315, 350, 40);
rect(0, 385, 350, 60);
rect(0, 475, 350, 40);
pop();
// reveal artwork
push();
noStroke();
fill(color2);
rectMode(RADIUS);
rect(mainMask, 400, 400, 400);
pop();
push();
noStroke();
fill(color1);
rect(0, 0, masks[0], 100);
rect(0, 110, masks[1], 70);
rect(0, 190, masks[2], 50);
rect(0, 250, masks[3], 35);
rect(0, 315, masks[4], 25);
rect(0, 370, masks[5], 10);
rect(0, 410, masks[6], 10);
rect(0, 490, masks[7], 10);
rect(0, 550, masks[8], 10);
rect(0, 590, masks[9], 10);
rect(0, 660, masks[10], 10);
rect(0, 750, masks[11], 10);
pop();
// draw lighting rods
push();
noStroke();
fill(color2);
translate(0, 100);
rect(rods + 30, 0, 20, 140);
translate(0, 40);
rect(rods, 0, 10, 100);
pop();
// draw sun
push();
noStroke();
fill(color2);
circle(sunXPos, sunYPos, 143);
pop();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
我精简了代码,不得不 fiddle 解决了一些错误才能完成这项工作。希望基本概念清楚。