Lay the party logo over the background
Centred, spanning 60% of the screen width, on the poster's layer so the video frame and the stills still pass in front of it. The file lives in assets/ with the posters, so it has to be kept out of the background rotation — it is the one image there that is never a background. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H9v2Xoa6eoeGYpK6gp95k9
This commit is contained in:
@@ -17,11 +17,24 @@ import {
|
||||
BACKGROUND_MAX_ZOOM,
|
||||
BACKGROUND_FOCUS_SPREAD,
|
||||
BACKGROUND_MAX_OVERSAMPLE,
|
||||
LOGO_SRC,
|
||||
LOGO_WIDTH,
|
||||
} from '/config.js';
|
||||
import { createPicker } from './motion.js';
|
||||
|
||||
const KEYS = Object.keys(BACKGROUNDS);
|
||||
|
||||
/**
|
||||
* Point the logo overlay at the configured file and size it against the
|
||||
* screen. The element is in the page from the start — only the two values that
|
||||
* belong to the config are set here.
|
||||
*/
|
||||
export function showLogo(element) {
|
||||
if (!element) return;
|
||||
element.src = LOGO_SRC;
|
||||
element.style.width = `${LOGO_WIDTH * 100}vw`;
|
||||
}
|
||||
|
||||
/**
|
||||
* A zoom level and the point of the image the crop closes in on, in percent.
|
||||
* The focal point is pulled toward the middle by BACKGROUND_FOCUS_SPREAD, so a
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
<body>
|
||||
<div id="backgrounds"></div>
|
||||
|
||||
<!-- The party's logo, centred over the poster. Its src and width come from
|
||||
the shared config, so the file can be swapped without touching this. -->
|
||||
<img id="logo" alt="" />
|
||||
|
||||
<!-- Frozen screenshots of the frame. A sibling, not a child, of #frameMover:
|
||||
these are positioned against the screen, not the moving frame. -->
|
||||
<div id="stills"></div>
|
||||
|
||||
@@ -42,6 +42,23 @@ body {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* The logo sits on the poster, not on the video: it shares the backdrop's
|
||||
layer so the frame and the stills still pass in front of it. Its width comes
|
||||
from LOGO_WIDTH, written onto the element by backdrop.js. */
|
||||
#logo {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
translate: -50% -50%;
|
||||
height: auto;
|
||||
/* Only bites on a screen too short for the width above — on the projector
|
||||
the width is what decides. */
|
||||
max-height: 70vh;
|
||||
object-fit: contain;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
/* Built and removed by the wash animation. Sits between the poster and the
|
||||
stills, and blends rather than covers, so the poster stays legible through
|
||||
whatever colour is passing over it. The gradient itself is written per frame
|
||||
|
||||
@@ -2,7 +2,7 @@ import { connect } from '/shared/socket.js';
|
||||
import { OVERLAP_SECONDS, HARD_CUT_SECONDS, AUTO_BACKGROUND, AUTO_ANIMATION } from '/config.js';
|
||||
import { createPlayer, loadApi, STATE } from './yt.js';
|
||||
import { startAnimationCycle } from './motion.js';
|
||||
import { startBackgroundCycle } from './backdrop.js';
|
||||
import { startBackgroundCycle, showLogo } from './backdrop.js';
|
||||
import { requestCapture } from './capture.js';
|
||||
|
||||
const TICK_MS = 250;
|
||||
@@ -25,6 +25,8 @@ const backgrounds = startBackgroundCycle(
|
||||
state.background,
|
||||
);
|
||||
|
||||
showLogo(document.getElementById('logo'));
|
||||
|
||||
// --- start gate ---------------------------------------------------------
|
||||
|
||||
const gate = document.getElementById('gate');
|
||||
|
||||
Reference in New Issue
Block a user