如何为 p5js 创建动画 class 库
How to create animation class library for p5js
我正在开发一个应用程序,我想使用 p5js 将不同动画叠加到一系列视频上。我希望组织我的 classes 动画类型,以便每个动画都有类似的结构来在每个循环中更新和销毁对象。我的计划是让一组当前 "active" 的动画在循环的每次迭代中更新它们,然后在它们完成时销毁它们。我构建了一个 class 来以这种方式淡化文本,但我得到了一些奇怪的华而不实的行为,每次在另一个动画中间触发一个新动画时似乎都会发生这种行为。我一直在尝试调试它,但没有成功。你有什么建议:
(1) 如果这是由于我的代码结构造成的? (也许你有更好的建议),
要么
(2) 我做错了什么?
代码如下:
// create an array of currently executing animations to update
// each animation class needs to have one function and one attribute:
// (1) update() -- function to move the objects where ever they need to be moved
// (2) done -- attribute to determine if they should be spliced out of the array
var animations = [];
//////////////////////////////////////////
// Global Variables for Animations //
//////////////////////////////////////////
let start = false;
let count = 0;
function setup(){
let canv = createCanvas(1920, 1080);
canv.id = "myP5canvas";
background(0);
}
function draw(){
background(0);
// Check things to see if we should be adding any animations to the picture
var drawText = random(100);
if (drawText > 98) {
//if (start == false) {
let r = 255;
let g = 204;
let b = 0;
let x = random(width-10);
let y = random(height-10);
animations.push(new TextFader("Wowwwzers!", 100, 'Georgia', r, g, b, x, y, count));
start = true;
count += 1;
}
// Update animations that exist!
for (var i=0; i < animations.length; i++) {
// update the position/attributes of the animation
animations[i].update();
// check if the animation is done and should be removed from the array
if (animations[i].done) {
console.log("SPLICE: " + animations[i].id);
animations.splice(i, 1);
}
}
}
// EXAMPLE ANIMATION
// TEXT FADE
let TextFader = function(words, size, font, red, green, blue, xloc, yloc, id) {
this.id = id;
console.log("create fader: " + this.id);
// translating inputs to variables
this.text = words;
this.size = size;
this.font = font;
// To Do: separating out each of the values until I figure out how to fade separately from the color constructor
this.red = red;
this.green = green;
this.blue = blue;
this.xloc = xloc;
this.yloc = yloc;
// Maybe add customization in the future for fading...
this.fade = 255;
this.fadeTime = 3; // in seconds
this.fadeIncrement = 5;
// Variables to use for destruction
this.createTime = millis();
this.done = false;
}
TextFader.prototype.update = function() {
// Update the fade
// If the fade is below zero don't update and set to be destroyed
this.fade -= this.fadeIncrement;
if (this.fade <= 0) {
this.done = true;
} else {
this.show();
}
}
TextFader.prototype.show = function() {
textFont(this.font);
textSize(this.size);
fill(this.red, this.green, this.blue, this.fade);
text(this.text, this.xloc, this.yloc);
console.log("Drawing: " + this.id + " fade: " + this.fade + " done: " + this.done);
}
耶,我给你答案了!当您反转循环遍历动画的 for 循环时,它会像预期的那样工作。
因为你在循环内拼接了同一个数组的元素,一些元素被跳过了。例如; animations[0].done = true 并被移除。这意味着 animations[1] 现在位于 animations[0] 的位置,而 animations[2] 现在位于 animations[1] 的位置。
i 变量递增到 1,因此在下一个循环中,您更新动画 [1](并跳过现在位于动画 [0] 中的动画)。
当你反转循环时,你拼接的元素之前的所有内容都保持不变,没有任何内容被跳过。
例如; animations[2].done = true 并被移除。这意味着 animations[1] 仍然在 animations[1].
的位置
i 变量递减为 1,因此在下一个循环中,您更新动画 [1] 并且不跳过任何元素。
// Update animations that exist!
for (var i = animations.length - 1; i >= 0; i--) {
// update the position/attributes of the animation
animations[i].update();
// check if the animation is done and should be removed from the array
if (animations[i].done) {
//console.log("SPLICE: " + animations[i].id);
animations.splice(i, 1);
}
}
我正在开发一个应用程序,我想使用 p5js 将不同动画叠加到一系列视频上。我希望组织我的 classes 动画类型,以便每个动画都有类似的结构来在每个循环中更新和销毁对象。我的计划是让一组当前 "active" 的动画在循环的每次迭代中更新它们,然后在它们完成时销毁它们。我构建了一个 class 来以这种方式淡化文本,但我得到了一些奇怪的华而不实的行为,每次在另一个动画中间触发一个新动画时似乎都会发生这种行为。我一直在尝试调试它,但没有成功。你有什么建议: (1) 如果这是由于我的代码结构造成的? (也许你有更好的建议), 要么 (2) 我做错了什么?
代码如下:
// create an array of currently executing animations to update
// each animation class needs to have one function and one attribute:
// (1) update() -- function to move the objects where ever they need to be moved
// (2) done -- attribute to determine if they should be spliced out of the array
var animations = [];
//////////////////////////////////////////
// Global Variables for Animations //
//////////////////////////////////////////
let start = false;
let count = 0;
function setup(){
let canv = createCanvas(1920, 1080);
canv.id = "myP5canvas";
background(0);
}
function draw(){
background(0);
// Check things to see if we should be adding any animations to the picture
var drawText = random(100);
if (drawText > 98) {
//if (start == false) {
let r = 255;
let g = 204;
let b = 0;
let x = random(width-10);
let y = random(height-10);
animations.push(new TextFader("Wowwwzers!", 100, 'Georgia', r, g, b, x, y, count));
start = true;
count += 1;
}
// Update animations that exist!
for (var i=0; i < animations.length; i++) {
// update the position/attributes of the animation
animations[i].update();
// check if the animation is done and should be removed from the array
if (animations[i].done) {
console.log("SPLICE: " + animations[i].id);
animations.splice(i, 1);
}
}
}
// EXAMPLE ANIMATION
// TEXT FADE
let TextFader = function(words, size, font, red, green, blue, xloc, yloc, id) {
this.id = id;
console.log("create fader: " + this.id);
// translating inputs to variables
this.text = words;
this.size = size;
this.font = font;
// To Do: separating out each of the values until I figure out how to fade separately from the color constructor
this.red = red;
this.green = green;
this.blue = blue;
this.xloc = xloc;
this.yloc = yloc;
// Maybe add customization in the future for fading...
this.fade = 255;
this.fadeTime = 3; // in seconds
this.fadeIncrement = 5;
// Variables to use for destruction
this.createTime = millis();
this.done = false;
}
TextFader.prototype.update = function() {
// Update the fade
// If the fade is below zero don't update and set to be destroyed
this.fade -= this.fadeIncrement;
if (this.fade <= 0) {
this.done = true;
} else {
this.show();
}
}
TextFader.prototype.show = function() {
textFont(this.font);
textSize(this.size);
fill(this.red, this.green, this.blue, this.fade);
text(this.text, this.xloc, this.yloc);
console.log("Drawing: " + this.id + " fade: " + this.fade + " done: " + this.done);
}
耶,我给你答案了!当您反转循环遍历动画的 for 循环时,它会像预期的那样工作。
因为你在循环内拼接了同一个数组的元素,一些元素被跳过了。例如; animations[0].done = true 并被移除。这意味着 animations[1] 现在位于 animations[0] 的位置,而 animations[2] 现在位于 animations[1] 的位置。
i 变量递增到 1,因此在下一个循环中,您更新动画 [1](并跳过现在位于动画 [0] 中的动画)。
当你反转循环时,你拼接的元素之前的所有内容都保持不变,没有任何内容被跳过。
例如; animations[2].done = true 并被移除。这意味着 animations[1] 仍然在 animations[1].
的位置
i 变量递减为 1,因此在下一个循环中,您更新动画 [1] 并且不跳过任何元素。
// Update animations that exist!
for (var i = animations.length - 1; i >= 0; i--) {
// update the position/attributes of the animation
animations[i].update();
// check if the animation is done and should be removed from the array
if (animations[i].done) {
//console.log("SPLICE: " + animations[i].id);
animations.splice(i, 1);
}
}