Skip to content

Commit

Permalink
Merge pull request #673 from code-dot-org/ben/break-up-background-and…
Browse files Browse the repository at this point in the history
…-foreground-effects

Break up background and foreground effects
  • Loading branch information
bencodeorg authored Dec 14, 2023
2 parents 4c7f4e9 + e2343ce commit 8d51ef6
Show file tree
Hide file tree
Showing 12 changed files with 298 additions and 224 deletions.
102 changes: 15 additions & 87 deletions src/Effects.js → src/BackgroundEffects.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const constants = require('./constants');
const utils = require('./utils');

// background
const discoBall = require('./effects/background/discoBall');
const higherPower = require('./effects/background/higherPower');
const rainbow = require('./effects/background/rainbow');
Expand Down Expand Up @@ -30,68 +30,30 @@ const growingStars = require('./effects/background/growingStars');
const squiggles = require('./effects/background/squiggles');
const musicWave = require('./effects/background/musicWave');

// foreground
const rain = require('./effects/foreground/rain');
const rainingTacos = require('./effects/foreground/rainingTacos');
const pineapples = require('./effects/foreground/pineapples');
const spotlight = require('./effects/foreground/spotlight');
const colorLights = require('./effects/foreground/colorLights');
const smilingPoop = require('./effects/foreground/smilingPoop');
const heartsRed = require('./effects/foreground/heartsRed');
const heartsColorful = require('./effects/foreground/heartsColorful');
const floatingRainbows = require('./effects/foreground/floatingRainbows');
const bubbles = require('./effects/foreground/bubbles');
const explodingStars = require('./effects/foreground/explodingStars');
const pizzas = require('./effects/foreground/pizzas');
const smileFace = require('./effects/foreground/smileFace');
const confetti = require('./effects/foreground/confetti');
const musicNotes = require('./effects/foreground/musicNotes');
const paintDrip = require('./effects/foreground/paintDrip');
const emojis = require('./effects/foreground/emojis');

module.exports = class Effects {
constructor(p5, alpha, extraImages, blend, currentPalette = 'default') {
module.exports = class BackgroundEffects {
constructor(p5, getEffectsInPreviewMode, extraImages) {
this.p5_ = p5;
this.extraImages = extraImages;
this.blend = blend || p5.BLEND;
this.currentPalette = currentPalette;
this.inPreviewMode = false;
const getInPreviewMode = this.getInPreviewMode.bind(this);

this.currentPalette = 'default';

// Duplicated in ForegroundEffects
function randomNumber(min, max) {
return Math.round(p5.random(min, max));
}

function colorFromHue(h, s = 100, l = 80, a = alpha) {
// Duplicated in ForegroundEffects
function colorFromHue(h, s = 100, l = 80, a = constants.EFFECT_OPACITY.BACKGROUND) {
return p5.color(
'hsla(' + Math.floor(h % 360) + ', ' + s + '%, ' + l + '%,' + a + ')'
);
}

function randomColor(s = 100, l = 80, a = alpha) {
return colorFromHue(randomNumber(0, 359), s, l, a);
}

const colorFromPalette = n => {
const palette = constants.PALETTES[this.currentPalette];
return palette[n % palette.length];
};

const lerpColorFromPalette = amount => {
return lerpColorFromSpecificPalette(this.currentPalette, amount);
};

const lerpColorFromSpecificPalette = (paletteName, amount) => {
const palette = constants.PALETTES[paletteName];
const which = amount * palette.length;
const n = Math.floor(which);
const remainder = which - n;

const prev = palette[n % palette.length];
const next = palette[(n + 1) % palette.length];

return p5.lerpColor(p5.color(prev), p5.color(next), remainder);
return utils.lerpColorFromSpecificPalette(p5, this.currentPalette, amount);
};

const randomColorFromPalette = () => {
Expand All @@ -109,7 +71,6 @@ module.exports = class Effects {
},
};

// background
this.disco_ball = discoBall(p5, lerpColorFromPalette, colorFromPalette);
this.higher_power = higherPower(p5, getCurrentPalette, extraImages);
this.rainbow = rainbow(p5, lerpColorFromPalette);
Expand All @@ -122,57 +83,23 @@ module.exports = class Effects {
this.clouds = clouds(p5, lerpColorFromPalette);
this.frosted_grid = frostedGrid(p5, getCurrentPalette, randomNumber);
this.starburst = starburst(p5, lerpColorFromPalette, randomColorFromPalette, randomNumber);
this.diamonds = diamonds(p5, lerpColorFromPalette, getInPreviewMode);
this.diamonds = diamonds(p5, lerpColorFromPalette, getEffectsInPreviewMode);
this.circles = circles(p5, lerpColorFromPalette);
this.sparkles = sparkles(p5, randomColorFromPalette, randomNumber);
this.text = text(p5, lerpColorFromPalette, colorFromHue, randomNumber, getInPreviewMode);
this.text = text(p5, lerpColorFromPalette, colorFromHue, randomNumber, getEffectsInPreviewMode);
this.splatter = splatter(p5, randomColorFromPalette);
this.swirl = swirl(p5, randomColorFromPalette);
this.spiral = spiral(p5, lerpColorFromPalette);
this.lasers = lasers(p5, lerpColorFromPalette, getInPreviewMode);
this.lasers = lasers(p5, lerpColorFromPalette, getEffectsInPreviewMode);
this.quads = quads(p5, colorFromPalette);
this.kaleidoscope = kaleidoscope(p5, colorFromPalette);
this.snowflakes = snowflakes(p5, lerpColorFromPalette, getInPreviewMode);
this.snowflakes = snowflakes(p5, lerpColorFromPalette, getEffectsInPreviewMode);
this.fireworks = fireworks(p5, randomColorFromPalette, randomNumber);
this.stars = stars(p5, randomColorFromPalette, getInPreviewMode);
this.galaxy = galaxy(p5, randomColorFromPalette, randomNumber, getInPreviewMode);
this.stars = stars(p5, randomColorFromPalette, getEffectsInPreviewMode);
this.galaxy = galaxy(p5, randomColorFromPalette, randomNumber, getEffectsInPreviewMode);
this.growing_stars = growingStars(p5, colorFromPalette);
this.squiggles = squiggles(p5, lerpColorFromPalette);
this.music_wave = musicWave(p5, lerpColorFromPalette);

// foreground
this.rain = rain(p5, randomNumber);
this.raining_tacos = rainingTacos(p5, randomNumber, getInPreviewMode);
this.pineapples = pineapples(p5, randomNumber, getInPreviewMode);
this.spotlight = spotlight(p5, randomNumber);
this.color_lights = colorLights(p5, randomNumber, randomColor);
this.smiling_poop = smilingPoop(p5, randomNumber, getInPreviewMode);
this.hearts_red = heartsRed(p5, randomNumber);
this.hearts_colorful = heartsColorful(p5, randomNumber, randomColor);
this.floating_rainbows = floatingRainbows(p5, randomNumber, getInPreviewMode);
this.bubbles = bubbles(p5, randomColor, getInPreviewMode);
this.exploding_stars = explodingStars(p5, randomNumber, randomColor, getInPreviewMode);
this.pizzas = pizzas(p5, randomNumber, getInPreviewMode);
this.smile_face = smileFace(p5, randomNumber, getInPreviewMode);
this.confetti = confetti(p5, randomColor, getInPreviewMode);
this.music_notes = musicNotes(p5, randomNumber, getInPreviewMode);
this.paint_drip = paintDrip(p5, lerpColorFromSpecificPalette, getInPreviewMode);
this.emojis = emojis(p5, randomNumber, getInPreviewMode);
}

setInPreviewMode(inPreviewMode) {
this.inPreviewMode = inPreviewMode;
}

getInPreviewMode() {
return this.inPreviewMode;
}

randomForegroundEffect() {
const effects = constants.FOREGROUND_EFFECTS.filter(name =>
this.hasOwnProperty(name)
);
return this.sample_(effects);
}

randomBackgroundEffect() {
Expand All @@ -186,6 +113,7 @@ module.exports = class Effects {
return this.sample_(Object.keys(constants.PALETTES));
}

// Duplicated in ForegroundEffects
/**
* Randomly pick one element out of an array.
* @param {Array.<T>} collection
Expand Down
84 changes: 84 additions & 0 deletions src/ForegroundEffects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const constants = require('./constants');
const utils = require('./utils');

const rain = require('./effects/foreground/rain');
const rainingTacos = require('./effects/foreground/rainingTacos');
const pineapples = require('./effects/foreground/pineapples');
const spotlight = require('./effects/foreground/spotlight');
const colorLights = require('./effects/foreground/colorLights');
const smilingPoop = require('./effects/foreground/smilingPoop');
const heartsRed = require('./effects/foreground/heartsRed');
const heartsColorful = require('./effects/foreground/heartsColorful');
const floatingRainbows = require('./effects/foreground/floatingRainbows');
const bubbles = require('./effects/foreground/bubbles');
const explodingStars = require('./effects/foreground/explodingStars');
const pizzas = require('./effects/foreground/pizzas');
const smileFace = require('./effects/foreground/smileFace');
const confetti = require('./effects/foreground/confetti');
const musicNotes = require('./effects/foreground/musicNotes');
const paintDrip = require('./effects/foreground/paintDrip');
const emojis = require('./effects/foreground/emojis');

module.exports = class ForegroundEffects {
constructor(p5, getEffectsInPreviewMode) {
this.p5_ = p5;

// Duplicated in BackgroundEffects
function randomNumber(min, max) {
return Math.round(p5.random(min, max));
}

// Duplicated in BackgroundEffects
function colorFromHue(h, s = 100, l = 80, a = constants.EFFECT_OPACITY.FOREGROUND) {
return p5.color(
'hsla(' + Math.floor(h % 360) + ', ' + s + '%, ' + l + '%,' + a + ')'
);
}

function randomColor(s = 100, l = 80, a = constants.EFFECT_OPACITY.FOREGROUND) {
return colorFromHue(randomNumber(0, 359), s, l, a);
}

// selecting "none" as a foreground is a no-op,
// whereas selecting it as a background actually draws a white background.
this.none = {
draw: utils.noOp,
};

this.rain = rain(p5, randomNumber);
this.raining_tacos = rainingTacos(p5, randomNumber, getEffectsInPreviewMode);
this.pineapples = pineapples(p5, randomNumber, getEffectsInPreviewMode);
this.spotlight = spotlight(p5, randomNumber);
this.color_lights = colorLights(p5, randomNumber, randomColor);
this.smiling_poop = smilingPoop(p5, randomNumber, getEffectsInPreviewMode);
this.hearts_red = heartsRed(p5, randomNumber);
this.hearts_colorful = heartsColorful(p5, randomNumber, randomColor);
this.floating_rainbows = floatingRainbows(p5, randomNumber, getEffectsInPreviewMode);
this.bubbles = bubbles(p5, randomColor, getEffectsInPreviewMode);
this.exploding_stars = explodingStars(p5, randomNumber, randomColor, getEffectsInPreviewMode);
this.pizzas = pizzas(p5, randomNumber, getEffectsInPreviewMode);
this.smile_face = smileFace(p5, randomNumber, getEffectsInPreviewMode);
this.confetti = confetti(p5, randomColor, getEffectsInPreviewMode);
this.music_notes = musicNotes(p5, randomNumber, getEffectsInPreviewMode);
this.paint_drip = paintDrip(p5, getEffectsInPreviewMode);
this.emojis = emojis(p5, randomNumber, getEffectsInPreviewMode);
}

randomForegroundEffect() {
const effects = constants.FOREGROUND_EFFECTS.filter(name =>
this.hasOwnProperty(name)
);
return this.sample_(effects);
}

// Duplicated in BackgroundEffects
/**
* Randomly pick one element out of an array.
* @param {Array.<T>} collection
* @returns {T}
* @private
*/
sample_(collection) {
return collection[Math.floor(this.p5_.random(0, collection.length))];
}
};
66 changes: 35 additions & 31 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,54 +43,54 @@ module.exports = {
{name: 'XSlide', mirror: false, shortBurst: true},
],
RANDOM_EFFECT_KEY: 'rand',
BACKGROUND_EFFECTS: [
BACKGROUND_EFFECTS: [ // Effect name in Code.org Dance Party (if different than key listed here)
'blooming_petals',
'circles',
'color_cycle',
'clouds',
'color_cycle', // Colors
'diamonds',
'disco', // Squares
'disco_ball',
'fireworks',
'swirl',
'flowers',
'frosted_grid',
'galaxy', // Space
'growing_stars',
'kaleidoscope',
'lasers',
'splatter',
'lasers', // Laser Dance Floor
'music_wave', // Waves
'quads', // Angles
'rainbow',
'snowflakes',
'text',
'galaxy',
'sparkles',
'spiral',
'disco',
'stars',
'music_wave',
'ripples',
'ripples_random',
'quads',
'flowers',
'snowflakes', // Snow
'sparkles',
'spiral',
'splatter', // Paint Splatter
'squiggles',
'growing_stars',
'blooming_petals',
'clouds',
'frosted_grid',
'starburst',
'stars',
'swirl', // Hypno
'text' // Song Names
],
FOREGROUND_EFFECTS: [
FOREGROUND_EFFECTS: [ // Effect name in Code.org Dance Party (if different than key listed here)
'bubbles',
'color_lights', // Stage Lights
'confetti',
'hearts_red',
'emojis',
'exploding_stars', // Starburst
'floating_rainbows', // Rainbows
'hearts_colorful', // Colorful Hearts
'hearts_red', // Hearts
'music_notes',
'paint_drip',
'pineapples',
'pizzas',
'smiling_poop',
'rain',
'floating_rainbows',
'smile_face',
'spotlight',
'color_lights',
'raining_tacos',
'emojis',
'hearts_colorful',
'exploding_stars',
'paint_drip',
'raining_tacos', // Tacos
'smile_face', // Smiles
'smiling_poop', // Poop
'spotlight'
],
PALETTES: {
default: ['#ffa899', '#99aaff', '#99ffac', '#fcff99', '#ffdd99'],
Expand Down Expand Up @@ -143,4 +143,8 @@ module.exports = {
roses: ['#A00B64', '#121212'], // magenta to black
},
KEY_WENT_DOWN_EVENT_TYPE: 'this.p5_.keyWentDown',
EFFECT_OPACITY: {
BACKGROUND: 1,
FOREGROUND: 0.8,
},
};
6 changes: 4 additions & 2 deletions src/effects/foreground/paintDrip.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
module.exports = function (p5, lerpColorFromSpecificPalette, getInPreviewMode) {
const utils = require('../../utils');

module.exports = function (p5, getInPreviewMode) {
return {
current_drip: 0,
current_drip_height: 0,
Expand Down Expand Up @@ -26,7 +28,7 @@ module.exports = function (p5, lerpColorFromSpecificPalette, getInPreviewMode) {
},
draw: function () {
for (let i = 0; i < this.crayons.length; i++) {
let c = lerpColorFromSpecificPalette('neon', i / this.crayons.length);
let c = utils.lerpColorFromSpecificPalette(p5, 'neon', i / this.crayons.length);
p5.fill(c);
p5.noStroke();
let rectHeight = this.getPreviewCustomizations().getRectHeight();
Expand Down
6 changes: 4 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
const DanceParty = require('./p5.dance');
const Effects = require('./Effects');
const BackgroundEffects = require('./BackgroundEffects');
const ForegroundEffects = require('./ForegroundEffects');
const ResourceLoader = require('./ResourceLoader');
const constants = require('./constants');

module.exports = {
DanceParty,
Effects,
BackgroundEffects,
ForegroundEffects,
ResourceLoader,
constants,
};
Loading

0 comments on commit 8d51ef6

Please sign in to comment.