fix(layout): size top section to actual video aspect ratio (no letterbox) (v0.7.0)

This commit is contained in:
2026-05-05 18:25:52 +00:00
parent ddcdda2d5a
commit a2cf430cd8
+18 -6
View File
@@ -24,7 +24,7 @@
}; };
})(); })();
const VERSION = '0.6.0'; const VERSION = '0.7.0';
class WebrtcDoorbellCard extends HTMLElement { class WebrtcDoorbellCard extends HTMLElement {
setConfig(config) { setConfig(config) {
@@ -147,24 +147,36 @@ class WebrtcDoorbellCard extends HTMLElement {
].join(';'); ].join(';');
wrap.appendChild(stack); wrap.appendChild(stack);
const mkVideo = (objectFit, flexBasis) => { const mkVideo = (objectFit, flex, extra) => {
const v = document.createElement('video'); const v = document.createElement('video');
v.autoplay = true; v.autoplay = true;
v.muted = true; v.muted = true;
v.playsInline = true; v.playsInline = true;
v.setAttribute('playsinline', ''); v.setAttribute('playsinline', '');
v.style.cssText = [ v.style.cssText = [
`flex:${flexBasis}`, `flex:${flex}`,
'width:100%', 'min-height:0', 'width:100%', 'min-height:0',
`object-fit:${objectFit}`, `object-fit:${objectFit}`,
'background:black', 'background:black',
extra || '',
].join(';'); ].join(';');
return v; return v;
}; };
// Top: full uncropped frame (see the sides). Bottom: cover crop (fills width). // Top: full uncropped frame, sized to match the video's aspect ratio so
this._topVideo = mkVideo('contain', '0 0 40%'); // there's no letterbox. Bottom: takes the remaining height with a cover crop.
this._bottomVideo = mkVideo('cover', '1 1 60%'); // We default to a 16:9 aspect-ratio and refine once metadata loads.
this._topVideo = mkVideo(
'contain',
'0 0 auto',
'aspect-ratio:16/9;max-height:50vh',
);
this._bottomVideo = mkVideo('cover', '1 1 auto');
this._topVideo.addEventListener('loadedmetadata', () => {
const vw = this._topVideo.videoWidth;
const vh = this._topVideo.videoHeight;
if (vw && vh) this._topVideo.style.aspectRatio = `${vw}/${vh}`;
});
stack.appendChild(this._topVideo); stack.appendChild(this._topVideo);
stack.appendChild(this._bottomVideo); stack.appendChild(this._bottomVideo);
} }