YouTubeEmbed
A YouTube video that loads nothing but its poster until the play button is clicked, then starts at once.
Demo
Nothing loaded from YouTube yet: only the poster image.
Get it
It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.
$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/youtube_embed.qwemain.qwe
import ui/theme.qwe use theme_cssuse ui/youtube_embed.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>Example
The code of the preview above.
demos/youtube_embed.qwe
component YouTubeEmbedDemoLive() { state loaded = false <div.demo-stack> <YouTubeEmbed video="aqz-KE-bpKQ" title="Big Buck Bunny" on_play={() => { loaded = true }}/> <p.demo-note id="youtube-embed-demo-note">{loaded ? "The player is loaded." : "Nothing loaded from YouTube yet: only the poster image."}</p> </div>}view YouTubeEmbedDemo() = <div.demo-stack> <YouTubeEmbedDemoLive/> <div style="max-width: 360px"> <YouTubeEmbed video="aqz-KE-bpKQ" title="From the second minute" start={120} ratio="4/3"/> </div> </div>Source
ui/youtube_embed.qwe
// YouTubeEmbed: a YouTube video that costs the page nothing until it is// wanted: the poster shows with a play button, and YouTube's player loads only// when that is clicked, then starts at once. The poster is YouTube's own// thumbnail for the video; the player comes from youtube-nocookie.com.//// <YouTubeEmbed video="aqz-KE-bpKQ" title="Big Buck Bunny"/>// <YouTubeEmbed video="aqz-KE-bpKQ" title="Big Buck Bunny" start={90} poster="max"/>//// video: the video's id (the v= of its address). title (required): its name,// on the play button and the player. start: seconds in to start at. ratio: the// shape ("16/9"). poster: "hq" (default, 480px wide) or "max" (the largest// YouTube has; not every video has one). on_play(): inside one of your// components, called when the player is loaded.import ui/theme.qwe use ui_clslet youtube_embed_css = css`.ui-youtube-embed { position: relative; overflow: hidden; width: 100%; aspect-ratio: var(--r, 16/9); border-radius: var(--ui-radius); background: #000; }.ui-youtube-embed-poster { position: absolute; inset: 0; display: block; width: 100%; height: 100%; padding: 0; border: 0; background: #000; cursor: pointer; }.ui-youtube-embed-poster img { display: block; width: 100%; height: 100%; object-fit: cover; opacity: .9; transition: opacity .2s; }.ui-youtube-embed-poster:hover img { opacity: 1; }.ui-youtube-embed-poster:focus-visible { outline: none; box-shadow: var(--ui-focus); }.ui-youtube-embed-play { position: absolute; top: 50%; left: 50%; width: 68px; height: 48px; transform: translate(-50%, -50%); border-radius: 12px; background: rgba(20, 20, 20, .8); color: #fff; transition: background .15s;}.ui-youtube-embed-poster:hover .ui-youtube-embed-play { background: #f00; }.ui-youtube-embed-play svg { position: absolute; inset: 0; margin: auto; width: 24px; height: 24px; }.ui-youtube-embed-title { position: absolute; inset: 0 0 auto 0; padding: 12px 16px; background: linear-gradient(to bottom, rgba(0, 0, 0, .6), transparent); color: #fff; font: 500 15px/1.3 var(--ui-font); text-align: left; text-shadow: 0 1px 2px rgba(0, 0, 0, .5); }.ui-youtube-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }@media (prefers-reduced-motion: reduce) { .ui-youtube-embed-poster img, .ui-youtube-embed-play { transition: none; } }`component YouTubeEmbed(video: str, title: str, start: int = 0, ratio: str = "16/9", poster: str = "hq", on_play = null, class: str? = null) { style global youtube_embed_css state on = false let thumb = `https://i.ytimg.com/vi/${url_encode(video)}/${poster == "max" ? "maxresdefault" : "hqdefault"}.jpg` let player = `https://www.youtube-nocookie.com/embed/${url_encode(video)}?autoplay=1&rel=0${start > 0 ? `&start=${start}` : ""}` <div class={ui_cls(["ui-youtube-embed", class])} style={`--r: ${ratio}`} data-video={video}> {on ? <iframe src={player} title={title} allow="autoplay; encrypted-media; picture-in-picture; fullscreen" allowfullscreen={true} referrerpolicy="strict-origin-when-cross-origin"></iframe> : <button.ui-youtube-embed-poster type="button" aria-label={`Play video: ${title}`} @click={() => { on = true on_play && on_play() }}> <img src={thumb} alt="" loading="lazy"/> <span.ui-youtube-embed-title aria-hidden="true">{title}</span> <span.ui-youtube-embed-play aria-hidden="true"> <svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg> </span> </button>} </div>}Related
EmbedFrameAnother page in a frame that keeps its shape and fills its width, with a title, permissions and a sandbox.5 views · 5 downloadsVideoPlayerA video with the kit's own controls: play, seek, time, volume, full screen and the keyboard.7 views · 6 downloadsAudioPlayerAn audio clip with play, a seek bar that says the time, and a button cycling through playback speeds.6 views · 7 downloadsCameraCaptureTakes a photo with the camera into a hidden input as a data URL, with retake, and says so when there is no camera.6 views · 6 downloadsCoverImageA wide picture with a title, subtitle and actions over a gradient, in three heights.7 views · 7 downloadsFigureAn image (or anything) with a caption and a credit under it, as a figure with its figcaption.8 views · 9 downloads
Thread
Thread 0 posts
On YouTubeEmbed: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.