mirror of
https://github.com/NohamR/Pocket-Bird.git
synced 2026-05-24 19:59:36 +00:00
Add heart animation and window
This commit is contained in:
210
birb.js
210
birb.js
@@ -35,7 +35,8 @@ const HOP_SPEED = settings.hopSpeed;
|
||||
const FLY_SPEED = settings.flySpeed;
|
||||
const HOP_DISTANCE = settings.hopDistance;
|
||||
// Time in milliseconds until the user is considered AFK
|
||||
const AFK_TIME = 1000 * 20;
|
||||
const AFK_TIME = 1000 * 30;
|
||||
const MAX_HEIGHT = 32;
|
||||
|
||||
const styles = `
|
||||
#birb {
|
||||
@@ -45,6 +46,7 @@ const styles = `
|
||||
transform: scale(${CSS_SCALE});
|
||||
transform-origin: bottom;
|
||||
z-index: 999999999;
|
||||
cursor: pointer;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -62,13 +64,19 @@ class Frame {
|
||||
* @param {Layer[]} layers
|
||||
*/
|
||||
constructor(layers) {
|
||||
// Combine layers
|
||||
let maxHeight = layers.reduce((max, layer) => Math.max(max, layer.pixels.length), 0);
|
||||
this.pixels = layers[0].pixels.map(row => row.slice());
|
||||
// Pad from top with transparent pixels
|
||||
while (this.pixels.length < maxHeight) {
|
||||
this.pixels.unshift(new Array(this.pixels[0].length).fill(___));
|
||||
}
|
||||
// Combine layers
|
||||
for (let i = 1; i < layers.length; i++) {
|
||||
let layerPixels = layers[i].pixels;
|
||||
let topMargin = maxHeight - layerPixels.length;
|
||||
for (let y = 0; y < layerPixels.length; y++) {
|
||||
for (let x = 0; x < layerPixels[y].length; x++) {
|
||||
this.pixels[y][x] = layerPixels[y][x] !== ___ ? layerPixels[y][x] : this.pixels[y][x];
|
||||
this.pixels[y + topMargin][x] = layerPixels[y][x] !== ___ ? layerPixels[y][x] : this.pixels[y + topMargin][x];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,9 +112,10 @@ class Frame {
|
||||
for (let y = 0; y < this.pixels.length; y++) {
|
||||
const row = this.pixels[y];
|
||||
for (let x = 0; x < this.pixels[y].length; x++) {
|
||||
let topMargin = MAX_HEIGHT - this.pixels.length;
|
||||
const cell = direction === Directions.LEFT ? row[x] : row[this.pixels[y].length - x - 1];
|
||||
ctx.fillStyle = colors[cell];
|
||||
ctx.fillRect(x * CANVAS_PIXEL_SIZE, y * CANVAS_PIXEL_SIZE, CANVAS_PIXEL_SIZE, CANVAS_PIXEL_SIZE);
|
||||
ctx.fillRect(x * CANVAS_PIXEL_SIZE, (y + topMargin) * CANVAS_PIXEL_SIZE, CANVAS_PIXEL_SIZE, CANVAS_PIXEL_SIZE);
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -165,6 +174,9 @@ const BEL = "belly";
|
||||
const UND = "underbelly";
|
||||
const WNG = "wing";
|
||||
const WNE = "wing-edge";
|
||||
const HRT = "heart";
|
||||
const HRB = "heart-border";
|
||||
const HRS = "heart-shine";
|
||||
|
||||
const colors = {
|
||||
[___]: "transparent",
|
||||
@@ -178,9 +190,12 @@ const colors = {
|
||||
[UND]: "#ec8637",
|
||||
[WNG]: "#578ae6",
|
||||
[WNE]: "#326ed9",
|
||||
[HRT]: "#c82e2e",
|
||||
[HRB]: "#501a1a",
|
||||
[HRS]: "#ff6b6b",
|
||||
};
|
||||
|
||||
const transparent = new Layer([
|
||||
const transparentLayer = new Layer([
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
@@ -205,7 +220,7 @@ const transparent = new Layer([
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___]
|
||||
]);
|
||||
|
||||
const base = new Layer([
|
||||
const baseLayer = new Layer([
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
@@ -230,7 +245,32 @@ const base = new Layer([
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
]);
|
||||
|
||||
const down = new Layer(base.pixels.map((row, rowIndex) => {
|
||||
const happyEyeLayer = new Layer([
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, EYE, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, EYE, ___, EYE, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___]
|
||||
]);
|
||||
|
||||
const downLayer = new Layer(baseLayer.pixels.map((row, rowIndex) => {
|
||||
if (rowIndex === 16) {
|
||||
const newRow = row.slice();
|
||||
newRow[4] = OUT;
|
||||
@@ -240,9 +280,9 @@ const down = new Layer(base.pixels.map((row, rowIndex) => {
|
||||
}
|
||||
return row.slice();
|
||||
}).filter((_, i) => i !== 15));
|
||||
down.pixels.unshift(down.pixels[0].slice());
|
||||
downLayer.pixels.unshift(downLayer.pixels[0].slice());
|
||||
|
||||
const wingsUp = new Layer([
|
||||
const wingsUpLayer = new Layer([
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
@@ -267,7 +307,7 @@ const wingsUp = new Layer([
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___]
|
||||
]);
|
||||
|
||||
const wingsDown = new Layer([
|
||||
const wingsDownLayer = new Layer([
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
@@ -292,11 +332,78 @@ const wingsDown = new Layer([
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___]
|
||||
]);
|
||||
|
||||
const heartOneLayer = new Layer([
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, HRT, ___, HRT, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, HRT, HRT, HRT, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, HRT, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
]);
|
||||
|
||||
for (let i = 0; i < 19; i++) {
|
||||
heartOneLayer.pixels.push(heartOneLayer.pixels[heartOneLayer.pixels.length - 1].slice());
|
||||
}
|
||||
|
||||
const heartTwoLayer = new Layer([
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, HRB, ___, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, HRB, HRT, HRB, HRT, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, HRB, HRT, HRT, HRT, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, HRB, HRT, HRT, HRT, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, HRB, HRT, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
]);
|
||||
|
||||
for (let i = 0; i < 20; i++) {
|
||||
heartTwoLayer.pixels.push(heartTwoLayer.pixels[heartTwoLayer.pixels.length - 1].slice());
|
||||
}
|
||||
|
||||
const heartThreeLayer = new Layer([
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, HRB, HRB, ___, HRB, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, HRB, HRT, HRS, HRB, HRT, HRS, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, HRB, HRT, HRT, HRT, HRT, HRT, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, HRB, HRT, HRT, HRT, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, HRB, HRT, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
]);
|
||||
|
||||
for (let i = 0; i < 21; i++) {
|
||||
heartThreeLayer.pixels.push(heartThreeLayer.pixels[heartThreeLayer.pixels.length - 1].slice());
|
||||
}
|
||||
|
||||
const heartFourLayer = new Layer([
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, HRB, HRB, ___, HRB, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, HRB, HRT, HRS, HRB, HRT, HRS, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, HRB, HRT, HRT, HRT, HRT, HRT, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, HRB, HRT, HRT, HRT, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, HRB, HRT, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, HRB, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
[___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___],
|
||||
]);
|
||||
|
||||
for (let i = 0; i < 20; i++) {
|
||||
heartFourLayer.pixels.push(heartThreeLayer.pixels[heartThreeLayer.pixels.length - 1].slice());
|
||||
}
|
||||
|
||||
const sharedFrames = {
|
||||
base: new Frame([base]),
|
||||
headDown: new Frame([down]),
|
||||
wingsDown: new Frame([base, wingsDown]),
|
||||
wingsUp: new Frame([down, wingsUp]),
|
||||
base: new Frame([baseLayer]),
|
||||
headDown: new Frame([downLayer]),
|
||||
wingsDown: new Frame([baseLayer, wingsDownLayer]),
|
||||
wingsUp: new Frame([downLayer, wingsUpLayer]),
|
||||
heartOne: new Frame([baseLayer, happyEyeLayer, heartOneLayer]),
|
||||
heartTwo: new Frame([baseLayer, happyEyeLayer, heartTwoLayer]),
|
||||
heartThree: new Frame([baseLayer, happyEyeLayer, heartThreeLayer]),
|
||||
heartFour: new Frame([baseLayer, happyEyeLayer, heartFourLayer]),
|
||||
};
|
||||
|
||||
|
||||
@@ -306,20 +413,39 @@ const Animations = {
|
||||
sharedFrames.base,
|
||||
sharedFrames.headDown
|
||||
], [
|
||||
1200,
|
||||
250
|
||||
420,
|
||||
420
|
||||
]),
|
||||
FLYING: new Anim([
|
||||
sharedFrames.base,
|
||||
sharedFrames.wingsUp,
|
||||
sharedFrames.headDown,
|
||||
sharedFrames.wingsDown,
|
||||
sharedFrames.base,
|
||||
], [
|
||||
40,
|
||||
80,
|
||||
40,
|
||||
80,
|
||||
40
|
||||
]),
|
||||
HEART: new Anim([
|
||||
sharedFrames.heartOne,
|
||||
sharedFrames.heartTwo,
|
||||
sharedFrames.heartThree,
|
||||
sharedFrames.heartFour,
|
||||
sharedFrames.heartThree,
|
||||
sharedFrames.heartFour,
|
||||
sharedFrames.heartThree,
|
||||
sharedFrames.heartFour,
|
||||
], [
|
||||
60,
|
||||
80,
|
||||
250,
|
||||
250,
|
||||
250,
|
||||
250,
|
||||
250,
|
||||
250,
|
||||
], false),
|
||||
};
|
||||
|
||||
const styleElement = document.createElement("style");
|
||||
@@ -333,8 +459,8 @@ if (window === window.top) {
|
||||
// Insert a canvas element into the body with the same dimensions as the 2D array
|
||||
canvas.id = "birb";
|
||||
canvas.width = sharedFrames.base.pixels[0].length * CANVAS_PIXEL_SIZE;
|
||||
canvas.height = sharedFrames.base.pixels.length * CANVAS_PIXEL_SIZE;
|
||||
document.body.appendChild(canvas);
|
||||
canvas.height = MAX_HEIGHT * CANVAS_PIXEL_SIZE;
|
||||
document.body.appendChild(canvas);
|
||||
}
|
||||
|
||||
/** @type {CanvasRenderingContext2D} */
|
||||
@@ -371,6 +497,8 @@ let targetY = 0;
|
||||
let focusedElement = null;
|
||||
// Time of the user's last action on the page
|
||||
let timeOfLastAction = Date.now();
|
||||
// Stack of timestamps for each mouseover, max length of 10
|
||||
let petStack = [];
|
||||
|
||||
function update() {
|
||||
ticks++;
|
||||
@@ -391,6 +519,7 @@ window.addEventListener("scroll", () => {
|
||||
if (isMobile()) {
|
||||
focusOnGround();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
document.addEventListener("click", (e) => {
|
||||
@@ -401,6 +530,29 @@ document.addEventListener("click", (e) => {
|
||||
// focusOnElement();
|
||||
});
|
||||
|
||||
canvas.addEventListener("click", () => {
|
||||
focusOnElement();
|
||||
if (focusedElement === null && currentState === States.IDLE) {
|
||||
setAnimation(Animations.HEART)
|
||||
}
|
||||
});
|
||||
|
||||
canvas.addEventListener("mouseover", () => {
|
||||
timeOfLastAction = Date.now();
|
||||
if (currentState === States.IDLE) {
|
||||
petStack.push(Date.now());
|
||||
if (petStack.length > 10) {
|
||||
petStack.shift();
|
||||
}
|
||||
const pets = petStack.filter((time) => Date.now() - time < 1000).length;
|
||||
if (pets >= 4) {
|
||||
setAnimation(Animations.HEART);
|
||||
// Clear the stack
|
||||
petStack = [];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
setInterval(update, 1000 / 60);
|
||||
|
||||
function draw() {
|
||||
@@ -504,6 +656,14 @@ function parabolicLerp(startX, startY, endX, endY, amount, intensity = 1.2) {
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
function getFocusedElementRandomX() {
|
||||
if (focusedElement === null) {
|
||||
return Math.random() * window.innerWidth;
|
||||
}
|
||||
const rect = focusedElement.getBoundingClientRect();
|
||||
return Math.random() * (rect.right - rect.left) + rect.left;
|
||||
}
|
||||
|
||||
function getFocusedElementY() {
|
||||
if (focusedElement === null) {
|
||||
return 0;
|
||||
@@ -533,9 +693,7 @@ function focusOnElement() {
|
||||
}
|
||||
const randomImage = largeImages[Math.floor(Math.random() * largeImages.length)];
|
||||
focusedElement = randomImage;
|
||||
const rect = randomImage.getBoundingClientRect();
|
||||
const x = Math.random() * (rect.right - rect.left) + rect.left;
|
||||
flyTo(x, getFocusedElementY());
|
||||
flyTo(getFocusedElementRandomX(), getFocusedElementY());
|
||||
}
|
||||
|
||||
function getCanvasWidth() {
|
||||
@@ -570,10 +728,6 @@ function hop() {
|
||||
}
|
||||
}
|
||||
|
||||
canvas.addEventListener("click", () => {
|
||||
focusOnElement();
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
@@ -627,7 +781,7 @@ function setX(x) {
|
||||
* @param {number} y
|
||||
*/
|
||||
function setY(y) {
|
||||
canvas.style.bottom = `${y - WINDOW_PIXEL_SIZE}px`;
|
||||
canvas.style.bottom = `${y}px`;
|
||||
}
|
||||
|
||||
|
||||
|
||||
86
index.html
86
index.html
@@ -14,6 +14,83 @@
|
||||
#spacer {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
:root {
|
||||
--border-size: 3px;
|
||||
--neg-border-size: calc(var(--border-size) * -1);
|
||||
--double-border-size: calc(var(--border-size) * 2);
|
||||
--neg-double-border-size: calc(var(--neg-border-size) * 2);
|
||||
}
|
||||
|
||||
.window {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
/* transform: scale(3); */
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background-color: #ffecda;
|
||||
box-shadow:
|
||||
var(--border-size) 0 black,
|
||||
var(--neg-border-size) 0 black,
|
||||
0 var(--neg-border-size) black,
|
||||
0 var(--border-size) black,
|
||||
var(--double-border-size) 0 black,
|
||||
var(--neg-double-border-size) 0 black,
|
||||
0 var(--neg-double-border-size) black,
|
||||
0 var(--double-border-size) black,
|
||||
0 0 0 var(--border-size) black,
|
||||
0 0 0 var(--double-border-size) white,
|
||||
var(--double-border-size) 0 0 var(--border-size) white,
|
||||
var(--neg-double-border-size) 0 0 var(--border-size) white,
|
||||
0 var(--neg-double-border-size) 0 var(--border-size) white,
|
||||
0 var(--double-border-size) 0 var(--border-size) white;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.window-header {
|
||||
font-family: "Monocraft";
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 7px;
|
||||
padding-top: 1px;
|
||||
padding-bottom: 4px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
background-color: #ffa3cb;
|
||||
box-shadow:
|
||||
var(--border-size) 0 #ffa3cb,
|
||||
var(--neg-border-size) 0 #ffa3cb,
|
||||
0 var(--neg-border-size) #ffa3cb,
|
||||
var(--neg-border-size) var(--border-size) black,
|
||||
var(--border-size) var(--border-size) black;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.window-content {
|
||||
box-sizing: border-box;
|
||||
background-color: #ffecda;
|
||||
margin-top: var(--border-size);
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
box-shadow:
|
||||
var(--border-size) 0 #ffecda,
|
||||
var(--neg-border-size) 0 #ffecda,
|
||||
0 var(--neg-border-size) black,
|
||||
0 var(--border-size) black;
|
||||
}
|
||||
|
||||
.window-close {
|
||||
cursor: pointer;
|
||||
padding: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -24,6 +101,15 @@
|
||||
<img src="./images/bird-2.jpg" alt="Bird 2" style="width: 300px; height: auto; margin: 10px;">
|
||||
<img src="./images/bird-3.jpg" alt="Bird 3" style="width: 300px; height: auto; margin: 10px;">
|
||||
</div>
|
||||
<div class="window">
|
||||
<div class="window-header">
|
||||
<div class="window-title">Birb Sandbox</div>
|
||||
<div class="window-close">x</div>
|
||||
</div>
|
||||
<div class="window-content">
|
||||
<div class="birb"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="spacer"></div>
|
||||
<script src="birb.js"></script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user