mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-04 16:42:27 +00:00
feat(registry): add yt-avatar-pip — circle pip window
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
a4ef52fcb0
commit
d924630f23
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
title: "Circle PiP Window"
|
||||||
|
description: "Circular or rounded-rect masked picture-in-picture window with ring and shadow for a second video or image; pop in/out helpers"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Circle PiP Window
|
||||||
|
|
||||||
|
Circular or rounded-rect masked picture-in-picture window with ring and shadow for a second video or image; pop in/out helpers
|
||||||
|
|
||||||
|
`pip` `overlay` `creator`
|
||||||
|
|
||||||
|
<video className="w-full aspect-video rounded-xl object-cover bg-zinc-100 dark:bg-zinc-800" src="https://static.heygen.ai/hyperframes-oss/docs/images/catalog/components/yt-avatar-pip.mp4" poster="https://static.heygen.ai/hyperframes-oss/docs/images/catalog/components/yt-avatar-pip.png" autoPlay muted loop playsInline />
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
<CodeGroup>
|
||||||
|
|
||||||
|
```bash Terminal
|
||||||
|
npx hyperframes add yt-avatar-pip
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeGroup>
|
||||||
|
|
||||||
|
## Details
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
| --- | --- |
|
||||||
|
| Type | Component |
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
| File | Target | Type |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `yt-avatar-pip.html` | `compositions/components/yt-avatar-pip.html` | hyperframes:snippet |
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Read the installed file and copy its CSS, markup pattern, and helper functions into your host composition — the parent timeline owns all timing. The file's header comment documents the wiring calls.
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://hyperframes.heygen.com/schema/registry-item.json",
|
||||||
|
"name": "yt-avatar-pip",
|
||||||
|
"type": "hyperframes:component",
|
||||||
|
"title": "Circle PiP Window",
|
||||||
|
"description": "Circular or rounded-rect masked picture-in-picture window with ring and shadow for a second video or image; pop in/out helpers",
|
||||||
|
"tags": [
|
||||||
|
"pip",
|
||||||
|
"overlay",
|
||||||
|
"creator"
|
||||||
|
],
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"path": "yt-avatar-pip.html",
|
||||||
|
"target": "compositions/components/yt-avatar-pip.html",
|
||||||
|
"type": "hyperframes:snippet"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||||
|
<style>
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: transparent;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
/* ---- yt-avatar-pip ---------------------------------------------------
|
||||||
|
The screen-recording PiP: a circular (or rounded-rect) masked window
|
||||||
|
for a second video/image — one drop replaces the manual
|
||||||
|
crop-mask-resize dance. Size via --yt-pip-size, framing via an
|
||||||
|
inline transform scale on the inner media (an "inside scale"). */
|
||||||
|
.yt-pip {
|
||||||
|
--yt-pip-size: 300px;
|
||||||
|
--yt-pip-ring: rgba(255, 255, 255, 0.92);
|
||||||
|
--yt-pip-ring-w: 4px;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
width: var(--yt-pip-size);
|
||||||
|
height: var(--yt-pip-size);
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
border: var(--yt-pip-ring-w) solid var(--yt-pip-ring);
|
||||||
|
box-shadow: 0 18px 50px rgba(0, 0, 0, 0.4);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.yt-pip--rect {
|
||||||
|
border-radius: 22px;
|
||||||
|
width: calc(var(--yt-pip-size) * 1.55);
|
||||||
|
}
|
||||||
|
.yt-pip > img,
|
||||||
|
.yt-pip > video,
|
||||||
|
.yt-pip > .yt-pip-fill {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
/* self-preview stand-in (not part of the snippet) */
|
||||||
|
.yt-pip-fill {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-family: "Inter", ui-sans-serif, sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 92px;
|
||||||
|
color: rgba(255, 255, 255, 0.95);
|
||||||
|
background: linear-gradient(135deg, #ff8fb8 0%, #7d5cff 100%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Self-preview wrapper. WIRING: copy the .yt-pip CSS and the markup
|
||||||
|
pattern below into your host; put a <video data-start ...> or <img>
|
||||||
|
inside. The media element must live in the HOST root (this pattern
|
||||||
|
is copied in) — never inside a mounted sub-composition: sub-comps
|
||||||
|
are never seeked, so framework-owned media there renders black. Position via top/right/bottom/left; add class="clip" +
|
||||||
|
data-start/duration/track-index for host windowing. Framing: style
|
||||||
|
the inner media with transform: scale(1.15) etc. Then:
|
||||||
|
|
||||||
|
ytPipIn(tl, "#yt-my-pip", 2.0);
|
||||||
|
ytPipOut(tl, "#yt-my-pip", 12.0);
|
||||||
|
-->
|
||||||
|
<div
|
||||||
|
id="yt-pip-root"
|
||||||
|
data-composition-id="yt-avatar-pip"
|
||||||
|
data-start="0"
|
||||||
|
data-duration="4"
|
||||||
|
data-width="1920"
|
||||||
|
data-height="1080"
|
||||||
|
>
|
||||||
|
<div class="yt-pip" id="yt-pip-demo" style="left: 120px; bottom: 100px">
|
||||||
|
<div class="yt-pip-fill">AB</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="yt-pip-drv"
|
||||||
|
class="clip"
|
||||||
|
data-start="0"
|
||||||
|
data-duration="4"
|
||||||
|
data-track-index="0"
|
||||||
|
style="position:absolute;width:1px;height:1px;opacity:0;pointer-events:none"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
window.__timelines = window.__timelines || {};
|
||||||
|
|
||||||
|
// ---- copy these helpers into the host script ----
|
||||||
|
window.ytPipIn = function (tl, target, at) {
|
||||||
|
gsap.set(target, { opacity: 0, scale: 0.55, y: 26 });
|
||||||
|
tl.to(target, { opacity: 1, scale: 1, y: 0, duration: 0.55, ease: "back.out(1.5)" }, at);
|
||||||
|
};
|
||||||
|
window.ytPipOut = function (tl, target, at) {
|
||||||
|
tl.to(target, { opacity: 0, scale: 0.75, y: 18, duration: 0.35, ease: "power2.in" }, at);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Self-preview timeline (not part of the snippet you copy).
|
||||||
|
var tl = gsap.timeline({ paused: true });
|
||||||
|
window.ytPipIn(tl, "#yt-pip-demo", 0.4);
|
||||||
|
window.ytPipOut(tl, "#yt-pip-demo", 3.4);
|
||||||
|
tl.set("#yt-pip-root", { visibility: "hidden" }, 3.98);
|
||||||
|
window.__timelines["yt-avatar-pip"] = tl;
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -582,6 +582,10 @@
|
|||||||
{
|
{
|
||||||
"name": "yt-camera-move",
|
"name": "yt-camera-move",
|
||||||
"type": "hyperframes:component"
|
"type": "hyperframes:component"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "yt-avatar-pip",
|
||||||
|
"type": "hyperframes:component"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user