From e09d4f9eea6f8fd010e2a06f852f26068e442c7d Mon Sep 17 00:00:00 2001 From: Idrees Hassan Date: Sun, 18 Jan 2026 19:24:17 -0500 Subject: [PATCH] Control hat type from application --- dist/extension.zip | Bin 150655 -> 150770 bytes dist/extension/birb.js | 34 +++++++++++++++++++--------------- dist/obsidian/main.js | 34 +++++++++++++++++++--------------- dist/userscript/birb.user.js | 34 +++++++++++++++++++--------------- dist/web/birb.embed.js | 34 +++++++++++++++++++--------------- dist/web/birb.js | 34 +++++++++++++++++++--------------- src/animation/anim.js | 7 ++++--- src/animation/frame.js | 11 ++++++----- src/application.js | 8 +++++--- src/birb.js | 7 ++++--- src/hats.js | 4 ++-- 11 files changed, 116 insertions(+), 91 deletions(-) diff --git a/dist/extension.zip b/dist/extension.zip index 21abee3cfdc536478b5113038210e184d95fc077..a55ca9fa192aa742fc66b2e1478c69dc955237fd 100644 GIT binary patch delta 25820 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 In0kQ!0b+Pv0RR91 diff --git a/dist/extension/birb.js b/dist/extension/birb.js index ee81ae3..062135a 100644 --- a/dist/extension/birb.js +++ b/dist/extension/birb.js @@ -499,20 +499,21 @@ /** * @param {CanvasRenderingContext2D} ctx - * @param {BirdType} [species] - * @param {number} direction + * @param {number} direction * @param {number} canvasPixelSize + * @param {{ [key: string]: string }} colorScheme + * @param {string[]} tags */ - draw(ctx, direction, canvasPixelSize, species) { + draw(ctx, direction, canvasPixelSize, colorScheme, tags) { // Clear the canvas before drawing the new frame ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); - const pixels = this.getPixels(species?.tags[0]); + const pixels = this.getPixels(tags[0]); for (let y = 0; y < pixels.length; y++) { const row = pixels[y]; for (let x = 0; x < pixels[y].length; x++) { const cell = direction === Directions.LEFT ? row[x] : row[pixels[y].length - x - 1]; - ctx.fillStyle = species?.colors[cell] ?? cell; + ctx.fillStyle = colorScheme[cell] ?? cell; ctx.fillRect(x * canvasPixelSize, y * canvasPixelSize, canvasPixelSize, canvasPixelSize); } } } } @@ -575,10 +576,11 @@ * @param {number} direction * @param {number} timeStart The start time of the animation in milliseconds * @param {number} canvasPixelSize The size of a canvas pixel in pixels - * @param {BirdType} [species] The species to use for the animation + * @param {{ [key: string]: string }} colorScheme The color scheme to use for the animation + * @param {string[]} tags The tags to use for the animation * @returns {boolean} Whether the animation is complete */ - draw(ctx, direction, timeStart, canvasPixelSize, species) { + draw(ctx, direction, timeStart, canvasPixelSize, colorScheme, tags) { // Reset cache if animation was restarted if (this.lastTimeStart !== timeStart) { this.#clearCache(); @@ -595,7 +597,7 @@ const currentFrameIndex = this.getCurrentFrameIndex(time); if (this.#shouldRedraw(currentFrameIndex, direction)) { - this.frames[currentFrameIndex].draw(ctx, direction, canvasPixelSize, species); + this.frames[currentFrameIndex].draw(ctx, direction, canvasPixelSize, colorScheme, tags); this.lastFrameIndex = currentFrameIndex; this.lastDirection = direction; } @@ -699,7 +701,7 @@ } } } - return new Layer(paddedHatPixels); + return new Layer(paddedHatPixels, hatName); } /** @@ -823,12 +825,13 @@ /** * Draw the current animation frame - * @param {BirdType} species The species color data + * @param {BirdType} species The species data + * @param {string} [hat] The name of the current hat * @returns {boolean} Whether the animation has completed (for non-looping animations) */ - draw(species) { + draw(species, hat) { const anim = this.animations[this.currentAnimation]; - return anim.draw(this.ctx, this.direction, this.animStart, this.canvasPixelSize, species); + return anim.draw(this.ctx, this.direction, this.animStart, this.canvasPixelSize, species.colors, [...species.tags, hat || '']); } @@ -2023,6 +2026,7 @@ let petStack = []; let currentSpecies = DEFAULT_BIRD; let unlockedSpecies = [DEFAULT_BIRD]; + let currentHat = HAT.TOP_HAT; // let visible = true; let lastPetTimestamp = 0; /** @type {StickyNote[]} */ @@ -2243,7 +2247,7 @@ flySomewhere(); } - if (birb.draw(SPECIES[currentSpecies])) { + if (birb.draw(SPECIES[currentSpecies], currentHat)) { birb.setAnimation(Animations.STILL); } @@ -2332,7 +2336,7 @@ if (!featherCtx) { return; } - FEATHER_ANIMATIONS.feather.draw(featherCtx, Directions.LEFT, Date.now(), CANVAS_PIXEL_SIZE, type); + FEATHER_ANIMATIONS.feather.draw(featherCtx, Directions.LEFT, Date.now(), CANVAS_PIXEL_SIZE, type.colors, type.tags); document.body.appendChild(featherCanvas); onClick(featherCanvas, () => { unlockBird(birdType); @@ -2478,7 +2482,7 @@ if (!speciesCtx) { return; } - birb.getFrames().base.draw(speciesCtx, Directions.RIGHT, CANVAS_PIXEL_SIZE, type); + birb.getFrames().base.draw(speciesCtx, Directions.RIGHT, CANVAS_PIXEL_SIZE, type.colors, type.tags); speciesElement.appendChild(speciesCanvas); content.appendChild(speciesElement); if (unlocked) { diff --git a/dist/obsidian/main.js b/dist/obsidian/main.js index ac84a97..e41a871 100644 --- a/dist/obsidian/main.js +++ b/dist/obsidian/main.js @@ -504,20 +504,21 @@ module.exports = class PocketBird extends Plugin { /** * @param {CanvasRenderingContext2D} ctx - * @param {BirdType} [species] - * @param {number} direction + * @param {number} direction * @param {number} canvasPixelSize + * @param {{ [key: string]: string }} colorScheme + * @param {string[]} tags */ - draw(ctx, direction, canvasPixelSize, species) { + draw(ctx, direction, canvasPixelSize, colorScheme, tags) { // Clear the canvas before drawing the new frame ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); - const pixels = this.getPixels(species?.tags[0]); + const pixels = this.getPixels(tags[0]); for (let y = 0; y < pixels.length; y++) { const row = pixels[y]; for (let x = 0; x < pixels[y].length; x++) { const cell = direction === Directions.LEFT ? row[x] : row[pixels[y].length - x - 1]; - ctx.fillStyle = species?.colors[cell] ?? cell; + ctx.fillStyle = colorScheme[cell] ?? cell; ctx.fillRect(x * canvasPixelSize, y * canvasPixelSize, canvasPixelSize, canvasPixelSize); } } } } @@ -580,10 +581,11 @@ module.exports = class PocketBird extends Plugin { * @param {number} direction * @param {number} timeStart The start time of the animation in milliseconds * @param {number} canvasPixelSize The size of a canvas pixel in pixels - * @param {BirdType} [species] The species to use for the animation + * @param {{ [key: string]: string }} colorScheme The color scheme to use for the animation + * @param {string[]} tags The tags to use for the animation * @returns {boolean} Whether the animation is complete */ - draw(ctx, direction, timeStart, canvasPixelSize, species) { + draw(ctx, direction, timeStart, canvasPixelSize, colorScheme, tags) { // Reset cache if animation was restarted if (this.lastTimeStart !== timeStart) { this.#clearCache(); @@ -600,7 +602,7 @@ module.exports = class PocketBird extends Plugin { const currentFrameIndex = this.getCurrentFrameIndex(time); if (this.#shouldRedraw(currentFrameIndex, direction)) { - this.frames[currentFrameIndex].draw(ctx, direction, canvasPixelSize, species); + this.frames[currentFrameIndex].draw(ctx, direction, canvasPixelSize, colorScheme, tags); this.lastFrameIndex = currentFrameIndex; this.lastDirection = direction; } @@ -704,7 +706,7 @@ module.exports = class PocketBird extends Plugin { } } } - return new Layer(paddedHatPixels); + return new Layer(paddedHatPixels, hatName); } /** @@ -828,12 +830,13 @@ module.exports = class PocketBird extends Plugin { /** * Draw the current animation frame - * @param {BirdType} species The species color data + * @param {BirdType} species The species data + * @param {string} [hat] The name of the current hat * @returns {boolean} Whether the animation has completed (for non-looping animations) */ - draw(species) { + draw(species, hat) { const anim = this.animations[this.currentAnimation]; - return anim.draw(this.ctx, this.direction, this.animStart, this.canvasPixelSize, species); + return anim.draw(this.ctx, this.direction, this.animStart, this.canvasPixelSize, species.colors, [...species.tags, hat || '']); } @@ -2066,6 +2069,7 @@ module.exports = class PocketBird extends Plugin { let petStack = []; let currentSpecies = DEFAULT_BIRD; let unlockedSpecies = [DEFAULT_BIRD]; + let currentHat = HAT.TOP_HAT; // let visible = true; let lastPetTimestamp = 0; /** @type {StickyNote[]} */ @@ -2286,7 +2290,7 @@ module.exports = class PocketBird extends Plugin { flySomewhere(); } - if (birb.draw(SPECIES[currentSpecies])) { + if (birb.draw(SPECIES[currentSpecies], currentHat)) { birb.setAnimation(Animations.STILL); } @@ -2375,7 +2379,7 @@ module.exports = class PocketBird extends Plugin { if (!featherCtx) { return; } - FEATHER_ANIMATIONS.feather.draw(featherCtx, Directions.LEFT, Date.now(), CANVAS_PIXEL_SIZE, type); + FEATHER_ANIMATIONS.feather.draw(featherCtx, Directions.LEFT, Date.now(), CANVAS_PIXEL_SIZE, type.colors, type.tags); document.body.appendChild(featherCanvas); onClick(featherCanvas, () => { unlockBird(birdType); @@ -2521,7 +2525,7 @@ module.exports = class PocketBird extends Plugin { if (!speciesCtx) { return; } - birb.getFrames().base.draw(speciesCtx, Directions.RIGHT, CANVAS_PIXEL_SIZE, type); + birb.getFrames().base.draw(speciesCtx, Directions.RIGHT, CANVAS_PIXEL_SIZE, type.colors, type.tags); speciesElement.appendChild(speciesCanvas); content.appendChild(speciesElement); if (unlocked) { diff --git a/dist/userscript/birb.user.js b/dist/userscript/birb.user.js index 33cce0c..39bc16f 100644 --- a/dist/userscript/birb.user.js +++ b/dist/userscript/birb.user.js @@ -513,20 +513,21 @@ /** * @param {CanvasRenderingContext2D} ctx - * @param {BirdType} [species] - * @param {number} direction + * @param {number} direction * @param {number} canvasPixelSize + * @param {{ [key: string]: string }} colorScheme + * @param {string[]} tags */ - draw(ctx, direction, canvasPixelSize, species) { + draw(ctx, direction, canvasPixelSize, colorScheme, tags) { // Clear the canvas before drawing the new frame ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); - const pixels = this.getPixels(species?.tags[0]); + const pixels = this.getPixels(tags[0]); for (let y = 0; y < pixels.length; y++) { const row = pixels[y]; for (let x = 0; x < pixels[y].length; x++) { const cell = direction === Directions.LEFT ? row[x] : row[pixels[y].length - x - 1]; - ctx.fillStyle = species?.colors[cell] ?? cell; + ctx.fillStyle = colorScheme[cell] ?? cell; ctx.fillRect(x * canvasPixelSize, y * canvasPixelSize, canvasPixelSize, canvasPixelSize); } } } } @@ -589,10 +590,11 @@ * @param {number} direction * @param {number} timeStart The start time of the animation in milliseconds * @param {number} canvasPixelSize The size of a canvas pixel in pixels - * @param {BirdType} [species] The species to use for the animation + * @param {{ [key: string]: string }} colorScheme The color scheme to use for the animation + * @param {string[]} tags The tags to use for the animation * @returns {boolean} Whether the animation is complete */ - draw(ctx, direction, timeStart, canvasPixelSize, species) { + draw(ctx, direction, timeStart, canvasPixelSize, colorScheme, tags) { // Reset cache if animation was restarted if (this.lastTimeStart !== timeStart) { this.#clearCache(); @@ -609,7 +611,7 @@ const currentFrameIndex = this.getCurrentFrameIndex(time); if (this.#shouldRedraw(currentFrameIndex, direction)) { - this.frames[currentFrameIndex].draw(ctx, direction, canvasPixelSize, species); + this.frames[currentFrameIndex].draw(ctx, direction, canvasPixelSize, colorScheme, tags); this.lastFrameIndex = currentFrameIndex; this.lastDirection = direction; } @@ -713,7 +715,7 @@ } } } - return new Layer(paddedHatPixels); + return new Layer(paddedHatPixels, hatName); } /** @@ -837,12 +839,13 @@ /** * Draw the current animation frame - * @param {BirdType} species The species color data + * @param {BirdType} species The species data + * @param {string} [hat] The name of the current hat * @returns {boolean} Whether the animation has completed (for non-looping animations) */ - draw(species) { + draw(species, hat) { const anim = this.animations[this.currentAnimation]; - return anim.draw(this.ctx, this.direction, this.animStart, this.canvasPixelSize, species); + return anim.draw(this.ctx, this.direction, this.animStart, this.canvasPixelSize, species.colors, [...species.tags, hat || '']); } @@ -2028,6 +2031,7 @@ let petStack = []; let currentSpecies = DEFAULT_BIRD; let unlockedSpecies = [DEFAULT_BIRD]; + let currentHat = HAT.TOP_HAT; // let visible = true; let lastPetTimestamp = 0; /** @type {StickyNote[]} */ @@ -2248,7 +2252,7 @@ flySomewhere(); } - if (birb.draw(SPECIES[currentSpecies])) { + if (birb.draw(SPECIES[currentSpecies], currentHat)) { birb.setAnimation(Animations.STILL); } @@ -2337,7 +2341,7 @@ if (!featherCtx) { return; } - FEATHER_ANIMATIONS.feather.draw(featherCtx, Directions.LEFT, Date.now(), CANVAS_PIXEL_SIZE, type); + FEATHER_ANIMATIONS.feather.draw(featherCtx, Directions.LEFT, Date.now(), CANVAS_PIXEL_SIZE, type.colors, type.tags); document.body.appendChild(featherCanvas); onClick(featherCanvas, () => { unlockBird(birdType); @@ -2483,7 +2487,7 @@ if (!speciesCtx) { return; } - birb.getFrames().base.draw(speciesCtx, Directions.RIGHT, CANVAS_PIXEL_SIZE, type); + birb.getFrames().base.draw(speciesCtx, Directions.RIGHT, CANVAS_PIXEL_SIZE, type.colors, type.tags); speciesElement.appendChild(speciesCanvas); content.appendChild(speciesElement); if (unlocked) { diff --git a/dist/web/birb.embed.js b/dist/web/birb.embed.js index 2f15ba2..3fe2a00 100644 --- a/dist/web/birb.embed.js +++ b/dist/web/birb.embed.js @@ -499,20 +499,21 @@ /** * @param {CanvasRenderingContext2D} ctx - * @param {BirdType} [species] - * @param {number} direction + * @param {number} direction * @param {number} canvasPixelSize + * @param {{ [key: string]: string }} colorScheme + * @param {string[]} tags */ - draw(ctx, direction, canvasPixelSize, species) { + draw(ctx, direction, canvasPixelSize, colorScheme, tags) { // Clear the canvas before drawing the new frame ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); - const pixels = this.getPixels(species?.tags[0]); + const pixels = this.getPixels(tags[0]); for (let y = 0; y < pixels.length; y++) { const row = pixels[y]; for (let x = 0; x < pixels[y].length; x++) { const cell = direction === Directions.LEFT ? row[x] : row[pixels[y].length - x - 1]; - ctx.fillStyle = species?.colors[cell] ?? cell; + ctx.fillStyle = colorScheme[cell] ?? cell; ctx.fillRect(x * canvasPixelSize, y * canvasPixelSize, canvasPixelSize, canvasPixelSize); } } } } @@ -575,10 +576,11 @@ * @param {number} direction * @param {number} timeStart The start time of the animation in milliseconds * @param {number} canvasPixelSize The size of a canvas pixel in pixels - * @param {BirdType} [species] The species to use for the animation + * @param {{ [key: string]: string }} colorScheme The color scheme to use for the animation + * @param {string[]} tags The tags to use for the animation * @returns {boolean} Whether the animation is complete */ - draw(ctx, direction, timeStart, canvasPixelSize, species) { + draw(ctx, direction, timeStart, canvasPixelSize, colorScheme, tags) { // Reset cache if animation was restarted if (this.lastTimeStart !== timeStart) { this.#clearCache(); @@ -595,7 +597,7 @@ const currentFrameIndex = this.getCurrentFrameIndex(time); if (this.#shouldRedraw(currentFrameIndex, direction)) { - this.frames[currentFrameIndex].draw(ctx, direction, canvasPixelSize, species); + this.frames[currentFrameIndex].draw(ctx, direction, canvasPixelSize, colorScheme, tags); this.lastFrameIndex = currentFrameIndex; this.lastDirection = direction; } @@ -699,7 +701,7 @@ } } } - return new Layer(paddedHatPixels); + return new Layer(paddedHatPixels, hatName); } /** @@ -823,12 +825,13 @@ /** * Draw the current animation frame - * @param {BirdType} species The species color data + * @param {BirdType} species The species data + * @param {string} [hat] The name of the current hat * @returns {boolean} Whether the animation has completed (for non-looping animations) */ - draw(species) { + draw(species, hat) { const anim = this.animations[this.currentAnimation]; - return anim.draw(this.ctx, this.direction, this.animStart, this.canvasPixelSize, species); + return anim.draw(this.ctx, this.direction, this.animStart, this.canvasPixelSize, species.colors, [...species.tags, hat || '']); } @@ -2008,6 +2011,7 @@ let petStack = []; let currentSpecies = DEFAULT_BIRD; let unlockedSpecies = [DEFAULT_BIRD]; + let currentHat = HAT.TOP_HAT; // let visible = true; let lastPetTimestamp = 0; /** @type {StickyNote[]} */ @@ -2228,7 +2232,7 @@ flySomewhere(); } - if (birb.draw(SPECIES[currentSpecies])) { + if (birb.draw(SPECIES[currentSpecies], currentHat)) { birb.setAnimation(Animations.STILL); } @@ -2317,7 +2321,7 @@ if (!featherCtx) { return; } - FEATHER_ANIMATIONS.feather.draw(featherCtx, Directions.LEFT, Date.now(), CANVAS_PIXEL_SIZE, type); + FEATHER_ANIMATIONS.feather.draw(featherCtx, Directions.LEFT, Date.now(), CANVAS_PIXEL_SIZE, type.colors, type.tags); document.body.appendChild(featherCanvas); onClick(featherCanvas, () => { unlockBird(birdType); @@ -2463,7 +2467,7 @@ if (!speciesCtx) { return; } - birb.getFrames().base.draw(speciesCtx, Directions.RIGHT, CANVAS_PIXEL_SIZE, type); + birb.getFrames().base.draw(speciesCtx, Directions.RIGHT, CANVAS_PIXEL_SIZE, type.colors, type.tags); speciesElement.appendChild(speciesCanvas); content.appendChild(speciesElement); if (unlocked) { diff --git a/dist/web/birb.js b/dist/web/birb.js index 2f15ba2..3fe2a00 100644 --- a/dist/web/birb.js +++ b/dist/web/birb.js @@ -499,20 +499,21 @@ /** * @param {CanvasRenderingContext2D} ctx - * @param {BirdType} [species] - * @param {number} direction + * @param {number} direction * @param {number} canvasPixelSize + * @param {{ [key: string]: string }} colorScheme + * @param {string[]} tags */ - draw(ctx, direction, canvasPixelSize, species) { + draw(ctx, direction, canvasPixelSize, colorScheme, tags) { // Clear the canvas before drawing the new frame ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); - const pixels = this.getPixels(species?.tags[0]); + const pixels = this.getPixels(tags[0]); for (let y = 0; y < pixels.length; y++) { const row = pixels[y]; for (let x = 0; x < pixels[y].length; x++) { const cell = direction === Directions.LEFT ? row[x] : row[pixels[y].length - x - 1]; - ctx.fillStyle = species?.colors[cell] ?? cell; + ctx.fillStyle = colorScheme[cell] ?? cell; ctx.fillRect(x * canvasPixelSize, y * canvasPixelSize, canvasPixelSize, canvasPixelSize); } } } } @@ -575,10 +576,11 @@ * @param {number} direction * @param {number} timeStart The start time of the animation in milliseconds * @param {number} canvasPixelSize The size of a canvas pixel in pixels - * @param {BirdType} [species] The species to use for the animation + * @param {{ [key: string]: string }} colorScheme The color scheme to use for the animation + * @param {string[]} tags The tags to use for the animation * @returns {boolean} Whether the animation is complete */ - draw(ctx, direction, timeStart, canvasPixelSize, species) { + draw(ctx, direction, timeStart, canvasPixelSize, colorScheme, tags) { // Reset cache if animation was restarted if (this.lastTimeStart !== timeStart) { this.#clearCache(); @@ -595,7 +597,7 @@ const currentFrameIndex = this.getCurrentFrameIndex(time); if (this.#shouldRedraw(currentFrameIndex, direction)) { - this.frames[currentFrameIndex].draw(ctx, direction, canvasPixelSize, species); + this.frames[currentFrameIndex].draw(ctx, direction, canvasPixelSize, colorScheme, tags); this.lastFrameIndex = currentFrameIndex; this.lastDirection = direction; } @@ -699,7 +701,7 @@ } } } - return new Layer(paddedHatPixels); + return new Layer(paddedHatPixels, hatName); } /** @@ -823,12 +825,13 @@ /** * Draw the current animation frame - * @param {BirdType} species The species color data + * @param {BirdType} species The species data + * @param {string} [hat] The name of the current hat * @returns {boolean} Whether the animation has completed (for non-looping animations) */ - draw(species) { + draw(species, hat) { const anim = this.animations[this.currentAnimation]; - return anim.draw(this.ctx, this.direction, this.animStart, this.canvasPixelSize, species); + return anim.draw(this.ctx, this.direction, this.animStart, this.canvasPixelSize, species.colors, [...species.tags, hat || '']); } @@ -2008,6 +2011,7 @@ let petStack = []; let currentSpecies = DEFAULT_BIRD; let unlockedSpecies = [DEFAULT_BIRD]; + let currentHat = HAT.TOP_HAT; // let visible = true; let lastPetTimestamp = 0; /** @type {StickyNote[]} */ @@ -2228,7 +2232,7 @@ flySomewhere(); } - if (birb.draw(SPECIES[currentSpecies])) { + if (birb.draw(SPECIES[currentSpecies], currentHat)) { birb.setAnimation(Animations.STILL); } @@ -2317,7 +2321,7 @@ if (!featherCtx) { return; } - FEATHER_ANIMATIONS.feather.draw(featherCtx, Directions.LEFT, Date.now(), CANVAS_PIXEL_SIZE, type); + FEATHER_ANIMATIONS.feather.draw(featherCtx, Directions.LEFT, Date.now(), CANVAS_PIXEL_SIZE, type.colors, type.tags); document.body.appendChild(featherCanvas); onClick(featherCanvas, () => { unlockBird(birdType); @@ -2463,7 +2467,7 @@ if (!speciesCtx) { return; } - birb.getFrames().base.draw(speciesCtx, Directions.RIGHT, CANVAS_PIXEL_SIZE, type); + birb.getFrames().base.draw(speciesCtx, Directions.RIGHT, CANVAS_PIXEL_SIZE, type.colors, type.tags); speciesElement.appendChild(speciesCanvas); content.appendChild(speciesElement); if (unlocked) { diff --git a/src/animation/anim.js b/src/animation/anim.js index abdfad0..c41d5db 100644 --- a/src/animation/anim.js +++ b/src/animation/anim.js @@ -59,10 +59,11 @@ class Anim { * @param {number} direction * @param {number} timeStart The start time of the animation in milliseconds * @param {number} canvasPixelSize The size of a canvas pixel in pixels - * @param {BirdType} [species] The species to use for the animation + * @param {{ [key: string]: string }} colorScheme The color scheme to use for the animation + * @param {string[]} tags The tags to use for the animation * @returns {boolean} Whether the animation is complete */ - draw(ctx, direction, timeStart, canvasPixelSize, species) { + draw(ctx, direction, timeStart, canvasPixelSize, colorScheme, tags) { // Reset cache if animation was restarted if (this.lastTimeStart !== timeStart) { this.#clearCache(); @@ -79,7 +80,7 @@ class Anim { const currentFrameIndex = this.getCurrentFrameIndex(time); if (this.#shouldRedraw(currentFrameIndex, direction)) { - this.frames[currentFrameIndex].draw(ctx, direction, canvasPixelSize, species); + this.frames[currentFrameIndex].draw(ctx, direction, canvasPixelSize, colorScheme, tags); this.lastFrameIndex = currentFrameIndex; this.lastDirection = direction; } diff --git a/src/animation/frame.js b/src/animation/frame.js index b623e41..5f75869 100644 --- a/src/animation/frame.js +++ b/src/animation/frame.js @@ -53,20 +53,21 @@ class Frame { /** * @param {CanvasRenderingContext2D} ctx - * @param {BirdType} [species] - * @param {number} direction + * @param {number} direction * @param {number} canvasPixelSize + * @param {{ [key: string]: string }} colorScheme + * @param {string[]} tags */ - draw(ctx, direction, canvasPixelSize, species) { + draw(ctx, direction, canvasPixelSize, colorScheme, tags) { // Clear the canvas before drawing the new frame ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); - const pixels = this.getPixels(species?.tags[0]); + const pixels = this.getPixels(tags[0]); for (let y = 0; y < pixels.length; y++) { const row = pixels[y]; for (let x = 0; x < pixels[y].length; x++) { const cell = direction === Directions.LEFT ? row[x] : row[pixels[y].length - x - 1]; - ctx.fillStyle = species?.colors[cell] ?? cell; + ctx.fillStyle = colorScheme[cell] ?? cell; ctx.fillRect(x * canvasPixelSize, y * canvasPixelSize, canvasPixelSize, canvasPixelSize); }; }; diff --git a/src/application.js b/src/application.js index 713e79b..5b4ad56 100644 --- a/src/application.js +++ b/src/application.js @@ -43,6 +43,7 @@ import { switchMenuItems, MENU_EXIT_ID } from './menu.js'; +import { HAT } from './hats.js'; /** @@ -236,6 +237,7 @@ function startApplication(birbPixels, featherPixels, hatsPixels) { let petStack = []; let currentSpecies = DEFAULT_BIRD; let unlockedSpecies = [DEFAULT_BIRD]; + let currentHat = HAT.TOP_HAT; // let visible = true; let lastPetTimestamp = 0; /** @type {StickyNote[]} */ @@ -456,7 +458,7 @@ function startApplication(birbPixels, featherPixels, hatsPixels) { flySomewhere(); } - if (birb.draw(SPECIES[currentSpecies])) { + if (birb.draw(SPECIES[currentSpecies], currentHat)) { birb.setAnimation(Animations.STILL); } @@ -548,7 +550,7 @@ function startApplication(birbPixels, featherPixels, hatsPixels) { if (!featherCtx) { return; } - FEATHER_ANIMATIONS.feather.draw(featherCtx, Directions.LEFT, Date.now(), CANVAS_PIXEL_SIZE, type); + FEATHER_ANIMATIONS.feather.draw(featherCtx, Directions.LEFT, Date.now(), CANVAS_PIXEL_SIZE, type.colors, type.tags); document.body.appendChild(featherCanvas); onClick(featherCanvas, () => { unlockBird(birdType); @@ -695,7 +697,7 @@ function startApplication(birbPixels, featherPixels, hatsPixels) { if (!speciesCtx) { return; } - birb.getFrames().base.draw(speciesCtx, Directions.RIGHT, CANVAS_PIXEL_SIZE, type); + birb.getFrames().base.draw(speciesCtx, Directions.RIGHT, CANVAS_PIXEL_SIZE, type.colors, type.tags); speciesElement.appendChild(speciesCanvas); content.appendChild(speciesElement); if (unlocked) { diff --git a/src/birb.js b/src/birb.js index 83f1490..cfc2c65 100644 --- a/src/birb.js +++ b/src/birb.js @@ -126,12 +126,13 @@ export class Birb { /** * Draw the current animation frame - * @param {BirdType} species The species color data + * @param {BirdType} species The species data + * @param {string} [hat] The name of the current hat * @returns {boolean} Whether the animation has completed (for non-looping animations) */ - draw(species) { + draw(species, hat) { const anim = this.animations[this.currentAnimation]; - return anim.draw(this.ctx, this.direction, this.animStart, this.canvasPixelSize, species); + return anim.draw(this.ctx, this.direction, this.animStart, this.canvasPixelSize, species.colors, [...species.tags, hat || '']); } diff --git a/src/hats.js b/src/hats.js index 8d01392..c5526a6 100644 --- a/src/hats.js +++ b/src/hats.js @@ -2,7 +2,7 @@ import Layer from "./animation/layer.js"; import { PALETTE } from "./animation/sprites.js"; import { getLayerPixels } from "./shared.js"; -const HAT = { +export const HAT = { TOP_HAT: 'top-hat' }; @@ -96,5 +96,5 @@ function buildHatLayer(spriteSheet, hatName, outlineBottom = false, yOffset = 0) } } } - return new Layer(paddedHatPixels); + return new Layer(paddedHatPixels, hatName); } \ No newline at end of file