mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat: add background video preset (#607)
This commit is contained in:
@@ -24,21 +24,6 @@
|
||||
"development": "./dist/dev/index.js",
|
||||
"default": "./dist/default/index.js"
|
||||
},
|
||||
"./video/*": {
|
||||
"types": "./dist/dev/define/video/*.d.ts",
|
||||
"development": "./dist/dev/define/video/*.js",
|
||||
"default": "./dist/default/define/video/*.js"
|
||||
},
|
||||
"./audio/*": {
|
||||
"types": "./dist/dev/define/audio/*.d.ts",
|
||||
"development": "./dist/dev/define/audio/*.js",
|
||||
"default": "./dist/default/define/audio/*.js"
|
||||
},
|
||||
"./background/*": {
|
||||
"types": "./dist/dev/define/background/*.d.ts",
|
||||
"development": "./dist/dev/define/background/*.js",
|
||||
"default": "./dist/default/define/background/*.js"
|
||||
},
|
||||
"./ui/*": {
|
||||
"types": "./dist/dev/define/ui/*.d.ts",
|
||||
"development": "./dist/dev/define/ui/*.js",
|
||||
@@ -53,6 +38,12 @@
|
||||
"types": "./dist/dev/define/media/*.d.ts",
|
||||
"development": "./dist/dev/define/media/*.js",
|
||||
"default": "./dist/default/define/media/*.js"
|
||||
},
|
||||
"./*.css": "./dist/default/define/*.css",
|
||||
"./*": {
|
||||
"types": "./dist/dev/define/*.d.ts",
|
||||
"development": "./dist/dev/define/*.js",
|
||||
"default": "./dist/default/define/*.js"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
background-video-player {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
background-video-skin {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
--media-object-fit: cover;
|
||||
object-fit: var(--media-object-fit);
|
||||
}
|
||||
|
||||
background-video-skin > [slot="media"] {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: inherit;
|
||||
}
|
||||
|
||||
background-video-skin > img,
|
||||
background-video-skin > picture {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: inherit;
|
||||
}
|
||||
@@ -1 +1,33 @@
|
||||
// TODO: Implement BackgroundVideoSkinElement and then register it here
|
||||
import { ReactiveElement } from '@videojs/element';
|
||||
import { namedNodeMapToObject } from '@videojs/utils/dom';
|
||||
|
||||
function getTemplateHTML(_attrs: Record<string, string>) {
|
||||
return /*html*/ `
|
||||
<media-container>
|
||||
<slot name="media" slot="media"></slot>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
export class BackgroundVideoSkinElement extends ReactiveElement {
|
||||
static readonly tagName = 'background-video-skin';
|
||||
static shadowRootOptions = { mode: 'open' as ShadowRootMode };
|
||||
static getTemplateHTML = getTemplateHTML;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
if (!this.shadowRoot) {
|
||||
this.attachShadow((this.constructor as typeof BackgroundVideoSkinElement).shadowRootOptions);
|
||||
this.shadowRoot!.innerHTML = getTemplateHTML(namedNodeMapToObject(this.attributes));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(BackgroundVideoSkinElement.tagName, BackgroundVideoSkinElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[BackgroundVideoSkinElement.tagName]: BackgroundVideoSkinElement;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from '../media/background-video';
|
||||
Vendored
+5
@@ -1 +1,6 @@
|
||||
declare const __DEV__: boolean;
|
||||
|
||||
declare module '*.css' {
|
||||
const content: string;
|
||||
export default content;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CustomMediaMixin } from '@videojs/core/dom/media/custom-media-element';
|
||||
import { namedNodeMapToObject } from '@videojs/utils/dom';
|
||||
|
||||
function getTemplateHTML(attrs: Record<string, string>) {
|
||||
return /*html*/ `
|
||||
@@ -12,7 +12,8 @@ function getTemplateHTML(attrs: Record<string, string>) {
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: inherit;
|
||||
object-fit: var(--media-object-fit, inherit);
|
||||
object-position: var(--media-object-position, 50% 50%);
|
||||
}
|
||||
</style>
|
||||
<slot></slot>
|
||||
@@ -20,9 +21,13 @@ function getTemplateHTML(attrs: Record<string, string>) {
|
||||
`;
|
||||
}
|
||||
|
||||
export class BackgroundVideo extends CustomMediaMixin(HTMLElement, { tag: 'video' }) {
|
||||
// Don't extend CustomMediaMixin to save some bytes, background videos don't need the full Media API.
|
||||
export class BackgroundVideo extends HTMLElement {
|
||||
static shadowRootOptions = { mode: 'open' as ShadowRootMode };
|
||||
static getTemplateHTML = getTemplateHTML;
|
||||
static get observedAttributes() {
|
||||
return ['src'];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -42,15 +47,27 @@ export class BackgroundVideo extends CustomMediaMixin(HTMLElement, { tag: 'video
|
||||
|
||||
this.shadowRoot!.innerHTML = getTemplateHTML(attrs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function namedNodeMapToObject(namedNodeMap: NamedNodeMap) {
|
||||
const obj: Record<string, string> = {};
|
||||
for (const attr of namedNodeMap) {
|
||||
obj[attr.name] = attr.value;
|
||||
// Neither Chrome or Firefox support setting the muted attribute
|
||||
// after using document.createElement.
|
||||
// Get around this by setting the muted property manually.
|
||||
this.target!.muted = !this.hasAttribute('nomuted');
|
||||
}
|
||||
|
||||
attributeChangedCallback(attrName: string, oldValue: string | null, newValue: string | null): void {
|
||||
if (attrName === 'src' && oldValue !== newValue) {
|
||||
this.target!.src = newValue ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
get target(): HTMLVideoElement | null {
|
||||
return (
|
||||
this.querySelector(':scope > [slot=media]') ??
|
||||
this.querySelector('video') ??
|
||||
this.shadowRoot?.querySelector('video') ??
|
||||
null
|
||||
);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
const VideoAttributes = [
|
||||
|
||||
@@ -32,6 +32,24 @@ const createConfig = (mode: BuildMode): UserConfig => ({
|
||||
__DEV__: mode === 'dev' ? 'true' : 'false',
|
||||
},
|
||||
dts: mode === 'dev',
|
||||
copy: [
|
||||
{
|
||||
from: 'src/**/*.css',
|
||||
to: `dist/${mode}`,
|
||||
flatten: false,
|
||||
},
|
||||
],
|
||||
plugins: [
|
||||
{
|
||||
name: 'watch-css',
|
||||
buildStart() {
|
||||
const cssFiles = globSync('src/**/*.css');
|
||||
for (const file of cssFiles) {
|
||||
this.addWatchFile(file);
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export default defineConfig(buildModes.map((mode) => createConfig(mode)));
|
||||
|
||||
Reference in New Issue
Block a user