在 p5js 中逐渐给矩形上色
Gradually color rectangles in p5js
我正在尝试使用 p5.js 在浏览器中构建冒泡排序算法的可视化。我已经设法实现了该算法,并且条形图成功地切换了位置。现在我想在考虑交换它们时给条着色(当它们在 'bubble' 中时,就像在冒泡排序中一样)。给它们上色很容易,但颜色会急剧变化,看起来不太好。我想要的是逐渐改变颜色。例如从蓝色渐变为绿色。这是我的设置和绘制函数:
let bars = []; // array of Bar objects
let values = [];
let greenColor;
let blueColor;
let redColor;
let orangeColor;
function setup() {
//Init colors
greenColor = color(16, 112, 1);
blueColor = color(158, 207, 224);
redColor = color(208, 0, 46);
orangeColor = color(253, 148, 8);
createCanvas(900, 900);
textSize(15);
// Create objects
for (let i = 0; i < 10; i++) {
values[i] = round(random(150));
bars.push(new Bar(i*50 + i*10, values[i], -1));
}
}
function draw() {
background(255, 255, 255);
for (let i = 0; i < bars.length; i++) {
bars[i].display();
}
}
设置和绘制函数使用自定义 class 命名栏。 Draw 使用 Bar.display() 函数将矩形绘制到屏幕上。如下所示:
display() {
if (this.colorState == 1) {
let firstColor = blueColor;
let secondColor = blueColor;
if (this.currentColor == "green") {
firstColor = greenColor;
} else if (this.currentColor == "red") {
firstColor = redColor;
} else if (this.currentColor == "orange") {
firstColor = orangeColor;
} else {
firstColor = blueColor;
}
if (this.nextColor == "green") {
secondColor = greenColor;
} else if (this.nextColor == "red") {
secondColor = redColor;
} else if (this.nextColor == "orange"){
secondColor = orangeColor;
} else {
firstColor = blueColor;
}
if (this.amt <= 1.0) {
var gradient = lerpColor(firstColor, secondColor, this.amt);
this.amt += 0.05;
fill(gradient);
} else {
this.colorState = 0;
this.currentColor = this.nextColor;
this.amt = 0;
}
} else {
if (this.currentColor == "green") {
fill(greenColor);
} else if (this.currentColor == 'blue') {
fill(blueColor);
} else if (this.currentColor == "red") {
fill(redColor);
} else {
fill(orangeColor);
}
}
noStroke();
rect(this.x, this.y, 50, this.height);
fill(color(0, 0, 0));
text(-this.height, this.x + 15, (height / 2) + (this.height) - 20, 60, 60);
function mouseClicked() {
bars[0].colorState = 1;
bars[0].nextColor = "green";
}
我发现将 lerpColor 与 amt 参数一起使用可以让我逐渐改变颜色。当我想淡入下一种颜色时,我将它增加 0.05。截至目前,它可以使颜色褪色,但随后会出现闪烁效果,它会在几毫秒内变黑,我不知道为什么。请帮我解决这个问题。这是 js fiddle:
https://jsfiddle.net/jomzkct4/(稍微向下滚动以查看栏)。
有一个帧,当颜色过渡完成时 amt > 1
,填充颜色没有重新分配,所以它使用前一帧的颜色 fill(color(0, 0, 0))
。您可以通过在此代码块中添加不同的颜色来进行测试:
else {
this.colorState = 0;
this.currentColor = this.nextColor;
this.amt = 0;
// Now it "blinks" red
fill([255, 0, 0])
}
最终,您可能希望在 colorState
值为 0
时重用颜色分配逻辑,或者调整 if (this.colorState == 1) {...} else{...}
块的逻辑。
let bars = []; // array of Bar objects
let values = [];
let greenColor;
let blueColor;
let redColor;
let orangeColor;
function setup() {
//Init colors
greenColor = color(16, 112, 1);
blueColor = color(158, 207, 224);
redColor = color(208, 0, 46);
orangeColor = color(253, 148, 8);
createCanvas(900, 900);
textSize(15);
frameRate(10)
// Create objects
for (let i = 0; i < 10; i++) {
values[i] = round(random(150));
bars.push(new Bar(i*50 + i*10, values[i], -1));
}
}
function draw() {
background(255, 255, 255);
for (let i = 0; i < bars.length; i++) {
bars[i].display();
}
}
// Bar class
class Bar {
constructor(xCord, heightIn) {
this.x = xCord;
this.y = height / 2;
this.speed = 1;
this.height = -heightIn;
this.currentColor = "blue";
this.nextColor = "blue";
this.amt = 0;
this.colorState = 0; //0 for static, 1 for changing
}
display() {
if (this.colorState == 1) {
let firstColor = blueColor;
let secondColor = blueColor;
if (this.currentColor == "green") {
firstColor = greenColor;
} else if (this.currentColor == "red") {
firstColor = redColor;
} else if (this.currentColor == "orange") {
firstColor = orangeColor;
} else {
firstColor = blueColor;
}
if (this.nextColor == "green") {
secondColor = greenColor;
} else if (this.nextColor == "red") {
secondColor = redColor;
} else if (this.nextColor == "orange"){
secondColor = orangeColor;
} else {
firstColor = blueColor;
}
if (this.amt <= 1.0) {
var gradient = lerpColor(firstColor, secondColor, this.amt);
this.amt += 0.05;
fill(gradient);
}
else {
this.colorState = 0;
this.currentColor = this.nextColor;
this.amt = 0;
// Either reuse the logic:
/* if (this.currentColor == "green") {
fill(greenColor);
} else if (this.currentColor == 'blue') {
fill(blueColor);
} else if (this.currentColor == "red") {
fill(redColor);
} else {
fill(orangeColor);
} */
}
}
// or tweak the logic of the if-else block
//else{
if (this.colorState == 0) {
if (this.currentColor == "green") {
fill(greenColor);
} else if (this.currentColor == 'blue') {
fill(blueColor);
} else if (this.currentColor == "red") {
fill(redColor);
} else {
fill(orangeColor);
}
}
noStroke();
rect(this.x, this.y, 50, this.height);
fill(color(0, 0, 0));
text(-this.height, this.x + 15, (height / 2) + (this.height) - 20, 60, 60);
}
}
function mouseClicked() {
bars[0].colorState = 1;
bars[0].nextColor = "green";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.min.js"></script>
我正在尝试使用 p5.js 在浏览器中构建冒泡排序算法的可视化。我已经设法实现了该算法,并且条形图成功地切换了位置。现在我想在考虑交换它们时给条着色(当它们在 'bubble' 中时,就像在冒泡排序中一样)。给它们上色很容易,但颜色会急剧变化,看起来不太好。我想要的是逐渐改变颜色。例如从蓝色渐变为绿色。这是我的设置和绘制函数:
let bars = []; // array of Bar objects
let values = [];
let greenColor;
let blueColor;
let redColor;
let orangeColor;
function setup() {
//Init colors
greenColor = color(16, 112, 1);
blueColor = color(158, 207, 224);
redColor = color(208, 0, 46);
orangeColor = color(253, 148, 8);
createCanvas(900, 900);
textSize(15);
// Create objects
for (let i = 0; i < 10; i++) {
values[i] = round(random(150));
bars.push(new Bar(i*50 + i*10, values[i], -1));
}
}
function draw() {
background(255, 255, 255);
for (let i = 0; i < bars.length; i++) {
bars[i].display();
}
}
设置和绘制函数使用自定义 class 命名栏。 Draw 使用 Bar.display() 函数将矩形绘制到屏幕上。如下所示:
display() {
if (this.colorState == 1) {
let firstColor = blueColor;
let secondColor = blueColor;
if (this.currentColor == "green") {
firstColor = greenColor;
} else if (this.currentColor == "red") {
firstColor = redColor;
} else if (this.currentColor == "orange") {
firstColor = orangeColor;
} else {
firstColor = blueColor;
}
if (this.nextColor == "green") {
secondColor = greenColor;
} else if (this.nextColor == "red") {
secondColor = redColor;
} else if (this.nextColor == "orange"){
secondColor = orangeColor;
} else {
firstColor = blueColor;
}
if (this.amt <= 1.0) {
var gradient = lerpColor(firstColor, secondColor, this.amt);
this.amt += 0.05;
fill(gradient);
} else {
this.colorState = 0;
this.currentColor = this.nextColor;
this.amt = 0;
}
} else {
if (this.currentColor == "green") {
fill(greenColor);
} else if (this.currentColor == 'blue') {
fill(blueColor);
} else if (this.currentColor == "red") {
fill(redColor);
} else {
fill(orangeColor);
}
}
noStroke();
rect(this.x, this.y, 50, this.height);
fill(color(0, 0, 0));
text(-this.height, this.x + 15, (height / 2) + (this.height) - 20, 60, 60);
function mouseClicked() {
bars[0].colorState = 1;
bars[0].nextColor = "green";
}
我发现将 lerpColor 与 amt 参数一起使用可以让我逐渐改变颜色。当我想淡入下一种颜色时,我将它增加 0.05。截至目前,它可以使颜色褪色,但随后会出现闪烁效果,它会在几毫秒内变黑,我不知道为什么。请帮我解决这个问题。这是 js fiddle:
https://jsfiddle.net/jomzkct4/(稍微向下滚动以查看栏)。
有一个帧,当颜色过渡完成时 amt > 1
,填充颜色没有重新分配,所以它使用前一帧的颜色 fill(color(0, 0, 0))
。您可以通过在此代码块中添加不同的颜色来进行测试:
else {
this.colorState = 0;
this.currentColor = this.nextColor;
this.amt = 0;
// Now it "blinks" red
fill([255, 0, 0])
}
最终,您可能希望在 colorState
值为 0
时重用颜色分配逻辑,或者调整 if (this.colorState == 1) {...} else{...}
块的逻辑。
let bars = []; // array of Bar objects
let values = [];
let greenColor;
let blueColor;
let redColor;
let orangeColor;
function setup() {
//Init colors
greenColor = color(16, 112, 1);
blueColor = color(158, 207, 224);
redColor = color(208, 0, 46);
orangeColor = color(253, 148, 8);
createCanvas(900, 900);
textSize(15);
frameRate(10)
// Create objects
for (let i = 0; i < 10; i++) {
values[i] = round(random(150));
bars.push(new Bar(i*50 + i*10, values[i], -1));
}
}
function draw() {
background(255, 255, 255);
for (let i = 0; i < bars.length; i++) {
bars[i].display();
}
}
// Bar class
class Bar {
constructor(xCord, heightIn) {
this.x = xCord;
this.y = height / 2;
this.speed = 1;
this.height = -heightIn;
this.currentColor = "blue";
this.nextColor = "blue";
this.amt = 0;
this.colorState = 0; //0 for static, 1 for changing
}
display() {
if (this.colorState == 1) {
let firstColor = blueColor;
let secondColor = blueColor;
if (this.currentColor == "green") {
firstColor = greenColor;
} else if (this.currentColor == "red") {
firstColor = redColor;
} else if (this.currentColor == "orange") {
firstColor = orangeColor;
} else {
firstColor = blueColor;
}
if (this.nextColor == "green") {
secondColor = greenColor;
} else if (this.nextColor == "red") {
secondColor = redColor;
} else if (this.nextColor == "orange"){
secondColor = orangeColor;
} else {
firstColor = blueColor;
}
if (this.amt <= 1.0) {
var gradient = lerpColor(firstColor, secondColor, this.amt);
this.amt += 0.05;
fill(gradient);
}
else {
this.colorState = 0;
this.currentColor = this.nextColor;
this.amt = 0;
// Either reuse the logic:
/* if (this.currentColor == "green") {
fill(greenColor);
} else if (this.currentColor == 'blue') {
fill(blueColor);
} else if (this.currentColor == "red") {
fill(redColor);
} else {
fill(orangeColor);
} */
}
}
// or tweak the logic of the if-else block
//else{
if (this.colorState == 0) {
if (this.currentColor == "green") {
fill(greenColor);
} else if (this.currentColor == 'blue') {
fill(blueColor);
} else if (this.currentColor == "red") {
fill(redColor);
} else {
fill(orangeColor);
}
}
noStroke();
rect(this.x, this.y, 50, this.height);
fill(color(0, 0, 0));
text(-this.height, this.x + 15, (height / 2) + (this.height) - 20, 60, 60);
}
}
function mouseClicked() {
bars[0].colorState = 1;
bars[0].nextColor = "green";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.min.js"></script>