Skip to content

Commit

Permalink
Merge pull request #672 from code-dot-org/ben/break-up-effects
Browse files Browse the repository at this point in the history
Break up Effects.js
  • Loading branch information
bencodeorg authored Dec 14, 2023
2 parents a7297ab + 5c6c6b8 commit 4c7f4e9
Show file tree
Hide file tree
Showing 46 changed files with 2,464 additions and 2,293 deletions.
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

0 comments on commit 4c7f4e9

Please sign in to comment.