Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Break up Effects.js #672

Merged
merged 3 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,391 changes: 98 additions & 2,293 deletions src/Effects.js

Large diffs are not rendered by default.

58 changes: 58 additions & 0 deletions src/effects/background/bloomingPetals.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
const constants = require('../../constants');
const {hexToRgb} = require('../../utils');
const drawPetal = require('../../shapes/petal');

// This effect is slightly modified from Poetry background effect 'blooming'
// https://github.com/code-dot-org/code-dot-org/blob/381e9b93f7cbd081738dfa7adbc9e7ce4e169a0c/apps/src/p5lab/poetry/commands/backgroundEffects.js#L245
module.exports = function (p5, getCurrentPalette, colorFromPalette) {
return {
colorIndex: 0,
petals: [],
paletteLength: 0,
addPetalLayer: function (color, layer) {
for (let i = 0; i < 8; i++) {
this.petals.push({
theta: 45 * i,
length: 10 + 140 * layer,
...color,
});
}
},
init: function () {
this.paletteLength = constants.PALETTES[getCurrentPalette()].length;
this.petals = [];
// Initialize with enough petals to fill the screen - this is mostly
// useful so that preview shows what the background actually looks like.
// Increment from 3 down to 0 so that petals are layered correctly with
// bigger petals behind smaller petals.
for (let layer = 3; layer >= 0; layer--) {
const color = colorFromPalette(this.colorIndex);
this.addPetalLayer(hexToRgb(color), layer);
this.colorIndex = (this.colorIndex + 1) % this.paletteLength;
}
},
draw: function () {
p5.push();
p5.strokeWeight(2);
if (p5.World.frameCount % 70 === 0) {
const color = colorFromPalette(this.colorIndex);
this.addPetalLayer(hexToRgb(color), 0 /* layer */);
this.colorIndex = (this.colorIndex + 1) % this.paletteLength;
}
const petalWidth = 35;
this.petals.forEach(petal => {
// Multiply each component by 0.8 to have the stroke color be
// slightly darker than the fill color.
p5.stroke(
p5.color(petal.R * 0.8, petal.G * 0.8, petal.B * 0.8)
);
p5.fill(p5.color(petal.R, petal.G, petal.B));
drawPetal(p5, petal.length, petal.theta, petalWidth);
petal.theta = (petal.theta + 0.5) % 360;
petal.length += 2;
});
this.petals = this.petals.filter(petal => petal.length < 700);
p5.pop();
},
};
};
22 changes: 22 additions & 0 deletions src/effects/background/circles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module.exports = function (p5, lerpColorFromPalette) {
return {
hue: 0,
update: function () {
this.hue += 25;
},
draw: function ({isPeak}) {
if (isPeak) {
this.update();
}
p5.push();
p5.noStroke();
p5.ellipseMode(p5.CENTER);
p5.translate(200, 200);
for (let i = 5; i > -1; i--) {
p5.fill(lerpColorFromPalette(((this.hue + i * 10) % 360) / 360));
p5.ellipse(0, 0, i * 100 + 75, i * 100 + 75);
}
p5.pop();
},
};
};
47 changes: 47 additions & 0 deletions src/effects/background/clouds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const {getP5Color} = require('../../utils');

// This effect is slightly modified from Poetry background effect 'clouds'
// https://github.com/code-dot-org/code-dot-org/blob/381e9b93f7cbd081738dfa7adbc9e7ce4e169a0c/apps/src/p5lab/poetry/commands/backgroundEffects.js#L368
module.exports = function (p5, lerpColorFromPalette) {
return {
tileSize: 20,
tiles: [],
init: function () {
const noiseScale = 0.05;
this.tiles = [];
let xnoise = 0.01;
let ynoise = 0.01;
for (let x = 0; x < 400; x += this.tileSize) {
xnoise = 0.01;
for (let y = 0; y < 400; y += this.tileSize) {
this.tiles.push({
x,
y,
xnoise,
ynoise,
});
xnoise += noiseScale;
}
ynoise += noiseScale;
}
},
draw: function () {
const speed = 0.015;
let backgroundAmount = 0;
p5.push();
p5.noStroke();
backgroundAmount += speed;
p5.background(
lerpColorFromPalette(backgroundAmount)
);
this.tiles.forEach(tile => {
tile.alpha = p5.noise(tile.xnoise, tile.ynoise) * 255;
tile.xnoise += speed;
tile.ynoise += speed;
p5.fill(getP5Color(p5, '#ffffff', tile.alpha));
p5.rect(tile.x, tile.y, this.tileSize, this.tileSize);
});
p5.pop();
},
};
};
14 changes: 14 additions & 0 deletions src/effects/background/colorCycle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = function (p5, lerpColorFromPalette) {
return {
color: 0,
update: function () {
this.color += 0.03;
},
draw: function ({isPeak}) {
if (isPeak) {
this.update();
}
p5.background(lerpColorFromPalette(this.color));
},
};
};
30 changes: 30 additions & 0 deletions src/effects/background/diamonds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
module.exports = function (p5, lerpColorFromPalette, getInPreviewMode) {
return {
hue: 0,
update: function () {
this.hue += 25;
},
draw: function ({isPeak, centroid}) {
if (isPeak) {
this.update();
}
const centroidValue = this.getPreviewCustomizations().getCentroid(centroid);
p5.push();
p5.rectMode(p5.CENTER);
p5.translate(200, 200);
p5.rotate(45);
p5.noFill();
p5.strokeWeight(p5.map(centroidValue, 0, 4000, 0, 50));
for (let i = 5; i > -1; i--) {
p5.stroke(lerpColorFromPalette(((this.hue + i * 10) % 360) / 360));
p5.rect(0, 0, i * 100 + 50, i * 100 + 50);
}
p5.pop();
},
getPreviewCustomizations: function () {
return getInPreviewMode() ?
{getCentroid: () => 2000} :
{getCentroid: centroid => centroid};
},
};
};
49 changes: 49 additions & 0 deletions src/effects/background/disco.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
module.exports = function (p5, lerpColorFromPalette, randomNumber) {
return {
bg: undefined,
colors: [],
squaresPerSide: 4,
minColorChangesPerUpdate: 5,
maxColorChangesPerUpdate: 9,
init: function () {
if (this.colors.length) {
return;
}
// Alpha is ignored for this effect to avoid memory leaks with too many
// layers of alpha blending.
this.colors.length = this.squaresPerSide * this.squaresPerSide;
for (let i = 0; i < this.colors.length; i++) {
this.colors[i] = lerpColorFromPalette(p5.random(0, 1));
}
},
update: function () {
const numChanges = randomNumber(
this.minColorChangesPerUpdate,
this.maxColorChangesPerUpdate
);
for (let i = 0; i < numChanges; i++) {
const loc = randomNumber(0, this.colors.length);
this.colors[loc] = lerpColorFromPalette(p5.random(0, 1));
}
},
draw: function ({isPeak}) {
if (isPeak) {
this.update();
}
p5.push();
p5.noStroke();
const squareWidth = p5.width / this.squaresPerSide;
const squareHeight = p5.height / this.squaresPerSide;
for (let i = 0; i < this.colors.length; i++) {
p5.fill(this.colors[i]);
p5.rect(
(i % this.squaresPerSide) * squareWidth,
Math.floor(i / this.squaresPerSide) * squareHeight,
squareWidth,
squareHeight
);
}
p5.pop();
},
};
};
104 changes: 104 additions & 0 deletions src/effects/background/discoBall.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const drawSparkle = require("../../shapes/sparkle");

module.exports = function (p5, lerpColorFromPalette, colorFromPalette) {
return {
stars: [],
globe: function (u, v) {
u = p5.constrain(u, -90, 90);
return {
x: (1 + p5.sin(u) * p5.sin(v)) * 45 + 155,
y: (1 + p5.cos(v)) * 45 + 10,
};
},
quad: function (i, j, faceSize, rotation = 0) {
const k = ((i + rotation) % 360) - 180;
if (k < -90 - faceSize || k > 90) {
return;
}
const color = lerpColorFromPalette(p5.noise(i, j, p5.frameCount / 70));
const highlight = 50 * p5.pow(p5.cos(k), 2);
const brightness =
p5.noise(i, j, p5.frameCount / 50) * 150 + 100 + highlight;
p5.fill(p5.lerpColor(color, p5.color(brightness), brightness / 255));
const a = this.globe(k, j);
const b = this.globe(k + faceSize, j);
const c = this.globe(k + faceSize, j + faceSize);
const d = this.globe(k, j + faceSize);
p5.quad(a.x, a.y, b.x, b.y, c.x, c.y, d.x, d.y);
},
init: function () {
this.stars.length = 0;

for (let i = 0; i < 75; i++) {
this.stars.push({
x: p5.random(0, 400),
y: p5.random(0, 250),
color: p5.lerpColor(
lerpColorFromPalette(p5.random()),
p5.color('#fff'),
0.75
),
});
}
},
draw: function () {
p5.noFill();
// Draw a horizontal gradient of the palette colors to the background
let ctx = p5._renderer.drawingContext;
ctx.save();
let gradient = ctx.createLinearGradient(425, 425, 425, 0);
// Initialize first color stop so colors loop
let color = colorFromPalette(0);
gradient.addColorStop(0, color);
for (let i = 0; i < 5; i++) {
let color = colorFromPalette(i);
gradient.addColorStop((5 - i) / 5, color.toString());
}
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 425, 425);
ctx.restore();

p5.noStroke();

for (const star of this.stars) {
const distanceFromCenter = 200 - star.x;
const opacity = p5.constrain(p5.cos(distanceFromCenter / 2), 0, 4);
const heightFade = p5.constrain(250 - star.y, 0, 500);
p5.push();
p5.translate(star.x, star.y);
const sparkle = p5.constrain(
p5.noise(star.x / 50, star.y / 50, p5.frameCount / 50) + 0.4,
0,
1
);
p5.drawingContext.globalAlpha = opacity * (heightFade / 100) * 0.85;
p5.scale(1 / sparkle);
drawSparkle(p5._renderer.drawingContext, star.color);
p5.pop();

// Move the star to the left.
star.x -= 4.5 - opacity * 1.5;

// If we've gone off-screen, loop around to the right.
if (star.x < 0) {
star.x = 400;
}
}

p5.noiseDetail(50, 0.5);
p5.stroke('#999');
p5.strokeWeight(2);
p5.line(200, 0, 200, 15);
p5.strokeWeight(0.25);

const step = 20;
for (let i = 0; i <= 360; i += step) {
for (let j = 0; j < 180; j += step) {
p5.push();
this.quad(i, j, step, p5.frameCount * 2);
p5.pop();
}
}
},
};
};
Loading
Loading