mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-15 13:58:20 +00:00
style: format caption component files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
78ddd2602b
commit
a19a772dc5
+171
-110
@@ -6,42 +6,75 @@
|
||||
<title>Clip Wipe</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@800&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Poppins:wght@800&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#clip-wipe {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#wp-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.wp-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.45); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#wp-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.wp-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 100px;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 100px;
|
||||
visibility: hidden;
|
||||
}
|
||||
.wp-word {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-weight: 800; font-size: 88px;
|
||||
font-family: "Poppins", sans-serif;
|
||||
font-weight: 800;
|
||||
font-size: 88px;
|
||||
text-transform: uppercase;
|
||||
color: #ffffff;
|
||||
display: inline-block; letter-spacing: 0.04em; line-height: 1;
|
||||
display: inline-block;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
clip-path: inset(0 100% 0 0);
|
||||
will-change: clip-path, color, opacity;
|
||||
}
|
||||
@@ -57,114 +90,142 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="wp-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="wp-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="wp-overlay"></div>
|
||||
<div id="wp-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
function mulberry32(seed) {
|
||||
return function() {
|
||||
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
|
||||
var t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
||||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
function mulberry32(seed) {
|
||||
return function () {
|
||||
seed |= 0;
|
||||
seed = (seed + 0x6d2b79f5) | 0;
|
||||
var t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
|
||||
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var RAW_GROUPS = [
|
||||
[0,3],[4,7],[8,8],[9,12],[13,15],[16,16],[17,19],[20,22],[23,24],[25,27]
|
||||
];
|
||||
var GROUPS = RAW_GROUPS.map(function(pair, gi) {
|
||||
var ws = pair[0], we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi+1][0]].start : 8.0;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.35, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
var container = document.getElementById('wp-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'wp-group';
|
||||
grp.id = 'wp-grp-' + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement('span');
|
||||
span.className = 'wp-word';
|
||||
span.id = 'wp-w-' + wi;
|
||||
span.textContent = w.text.toUpperCase();
|
||||
span.style.fontSize = '88px';
|
||||
grp.appendChild(span);
|
||||
var RAW_GROUPS = [
|
||||
[0, 3],
|
||||
[4, 7],
|
||||
[8, 8],
|
||||
[9, 12],
|
||||
[13, 15],
|
||||
[16, 16],
|
||||
[17, 19],
|
||||
[20, 22],
|
||||
[23, 24],
|
||||
[25, 27],
|
||||
];
|
||||
var GROUPS = RAW_GROUPS.map(function (pair, gi) {
|
||||
var ws = pair[0],
|
||||
we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : 8.0;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.35, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
var container = document.getElementById("wp-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
tl.set(grp, { visibility: 'visible' }, g.start);
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "wp-group";
|
||||
grp.id = "wp-grp-" + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordEl = document.getElementById('wp-w-' + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement("span");
|
||||
span.className = "wp-word";
|
||||
span.id = "wp-w-" + wi;
|
||||
span.textContent = w.text.toUpperCase();
|
||||
span.style.fontSize = "88px";
|
||||
grp.appendChild(span);
|
||||
});
|
||||
|
||||
tl.to(wordEl, { clipPath: 'inset(0 0% 0 0)', duration: 0.15, ease: 'power3.out' }, w.start);
|
||||
if (isKW) {
|
||||
tl.to(wordEl, { color: '#FFD700', duration: 0.05 }, w.start + 0.1);
|
||||
}
|
||||
tl.to(wordEl, { color: 'rgba(255,255,255,0.4)', duration: 0.12 }, w.end);
|
||||
container.appendChild(grp);
|
||||
|
||||
tl.set(grp, { visibility: "visible" }, g.start);
|
||||
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordEl = document.getElementById("wp-w-" + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ clipPath: "inset(0 0% 0 0)", duration: 0.15, ease: "power3.out" },
|
||||
w.start,
|
||||
);
|
||||
if (isKW) {
|
||||
tl.to(wordEl, { color: "#FFD700", duration: 0.05 }, w.start + 0.1);
|
||||
}
|
||||
tl.to(wordEl, { color: "rgba(255,255,255,0.4)", duration: 0.12 }, w.end);
|
||||
});
|
||||
|
||||
var wordEls = grp.querySelectorAll(".wp-word");
|
||||
tl.to(
|
||||
wordEls,
|
||||
{
|
||||
clipPath: "inset(0 0% 0 100%)",
|
||||
duration: 0.14,
|
||||
stagger: 0.04,
|
||||
ease: "power2.in",
|
||||
},
|
||||
g.end - 0.2,
|
||||
);
|
||||
tl.set(grp, { visibility: "hidden", opacity: 0 }, g.end);
|
||||
});
|
||||
|
||||
var wordEls = grp.querySelectorAll('.wp-word');
|
||||
tl.to(wordEls, {
|
||||
clipPath: 'inset(0 0% 0 100%)',
|
||||
duration: 0.14, stagger: 0.04, ease: 'power2.in'
|
||||
}, g.end - 0.2);
|
||||
tl.set(grp, { visibility: 'hidden', opacity: 0 }, g.end);
|
||||
});
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines['clip-wipe'] = tl;
|
||||
})();
|
||||
tl.seek(0);
|
||||
window.__timelines["clip-wipe"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+171
-110
@@ -6,42 +6,75 @@
|
||||
<title>Clip Wipe</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@800&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Poppins:wght@800&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#clip-wipe {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#wp-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.wp-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.45); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#wp-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.wp-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 100px;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 100px;
|
||||
visibility: hidden;
|
||||
}
|
||||
.wp-word {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-weight: 800; font-size: 88px;
|
||||
font-family: "Poppins", sans-serif;
|
||||
font-weight: 800;
|
||||
font-size: 88px;
|
||||
text-transform: uppercase;
|
||||
color: #ffffff;
|
||||
display: inline-block; letter-spacing: 0.04em; line-height: 1;
|
||||
display: inline-block;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
clip-path: inset(0 100% 0 0);
|
||||
will-change: clip-path, color, opacity;
|
||||
}
|
||||
@@ -57,114 +90,142 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="wp-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="wp-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="wp-overlay"></div>
|
||||
<div id="wp-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
function mulberry32(seed) {
|
||||
return function() {
|
||||
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
|
||||
var t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
||||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
function mulberry32(seed) {
|
||||
return function () {
|
||||
seed |= 0;
|
||||
seed = (seed + 0x6d2b79f5) | 0;
|
||||
var t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
|
||||
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var RAW_GROUPS = [
|
||||
[0,3],[4,7],[8,8],[9,12],[13,15],[16,16],[17,19],[20,22],[23,24],[25,27]
|
||||
];
|
||||
var GROUPS = RAW_GROUPS.map(function(pair, gi) {
|
||||
var ws = pair[0], we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi+1][0]].start : 8.0;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.35, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
var container = document.getElementById('wp-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'wp-group';
|
||||
grp.id = 'wp-grp-' + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement('span');
|
||||
span.className = 'wp-word';
|
||||
span.id = 'wp-w-' + wi;
|
||||
span.textContent = w.text.toUpperCase();
|
||||
span.style.fontSize = '88px';
|
||||
grp.appendChild(span);
|
||||
var RAW_GROUPS = [
|
||||
[0, 3],
|
||||
[4, 7],
|
||||
[8, 8],
|
||||
[9, 12],
|
||||
[13, 15],
|
||||
[16, 16],
|
||||
[17, 19],
|
||||
[20, 22],
|
||||
[23, 24],
|
||||
[25, 27],
|
||||
];
|
||||
var GROUPS = RAW_GROUPS.map(function (pair, gi) {
|
||||
var ws = pair[0],
|
||||
we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : 8.0;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.35, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
var container = document.getElementById("wp-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
tl.set(grp, { visibility: 'visible' }, g.start);
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "wp-group";
|
||||
grp.id = "wp-grp-" + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordEl = document.getElementById('wp-w-' + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement("span");
|
||||
span.className = "wp-word";
|
||||
span.id = "wp-w-" + wi;
|
||||
span.textContent = w.text.toUpperCase();
|
||||
span.style.fontSize = "88px";
|
||||
grp.appendChild(span);
|
||||
});
|
||||
|
||||
tl.to(wordEl, { clipPath: 'inset(0 0% 0 0)', duration: 0.15, ease: 'power3.out' }, w.start);
|
||||
if (isKW) {
|
||||
tl.to(wordEl, { color: '#FFD700', duration: 0.05 }, w.start + 0.1);
|
||||
}
|
||||
tl.to(wordEl, { color: 'rgba(255,255,255,0.4)', duration: 0.12 }, w.end);
|
||||
container.appendChild(grp);
|
||||
|
||||
tl.set(grp, { visibility: "visible" }, g.start);
|
||||
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordEl = document.getElementById("wp-w-" + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ clipPath: "inset(0 0% 0 0)", duration: 0.15, ease: "power3.out" },
|
||||
w.start,
|
||||
);
|
||||
if (isKW) {
|
||||
tl.to(wordEl, { color: "#FFD700", duration: 0.05 }, w.start + 0.1);
|
||||
}
|
||||
tl.to(wordEl, { color: "rgba(255,255,255,0.4)", duration: 0.12 }, w.end);
|
||||
});
|
||||
|
||||
var wordEls = grp.querySelectorAll(".wp-word");
|
||||
tl.to(
|
||||
wordEls,
|
||||
{
|
||||
clipPath: "inset(0 0% 0 100%)",
|
||||
duration: 0.14,
|
||||
stagger: 0.04,
|
||||
ease: "power2.in",
|
||||
},
|
||||
g.end - 0.2,
|
||||
);
|
||||
tl.set(grp, { visibility: "hidden", opacity: 0 }, g.end);
|
||||
});
|
||||
|
||||
var wordEls = grp.querySelectorAll('.wp-word');
|
||||
tl.to(wordEls, {
|
||||
clipPath: 'inset(0 0% 0 100%)',
|
||||
duration: 0.14, stagger: 0.04, ease: 'power2.in'
|
||||
}, g.end - 0.2);
|
||||
tl.set(grp, { visibility: 'hidden', opacity: 0 }, g.end);
|
||||
});
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines['clip-wipe'] = tl;
|
||||
})();
|
||||
tl.seek(0);
|
||||
window.__timelines["clip-wipe"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+131
-49
@@ -6,7 +6,10 @@
|
||||
<title>Editorial Emphasis</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400&family=Playfair+Display:ital,wght@0,800;1,800&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400&family=Playfair+Display:ital,wght@0,800;1,800&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*,
|
||||
@@ -85,8 +88,10 @@
|
||||
|
||||
.word {
|
||||
display: inline-block;
|
||||
color: #F5F0D0;
|
||||
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6), 0 4px 24px rgba(0, 0, 0, 0.35);
|
||||
color: #f5f0d0;
|
||||
text-shadow:
|
||||
0 2px 12px rgba(0, 0, 0, 0.6),
|
||||
0 4px 24px rgba(0, 0, 0, 0.35);
|
||||
will-change: transform, opacity;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
@@ -111,7 +116,7 @@
|
||||
font-weight: 800;
|
||||
font-style: italic;
|
||||
line-height: 0.9;
|
||||
color: #F5F0D0;
|
||||
color: #f5f0d0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -149,49 +154,108 @@
|
||||
|
||||
// Generic transcript words
|
||||
var W = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
// Block layout: [wordIndex, type] — n=normal, i=italic, e=emphasis(large)
|
||||
// Emphasis words: HyperFrames(8), HTML(12), professional(15), code(24), cinema.(27)
|
||||
var BLOCKS = [
|
||||
{ line1: [[0,"n"],[1,"n"],[2,"n"]], line2: [[3,"n"],[4,"n"]] },
|
||||
{ line1: [[5,"n"],[6,"n"]], line2: [[7,"e"]] },
|
||||
{ line1: [[8,"e"]], line2: null },
|
||||
{ line1: [[9,"n"],[10,"n"],[11,"n"]], line2: [[12,"e"]] },
|
||||
{ line1: [[13,"n"],[14,"n"]], line2: [[15,"e"]] },
|
||||
{ line1: [[16,"n"],[17,"n"]], line2: null },
|
||||
{ line1: [[18,"n"]], line2: [[19,"n"],[20,"n"]] },
|
||||
{ line1: [[21,"n"],[22,"n"]], line2: null },
|
||||
{ line1: [[23,"i"],[24,"e"]], line2: null },
|
||||
{ line1: [[25,"n"],[26,"n"]], line2: [[27,"e"]] },
|
||||
{
|
||||
line1: [
|
||||
[0, "n"],
|
||||
[1, "n"],
|
||||
[2, "n"],
|
||||
],
|
||||
line2: [
|
||||
[3, "n"],
|
||||
[4, "n"],
|
||||
],
|
||||
},
|
||||
{
|
||||
line1: [
|
||||
[5, "n"],
|
||||
[6, "n"],
|
||||
],
|
||||
line2: [[7, "e"]],
|
||||
},
|
||||
{ line1: [[8, "e"]], line2: null },
|
||||
{
|
||||
line1: [
|
||||
[9, "n"],
|
||||
[10, "n"],
|
||||
[11, "n"],
|
||||
],
|
||||
line2: [[12, "e"]],
|
||||
},
|
||||
{
|
||||
line1: [
|
||||
[13, "n"],
|
||||
[14, "n"],
|
||||
],
|
||||
line2: [[15, "e"]],
|
||||
},
|
||||
{
|
||||
line1: [
|
||||
[16, "n"],
|
||||
[17, "n"],
|
||||
],
|
||||
line2: null,
|
||||
},
|
||||
{
|
||||
line1: [[18, "n"]],
|
||||
line2: [
|
||||
[19, "n"],
|
||||
[20, "n"],
|
||||
],
|
||||
},
|
||||
{
|
||||
line1: [
|
||||
[21, "n"],
|
||||
[22, "n"],
|
||||
],
|
||||
line2: null,
|
||||
},
|
||||
{
|
||||
line1: [
|
||||
[23, "i"],
|
||||
[24, "e"],
|
||||
],
|
||||
line2: null,
|
||||
},
|
||||
{
|
||||
line1: [
|
||||
[25, "n"],
|
||||
[26, "n"],
|
||||
],
|
||||
line2: [[27, "e"]],
|
||||
},
|
||||
];
|
||||
|
||||
var CLASS_MAP = { n: "word word--normal", i: "word word--italic", e: "word word--emphasis" };
|
||||
@@ -243,7 +307,9 @@
|
||||
el.style.position = "relative";
|
||||
var lines = el.querySelectorAll(".caption-line");
|
||||
var maxW = 0;
|
||||
lines.forEach(function (line) { if (line.scrollWidth > maxW) maxW = line.scrollWidth; });
|
||||
lines.forEach(function (line) {
|
||||
if (line.scrollWidth > maxW) maxW = line.scrollWidth;
|
||||
});
|
||||
if (maxW > SAFE_WIDTH) {
|
||||
var s = SAFE_WIDTH / maxW;
|
||||
el.style.transform = "scale(" + s + ")";
|
||||
@@ -256,27 +322,39 @@
|
||||
window.__timelines = window.__timelines || {};
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
var allEls = BLOCKS.map(function (_, i) { return document.getElementById("b" + i); });
|
||||
var allEls = BLOCKS.map(function (_, i) {
|
||||
return document.getElementById("b" + i);
|
||||
});
|
||||
|
||||
function blockStart(bi) { return W[BLOCKS[bi].line1[0][0]].start; }
|
||||
function blockStart(bi) {
|
||||
return W[BLOCKS[bi].line1[0][0]].start;
|
||||
}
|
||||
|
||||
BLOCKS.forEach(function (block, bi) {
|
||||
var el = allEls[bi];
|
||||
var start = blockStart(bi);
|
||||
var nextStart = bi < BLOCKS.length - 1 ? blockStart(bi + 1) : DURATION;
|
||||
|
||||
allEls.forEach(function (other, oi) { if (oi !== bi) tl.set(other, { opacity: 0 }, start); });
|
||||
allEls.forEach(function (other, oi) {
|
||||
if (oi !== bi) tl.set(other, { opacity: 0 }, start);
|
||||
});
|
||||
tl.set(el, { opacity: 1 }, start);
|
||||
|
||||
block.line1.forEach(function (pair, wi) {
|
||||
var wordEl = document.getElementById("b" + bi + "L1w" + wi);
|
||||
var wordStart = W[pair[0]].start;
|
||||
tl.set(wordEl, { opacity: 0, scale: 1.12, transformOrigin: "0% 100%" }, start);
|
||||
tl.to(wordEl, { opacity: 1, scale: 1, duration: ENTRY_DUR, ease: "power2.out" }, wordStart);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ opacity: 1, scale: 1, duration: ENTRY_DUR, ease: "power2.out" },
|
||||
wordStart,
|
||||
);
|
||||
});
|
||||
|
||||
if (block.line2) {
|
||||
var hasEmphasis = block.line2.some(function (p) { return p[1] === "e"; });
|
||||
var hasEmphasis = block.line2.some(function (p) {
|
||||
return p[1] === "e";
|
||||
});
|
||||
var l2El = document.getElementById("b" + bi + "L2");
|
||||
if (hasEmphasis) {
|
||||
var l2Start = W[block.line2[0][0]].start;
|
||||
@@ -288,7 +366,11 @@
|
||||
var wordEl = document.getElementById("b" + bi + "L2w" + wi);
|
||||
var wordStart = W[pair[0]].start;
|
||||
tl.set(wordEl, { opacity: 0, scale: 1.12, transformOrigin: "0% 100%" }, start);
|
||||
tl.to(wordEl, { opacity: 1, scale: 1, duration: ENTRY_DUR, ease: "power2.out" }, wordStart);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ opacity: 1, scale: 1, duration: ENTRY_DUR, ease: "power2.out" },
|
||||
wordStart,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+131
-49
@@ -6,7 +6,10 @@
|
||||
<title>Editorial Emphasis</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400&family=Playfair+Display:ital,wght@0,800;1,800&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400&family=Playfair+Display:ital,wght@0,800;1,800&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*,
|
||||
@@ -85,8 +88,10 @@
|
||||
|
||||
.word {
|
||||
display: inline-block;
|
||||
color: #F5F0D0;
|
||||
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6), 0 4px 24px rgba(0, 0, 0, 0.35);
|
||||
color: #f5f0d0;
|
||||
text-shadow:
|
||||
0 2px 12px rgba(0, 0, 0, 0.6),
|
||||
0 4px 24px rgba(0, 0, 0, 0.35);
|
||||
will-change: transform, opacity;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
@@ -111,7 +116,7 @@
|
||||
font-weight: 800;
|
||||
font-style: italic;
|
||||
line-height: 0.9;
|
||||
color: #F5F0D0;
|
||||
color: #f5f0d0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -149,49 +154,108 @@
|
||||
|
||||
// Generic transcript words
|
||||
var W = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
// Block layout: [wordIndex, type] — n=normal, i=italic, e=emphasis(large)
|
||||
// Emphasis words: HyperFrames(8), HTML(12), professional(15), code(24), cinema.(27)
|
||||
var BLOCKS = [
|
||||
{ line1: [[0,"n"],[1,"n"],[2,"n"]], line2: [[3,"n"],[4,"n"]] },
|
||||
{ line1: [[5,"n"],[6,"n"]], line2: [[7,"e"]] },
|
||||
{ line1: [[8,"e"]], line2: null },
|
||||
{ line1: [[9,"n"],[10,"n"],[11,"n"]], line2: [[12,"e"]] },
|
||||
{ line1: [[13,"n"],[14,"n"]], line2: [[15,"e"]] },
|
||||
{ line1: [[16,"n"],[17,"n"]], line2: null },
|
||||
{ line1: [[18,"n"]], line2: [[19,"n"],[20,"n"]] },
|
||||
{ line1: [[21,"n"],[22,"n"]], line2: null },
|
||||
{ line1: [[23,"i"],[24,"e"]], line2: null },
|
||||
{ line1: [[25,"n"],[26,"n"]], line2: [[27,"e"]] },
|
||||
{
|
||||
line1: [
|
||||
[0, "n"],
|
||||
[1, "n"],
|
||||
[2, "n"],
|
||||
],
|
||||
line2: [
|
||||
[3, "n"],
|
||||
[4, "n"],
|
||||
],
|
||||
},
|
||||
{
|
||||
line1: [
|
||||
[5, "n"],
|
||||
[6, "n"],
|
||||
],
|
||||
line2: [[7, "e"]],
|
||||
},
|
||||
{ line1: [[8, "e"]], line2: null },
|
||||
{
|
||||
line1: [
|
||||
[9, "n"],
|
||||
[10, "n"],
|
||||
[11, "n"],
|
||||
],
|
||||
line2: [[12, "e"]],
|
||||
},
|
||||
{
|
||||
line1: [
|
||||
[13, "n"],
|
||||
[14, "n"],
|
||||
],
|
||||
line2: [[15, "e"]],
|
||||
},
|
||||
{
|
||||
line1: [
|
||||
[16, "n"],
|
||||
[17, "n"],
|
||||
],
|
||||
line2: null,
|
||||
},
|
||||
{
|
||||
line1: [[18, "n"]],
|
||||
line2: [
|
||||
[19, "n"],
|
||||
[20, "n"],
|
||||
],
|
||||
},
|
||||
{
|
||||
line1: [
|
||||
[21, "n"],
|
||||
[22, "n"],
|
||||
],
|
||||
line2: null,
|
||||
},
|
||||
{
|
||||
line1: [
|
||||
[23, "i"],
|
||||
[24, "e"],
|
||||
],
|
||||
line2: null,
|
||||
},
|
||||
{
|
||||
line1: [
|
||||
[25, "n"],
|
||||
[26, "n"],
|
||||
],
|
||||
line2: [[27, "e"]],
|
||||
},
|
||||
];
|
||||
|
||||
var CLASS_MAP = { n: "word word--normal", i: "word word--italic", e: "word word--emphasis" };
|
||||
@@ -243,7 +307,9 @@
|
||||
el.style.position = "relative";
|
||||
var lines = el.querySelectorAll(".caption-line");
|
||||
var maxW = 0;
|
||||
lines.forEach(function (line) { if (line.scrollWidth > maxW) maxW = line.scrollWidth; });
|
||||
lines.forEach(function (line) {
|
||||
if (line.scrollWidth > maxW) maxW = line.scrollWidth;
|
||||
});
|
||||
if (maxW > SAFE_WIDTH) {
|
||||
var s = SAFE_WIDTH / maxW;
|
||||
el.style.transform = "scale(" + s + ")";
|
||||
@@ -256,27 +322,39 @@
|
||||
window.__timelines = window.__timelines || {};
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
var allEls = BLOCKS.map(function (_, i) { return document.getElementById("b" + i); });
|
||||
var allEls = BLOCKS.map(function (_, i) {
|
||||
return document.getElementById("b" + i);
|
||||
});
|
||||
|
||||
function blockStart(bi) { return W[BLOCKS[bi].line1[0][0]].start; }
|
||||
function blockStart(bi) {
|
||||
return W[BLOCKS[bi].line1[0][0]].start;
|
||||
}
|
||||
|
||||
BLOCKS.forEach(function (block, bi) {
|
||||
var el = allEls[bi];
|
||||
var start = blockStart(bi);
|
||||
var nextStart = bi < BLOCKS.length - 1 ? blockStart(bi + 1) : DURATION;
|
||||
|
||||
allEls.forEach(function (other, oi) { if (oi !== bi) tl.set(other, { opacity: 0 }, start); });
|
||||
allEls.forEach(function (other, oi) {
|
||||
if (oi !== bi) tl.set(other, { opacity: 0 }, start);
|
||||
});
|
||||
tl.set(el, { opacity: 1 }, start);
|
||||
|
||||
block.line1.forEach(function (pair, wi) {
|
||||
var wordEl = document.getElementById("b" + bi + "L1w" + wi);
|
||||
var wordStart = W[pair[0]].start;
|
||||
tl.set(wordEl, { opacity: 0, scale: 1.12, transformOrigin: "0% 100%" }, start);
|
||||
tl.to(wordEl, { opacity: 1, scale: 1, duration: ENTRY_DUR, ease: "power2.out" }, wordStart);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ opacity: 1, scale: 1, duration: ENTRY_DUR, ease: "power2.out" },
|
||||
wordStart,
|
||||
);
|
||||
});
|
||||
|
||||
if (block.line2) {
|
||||
var hasEmphasis = block.line2.some(function (p) { return p[1] === "e"; });
|
||||
var hasEmphasis = block.line2.some(function (p) {
|
||||
return p[1] === "e";
|
||||
});
|
||||
var l2El = document.getElementById("b" + bi + "L2");
|
||||
if (hasEmphasis) {
|
||||
var l2Start = W[block.line2[0][0]].start;
|
||||
@@ -288,7 +366,11 @@
|
||||
var wordEl = document.getElementById("b" + bi + "L2w" + wi);
|
||||
var wordStart = W[pair[0]].start;
|
||||
tl.set(wordEl, { opacity: 0, scale: 1.12, transformOrigin: "0% 100%" }, start);
|
||||
tl.to(wordEl, { opacity: 1, scale: 1, duration: ENTRY_DUR, ease: "power2.out" }, wordStart);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ opacity: 1, scale: 1, duration: ENTRY_DUR, ease: "power2.out" },
|
||||
wordStart,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+150
-59
@@ -6,7 +6,10 @@
|
||||
<title>Emoji Pop</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Gabarito:wght@900&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Gabarito:wght@900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*,
|
||||
@@ -155,67 +158,117 @@
|
||||
var ACCENT_COLORS = ["#FF76FF", "#FF0002", "#B2F7FF"];
|
||||
var KEYWORDS = new Set(["hyperframes", "html", "professional", "code", "cinema"]);
|
||||
var TRANSITION_WORDS = new Set([
|
||||
"the", "a", "an", "and", "or", "but", "is", "are", "was", "were",
|
||||
"to", "of", "in", "on", "at", "for", "with", "by", "from", "as",
|
||||
"it", "its", "this", "that", "these", "those", "be", "been",
|
||||
"have", "has", "had", "do", "does", "did", "will", "would", "could",
|
||||
"should", "may", "might", "must", "can", "if", "then", "so", "just",
|
||||
"not", "no", "yes", "up", "out", "about"
|
||||
"the",
|
||||
"a",
|
||||
"an",
|
||||
"and",
|
||||
"or",
|
||||
"but",
|
||||
"is",
|
||||
"are",
|
||||
"was",
|
||||
"were",
|
||||
"to",
|
||||
"of",
|
||||
"in",
|
||||
"on",
|
||||
"at",
|
||||
"for",
|
||||
"with",
|
||||
"by",
|
||||
"from",
|
||||
"as",
|
||||
"it",
|
||||
"its",
|
||||
"this",
|
||||
"that",
|
||||
"these",
|
||||
"those",
|
||||
"be",
|
||||
"been",
|
||||
"have",
|
||||
"has",
|
||||
"had",
|
||||
"do",
|
||||
"does",
|
||||
"did",
|
||||
"will",
|
||||
"would",
|
||||
"could",
|
||||
"should",
|
||||
"may",
|
||||
"might",
|
||||
"must",
|
||||
"can",
|
||||
"if",
|
||||
"then",
|
||||
"so",
|
||||
"just",
|
||||
"not",
|
||||
"no",
|
||||
"yes",
|
||||
"up",
|
||||
"out",
|
||||
"about",
|
||||
]);
|
||||
|
||||
// Emoji map for key words
|
||||
var WORD_EMOJI = {
|
||||
"hyperframes": "🎬",
|
||||
"html": "💻",
|
||||
"professional": "✨",
|
||||
"code": "⌨️",
|
||||
"cinema": "🎥",
|
||||
"video": "📹",
|
||||
"frame": "🖼️"
|
||||
hyperframes: "🎬",
|
||||
html: "💻",
|
||||
professional: "✨",
|
||||
code: "⌨️",
|
||||
cinema: "🎥",
|
||||
video: "📹",
|
||||
frame: "🖼️",
|
||||
};
|
||||
|
||||
var TRANSCRIPT = [
|
||||
{"text": "Every", "start": 0.0, "end": 0.3},
|
||||
{"text": "great", "start": 0.3, "end": 0.55},
|
||||
{"text": "video", "start": 0.55, "end": 0.85},
|
||||
{"text": "starts", "start": 0.85, "end": 1.1},
|
||||
{"text": "with", "start": 1.1, "end": 1.25},
|
||||
{"text": "a", "start": 1.25, "end": 1.35},
|
||||
{"text": "single", "start": 1.35, "end": 1.65},
|
||||
{"text": "frame.", "start": 1.65, "end": 2.0},
|
||||
{"text": "HyperFrames", "start": 2.1, "end": 2.65},
|
||||
{"text": "lets", "start": 2.65, "end": 2.85},
|
||||
{"text": "you", "start": 2.85, "end": 2.95},
|
||||
{"text": "write", "start": 2.95, "end": 3.15},
|
||||
{"text": "HTML", "start": 3.15, "end": 3.55},
|
||||
{"text": "and", "start": 3.55, "end": 3.65},
|
||||
{"text": "render", "start": 3.65, "end": 3.95},
|
||||
{"text": "professional", "start": 3.95, "end": 4.45},
|
||||
{"text": "video.", "start": 4.45, "end": 4.8},
|
||||
{"text": "No", "start": 4.9, "end": 5.05},
|
||||
{"text": "timeline.", "start": 5.05, "end": 5.45},
|
||||
{"text": "No", "start": 5.5, "end": 5.65},
|
||||
{"text": "drag", "start": 5.65, "end": 5.85},
|
||||
{"text": "and", "start": 5.85, "end": 5.95},
|
||||
{"text": "drop.", "start": 5.95, "end": 6.25},
|
||||
{"text": "Just", "start": 6.35, "end": 6.55},
|
||||
{"text": "code", "start": 6.55, "end": 6.8},
|
||||
{"text": "that", "start": 6.8, "end": 6.95},
|
||||
{"text": "becomes", "start": 6.95, "end": 7.3},
|
||||
{"text": "cinema.", "start": 7.3, "end": 7.7}
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
function normalizeWords(rawWords) {
|
||||
return rawWords.map(function (item) {
|
||||
var text = String(item.word || item.text || "").trim();
|
||||
var clean = text.toLowerCase().replace(/[^a-z]/g, "");
|
||||
return {
|
||||
text: text,
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
emoji: WORD_EMOJI[clean] || null,
|
||||
};
|
||||
}).filter(function (word) { return word.text.length > 0; });
|
||||
return rawWords
|
||||
.map(function (item) {
|
||||
var text = String(item.word || item.text || "").trim();
|
||||
var clean = text.toLowerCase().replace(/[^a-z]/g, "");
|
||||
return {
|
||||
text: text,
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
emoji: WORD_EMOJI[clean] || null,
|
||||
};
|
||||
})
|
||||
.filter(function (word) {
|
||||
return word.text.length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
function seededRandom(seed) {
|
||||
@@ -272,7 +325,12 @@
|
||||
current.push(word);
|
||||
var punctuation = /[,.:!?]$/.test(word.text);
|
||||
var pause = nextWord ? nextWord.start - word.end : 0;
|
||||
if (!nextWord || punctuation || pause >= PAUSE_THRESHOLD || current.length >= MAX_WORDS_PER_GROUP) {
|
||||
if (
|
||||
!nextWord ||
|
||||
punctuation ||
|
||||
pause >= PAUSE_THRESHOLD ||
|
||||
current.length >= MAX_WORDS_PER_GROUP
|
||||
) {
|
||||
groups.push(makeGroup(current, groups.length));
|
||||
current = [];
|
||||
}
|
||||
@@ -285,9 +343,18 @@
|
||||
var colors = assignWordColors(words, groupIndex);
|
||||
var emoji = null;
|
||||
for (var i = 0; i < words.length; i++) {
|
||||
if (words[i].emoji) { emoji = words[i].emoji; break; }
|
||||
if (words[i].emoji) {
|
||||
emoji = words[i].emoji;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return { words: words.slice(), colors: colors, emoji: emoji, start: words[0].start, end: words[words.length - 1].end };
|
||||
return {
|
||||
words: words.slice(),
|
||||
colors: colors,
|
||||
emoji: emoji,
|
||||
start: words[0].start,
|
||||
end: words[words.length - 1].end,
|
||||
};
|
||||
}
|
||||
|
||||
function shadowForColor(color) {
|
||||
@@ -295,7 +362,21 @@
|
||||
var r = parseInt(hex.slice(0, 2), 16);
|
||||
var g = parseInt(hex.slice(2, 4), 16);
|
||||
var b = parseInt(hex.slice(4, 6), 16);
|
||||
return "0 4px 8px rgba(0,0,0,0.7), 0 0 2px rgba(" + r + "," + g + "," + b + ",1), 0 0 8px rgba(" + r + "," + g + "," + b + ",0.6)";
|
||||
return (
|
||||
"0 4px 8px rgba(0,0,0,0.7), 0 0 2px rgba(" +
|
||||
r +
|
||||
"," +
|
||||
g +
|
||||
"," +
|
||||
b +
|
||||
",1), 0 0 8px rgba(" +
|
||||
r +
|
||||
"," +
|
||||
g +
|
||||
"," +
|
||||
b +
|
||||
",0.6)"
|
||||
);
|
||||
}
|
||||
|
||||
function buildCaptions(groups) {
|
||||
@@ -343,7 +424,9 @@
|
||||
return Math.max(0, group.start - entryLead);
|
||||
});
|
||||
|
||||
var allGroupEls = GROUPS.map(function (_, i) { return document.getElementById("caption-group-" + i); });
|
||||
var allGroupEls = GROUPS.map(function (_, i) {
|
||||
return document.getElementById("caption-group-" + i);
|
||||
});
|
||||
|
||||
GROUPS.forEach(function (group, groupIndex) {
|
||||
var groupEl = allGroupEls[groupIndex];
|
||||
@@ -356,8 +439,16 @@
|
||||
});
|
||||
|
||||
tl.set(groupEl, { opacity: 0, scaleX: 0.8, scaleY: 1 }, visibleStart);
|
||||
tl.to(groupEl, { opacity: 1, scaleX: 1, duration: ENTRY_DURATION, ease: "power3.out", force3D: true }, visibleStart);
|
||||
tl.to(groupEl, { scaleX: 0.75, opacity: 0.8, duration: EXIT_DURATION, ease: "power2.in", force3D: true }, exitStart);
|
||||
tl.to(
|
||||
groupEl,
|
||||
{ opacity: 1, scaleX: 1, duration: ENTRY_DURATION, ease: "power3.out", force3D: true },
|
||||
visibleStart,
|
||||
);
|
||||
tl.to(
|
||||
groupEl,
|
||||
{ scaleX: 0.75, opacity: 0.8, duration: EXIT_DURATION, ease: "power2.in", force3D: true },
|
||||
exitStart,
|
||||
);
|
||||
tl.set(groupEl, { opacity: 0 }, visibleEnd);
|
||||
});
|
||||
|
||||
|
||||
+150
-59
@@ -6,7 +6,10 @@
|
||||
<title>Emoji Pop</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Gabarito:wght@900&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Gabarito:wght@900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*,
|
||||
@@ -155,67 +158,117 @@
|
||||
var ACCENT_COLORS = ["#FF76FF", "#FF0002", "#B2F7FF"];
|
||||
var KEYWORDS = new Set(["hyperframes", "html", "professional", "code", "cinema"]);
|
||||
var TRANSITION_WORDS = new Set([
|
||||
"the", "a", "an", "and", "or", "but", "is", "are", "was", "were",
|
||||
"to", "of", "in", "on", "at", "for", "with", "by", "from", "as",
|
||||
"it", "its", "this", "that", "these", "those", "be", "been",
|
||||
"have", "has", "had", "do", "does", "did", "will", "would", "could",
|
||||
"should", "may", "might", "must", "can", "if", "then", "so", "just",
|
||||
"not", "no", "yes", "up", "out", "about"
|
||||
"the",
|
||||
"a",
|
||||
"an",
|
||||
"and",
|
||||
"or",
|
||||
"but",
|
||||
"is",
|
||||
"are",
|
||||
"was",
|
||||
"were",
|
||||
"to",
|
||||
"of",
|
||||
"in",
|
||||
"on",
|
||||
"at",
|
||||
"for",
|
||||
"with",
|
||||
"by",
|
||||
"from",
|
||||
"as",
|
||||
"it",
|
||||
"its",
|
||||
"this",
|
||||
"that",
|
||||
"these",
|
||||
"those",
|
||||
"be",
|
||||
"been",
|
||||
"have",
|
||||
"has",
|
||||
"had",
|
||||
"do",
|
||||
"does",
|
||||
"did",
|
||||
"will",
|
||||
"would",
|
||||
"could",
|
||||
"should",
|
||||
"may",
|
||||
"might",
|
||||
"must",
|
||||
"can",
|
||||
"if",
|
||||
"then",
|
||||
"so",
|
||||
"just",
|
||||
"not",
|
||||
"no",
|
||||
"yes",
|
||||
"up",
|
||||
"out",
|
||||
"about",
|
||||
]);
|
||||
|
||||
// Emoji map for key words
|
||||
var WORD_EMOJI = {
|
||||
"hyperframes": "🎬",
|
||||
"html": "💻",
|
||||
"professional": "✨",
|
||||
"code": "⌨️",
|
||||
"cinema": "🎥",
|
||||
"video": "📹",
|
||||
"frame": "🖼️"
|
||||
hyperframes: "🎬",
|
||||
html: "💻",
|
||||
professional: "✨",
|
||||
code: "⌨️",
|
||||
cinema: "🎥",
|
||||
video: "📹",
|
||||
frame: "🖼️",
|
||||
};
|
||||
|
||||
var TRANSCRIPT = [
|
||||
{"text": "Every", "start": 0.0, "end": 0.3},
|
||||
{"text": "great", "start": 0.3, "end": 0.55},
|
||||
{"text": "video", "start": 0.55, "end": 0.85},
|
||||
{"text": "starts", "start": 0.85, "end": 1.1},
|
||||
{"text": "with", "start": 1.1, "end": 1.25},
|
||||
{"text": "a", "start": 1.25, "end": 1.35},
|
||||
{"text": "single", "start": 1.35, "end": 1.65},
|
||||
{"text": "frame.", "start": 1.65, "end": 2.0},
|
||||
{"text": "HyperFrames", "start": 2.1, "end": 2.65},
|
||||
{"text": "lets", "start": 2.65, "end": 2.85},
|
||||
{"text": "you", "start": 2.85, "end": 2.95},
|
||||
{"text": "write", "start": 2.95, "end": 3.15},
|
||||
{"text": "HTML", "start": 3.15, "end": 3.55},
|
||||
{"text": "and", "start": 3.55, "end": 3.65},
|
||||
{"text": "render", "start": 3.65, "end": 3.95},
|
||||
{"text": "professional", "start": 3.95, "end": 4.45},
|
||||
{"text": "video.", "start": 4.45, "end": 4.8},
|
||||
{"text": "No", "start": 4.9, "end": 5.05},
|
||||
{"text": "timeline.", "start": 5.05, "end": 5.45},
|
||||
{"text": "No", "start": 5.5, "end": 5.65},
|
||||
{"text": "drag", "start": 5.65, "end": 5.85},
|
||||
{"text": "and", "start": 5.85, "end": 5.95},
|
||||
{"text": "drop.", "start": 5.95, "end": 6.25},
|
||||
{"text": "Just", "start": 6.35, "end": 6.55},
|
||||
{"text": "code", "start": 6.55, "end": 6.8},
|
||||
{"text": "that", "start": 6.8, "end": 6.95},
|
||||
{"text": "becomes", "start": 6.95, "end": 7.3},
|
||||
{"text": "cinema.", "start": 7.3, "end": 7.7}
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
function normalizeWords(rawWords) {
|
||||
return rawWords.map(function (item) {
|
||||
var text = String(item.word || item.text || "").trim();
|
||||
var clean = text.toLowerCase().replace(/[^a-z]/g, "");
|
||||
return {
|
||||
text: text,
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
emoji: WORD_EMOJI[clean] || null,
|
||||
};
|
||||
}).filter(function (word) { return word.text.length > 0; });
|
||||
return rawWords
|
||||
.map(function (item) {
|
||||
var text = String(item.word || item.text || "").trim();
|
||||
var clean = text.toLowerCase().replace(/[^a-z]/g, "");
|
||||
return {
|
||||
text: text,
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
emoji: WORD_EMOJI[clean] || null,
|
||||
};
|
||||
})
|
||||
.filter(function (word) {
|
||||
return word.text.length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
function seededRandom(seed) {
|
||||
@@ -272,7 +325,12 @@
|
||||
current.push(word);
|
||||
var punctuation = /[,.:!?]$/.test(word.text);
|
||||
var pause = nextWord ? nextWord.start - word.end : 0;
|
||||
if (!nextWord || punctuation || pause >= PAUSE_THRESHOLD || current.length >= MAX_WORDS_PER_GROUP) {
|
||||
if (
|
||||
!nextWord ||
|
||||
punctuation ||
|
||||
pause >= PAUSE_THRESHOLD ||
|
||||
current.length >= MAX_WORDS_PER_GROUP
|
||||
) {
|
||||
groups.push(makeGroup(current, groups.length));
|
||||
current = [];
|
||||
}
|
||||
@@ -285,9 +343,18 @@
|
||||
var colors = assignWordColors(words, groupIndex);
|
||||
var emoji = null;
|
||||
for (var i = 0; i < words.length; i++) {
|
||||
if (words[i].emoji) { emoji = words[i].emoji; break; }
|
||||
if (words[i].emoji) {
|
||||
emoji = words[i].emoji;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return { words: words.slice(), colors: colors, emoji: emoji, start: words[0].start, end: words[words.length - 1].end };
|
||||
return {
|
||||
words: words.slice(),
|
||||
colors: colors,
|
||||
emoji: emoji,
|
||||
start: words[0].start,
|
||||
end: words[words.length - 1].end,
|
||||
};
|
||||
}
|
||||
|
||||
function shadowForColor(color) {
|
||||
@@ -295,7 +362,21 @@
|
||||
var r = parseInt(hex.slice(0, 2), 16);
|
||||
var g = parseInt(hex.slice(2, 4), 16);
|
||||
var b = parseInt(hex.slice(4, 6), 16);
|
||||
return "0 4px 8px rgba(0,0,0,0.7), 0 0 2px rgba(" + r + "," + g + "," + b + ",1), 0 0 8px rgba(" + r + "," + g + "," + b + ",0.6)";
|
||||
return (
|
||||
"0 4px 8px rgba(0,0,0,0.7), 0 0 2px rgba(" +
|
||||
r +
|
||||
"," +
|
||||
g +
|
||||
"," +
|
||||
b +
|
||||
",1), 0 0 8px rgba(" +
|
||||
r +
|
||||
"," +
|
||||
g +
|
||||
"," +
|
||||
b +
|
||||
",0.6)"
|
||||
);
|
||||
}
|
||||
|
||||
function buildCaptions(groups) {
|
||||
@@ -343,7 +424,9 @@
|
||||
return Math.max(0, group.start - entryLead);
|
||||
});
|
||||
|
||||
var allGroupEls = GROUPS.map(function (_, i) { return document.getElementById("caption-group-" + i); });
|
||||
var allGroupEls = GROUPS.map(function (_, i) {
|
||||
return document.getElementById("caption-group-" + i);
|
||||
});
|
||||
|
||||
GROUPS.forEach(function (group, groupIndex) {
|
||||
var groupEl = allGroupEls[groupIndex];
|
||||
@@ -356,8 +439,16 @@
|
||||
});
|
||||
|
||||
tl.set(groupEl, { opacity: 0, scaleX: 0.8, scaleY: 1 }, visibleStart);
|
||||
tl.to(groupEl, { opacity: 1, scaleX: 1, duration: ENTRY_DURATION, ease: "power3.out", force3D: true }, visibleStart);
|
||||
tl.to(groupEl, { scaleX: 0.75, opacity: 0.8, duration: EXIT_DURATION, ease: "power2.in", force3D: true }, exitStart);
|
||||
tl.to(
|
||||
groupEl,
|
||||
{ opacity: 1, scaleX: 1, duration: ENTRY_DURATION, ease: "power3.out", force3D: true },
|
||||
visibleStart,
|
||||
);
|
||||
tl.to(
|
||||
groupEl,
|
||||
{ scaleX: 0.75, opacity: 0.8, duration: EXIT_DURATION, ease: "power2.in", force3D: true },
|
||||
exitStart,
|
||||
);
|
||||
tl.set(groupEl, { opacity: 0 }, visibleEnd);
|
||||
});
|
||||
|
||||
|
||||
+229
-124
@@ -6,50 +6,89 @@
|
||||
<title>Glitch RGB</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#glitch-rgb {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#gl-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.gl-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.45); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
.gl-scanlines {
|
||||
position: absolute; inset: 0; z-index: 5; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 5;
|
||||
pointer-events: none;
|
||||
background: repeating-linear-gradient(
|
||||
to bottom,
|
||||
transparent 0px, transparent 3px,
|
||||
rgba(0,0,0,0.08) 3px, rgba(0,0,0,0.08) 4px
|
||||
transparent 0px,
|
||||
transparent 3px,
|
||||
rgba(0, 0, 0, 0.08) 3px,
|
||||
rgba(0, 0, 0, 0.08) 4px
|
||||
);
|
||||
}
|
||||
#gl-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.gl-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 100px;
|
||||
opacity: 0; visibility: hidden;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 100px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.gl-word {
|
||||
font-family: 'Space Grotesk', sans-serif;
|
||||
font-weight: 700; font-size: 88px;
|
||||
font-family: "Space Grotesk", sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 88px;
|
||||
text-transform: uppercase;
|
||||
color: rgba(180,230,255,0.45);
|
||||
display: inline-block; letter-spacing: 0.05em; line-height: 1;
|
||||
color: rgba(180, 230, 255, 0.45);
|
||||
display: inline-block;
|
||||
letter-spacing: 0.05em;
|
||||
line-height: 1;
|
||||
will-change: transform, text-shadow, color;
|
||||
}
|
||||
</style>
|
||||
@@ -64,124 +103,190 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="gl-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="gl-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="gl-overlay"></div>
|
||||
<div class="gl-scanlines"></div>
|
||||
<div id="gl-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
function mulberry32(seed) {
|
||||
return function() {
|
||||
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
|
||||
var t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
||||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
function mulberry32(seed) {
|
||||
return function () {
|
||||
seed |= 0;
|
||||
seed = (seed + 0x6d2b79f5) | 0;
|
||||
var t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
|
||||
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
// Keywords get white + glow on activation
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
// Keywords get white + glow on activation
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var RAW_GROUPS = [
|
||||
[0,3],[4,7],[8,8],[9,12],[13,15],[16,16],[17,19],[20,22],[23,24],[25,27]
|
||||
];
|
||||
var GROUPS = RAW_GROUPS.map(function(pair, gi) {
|
||||
var ws = pair[0], we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi+1][0]].start : 8.0;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.35, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
var BASE_FONT = 88;
|
||||
var container = document.getElementById('gl-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'gl-group';
|
||||
grp.id = 'gl-grp-' + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement('span');
|
||||
span.className = 'gl-word';
|
||||
span.id = 'gl-w-' + wi;
|
||||
span.textContent = w.text.toUpperCase();
|
||||
span.style.fontSize = BASE_FONT + 'px';
|
||||
grp.appendChild(span);
|
||||
var RAW_GROUPS = [
|
||||
[0, 3],
|
||||
[4, 7],
|
||||
[8, 8],
|
||||
[9, 12],
|
||||
[13, 15],
|
||||
[16, 16],
|
||||
[17, 19],
|
||||
[20, 22],
|
||||
[23, 24],
|
||||
[25, 27],
|
||||
];
|
||||
var GROUPS = RAW_GROUPS.map(function (pair, gi) {
|
||||
var ws = pair[0],
|
||||
we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : 8.0;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.35, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
var BASE_FONT = 88;
|
||||
var container = document.getElementById("gl-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
tl.set(grp, { visibility: 'visible' }, g.start);
|
||||
tl.fromTo(grp,
|
||||
{ opacity: 0, x: -8 },
|
||||
{ opacity: 1, x: 0, duration: 0.18, ease: 'power3.out' },
|
||||
g.start
|
||||
);
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "gl-group";
|
||||
grp.id = "gl-grp-" + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordEl = document.getElementById('gl-w-' + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
var rng = mulberry32(wi * 777 + 13);
|
||||
var j1 = (rng() - 0.5) * 10;
|
||||
var j2 = (rng() - 0.5) * 8;
|
||||
var j3 = (rng() - 0.5) * 6;
|
||||
var shadowMag = 3 + rng() * 4;
|
||||
var sm = shadowMag.toFixed(1);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement("span");
|
||||
span.className = "gl-word";
|
||||
span.id = "gl-w-" + wi;
|
||||
span.textContent = w.text.toUpperCase();
|
||||
span.style.fontSize = BASE_FONT + "px";
|
||||
grp.appendChild(span);
|
||||
});
|
||||
|
||||
tl.to(wordEl, { x: j1, color: '#ffffff', textShadow: sm + 'px 0 #ff003c, -' + sm + 'px 0 #00e5ff', duration: 0.045, ease: 'none' }, w.start);
|
||||
tl.to(wordEl, { x: j2, textShadow: '-' + (shadowMag * 0.7).toFixed(1) + 'px 0 #ff003c, ' + (shadowMag * 0.7).toFixed(1) + 'px 0 #00e5ff', duration: 0.038, ease: 'none' }, w.start + 0.045);
|
||||
tl.to(wordEl, { x: j3, textShadow: sm + 'px 0 #ff003c, -' + sm + 'px 0 #00e5ff', duration: 0.03, ease: 'none' }, w.start + 0.083);
|
||||
tl.to(wordEl, { x: 0, textShadow: 'none', color: isKW ? '#ffffff' : '#00e5ff', duration: 0.05, ease: 'power2.out' }, w.start + 0.113);
|
||||
tl.to(wordEl, { color: 'rgba(180,230,255,0.4)', textShadow: 'none', duration: 0.12 }, w.end);
|
||||
container.appendChild(grp);
|
||||
|
||||
tl.set(grp, { visibility: "visible" }, g.start);
|
||||
tl.fromTo(
|
||||
grp,
|
||||
{ opacity: 0, x: -8 },
|
||||
{ opacity: 1, x: 0, duration: 0.18, ease: "power3.out" },
|
||||
g.start,
|
||||
);
|
||||
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordEl = document.getElementById("gl-w-" + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
var rng = mulberry32(wi * 777 + 13);
|
||||
var j1 = (rng() - 0.5) * 10;
|
||||
var j2 = (rng() - 0.5) * 8;
|
||||
var j3 = (rng() - 0.5) * 6;
|
||||
var shadowMag = 3 + rng() * 4;
|
||||
var sm = shadowMag.toFixed(1);
|
||||
|
||||
tl.to(
|
||||
wordEl,
|
||||
{
|
||||
x: j1,
|
||||
color: "#ffffff",
|
||||
textShadow: sm + "px 0 #ff003c, -" + sm + "px 0 #00e5ff",
|
||||
duration: 0.045,
|
||||
ease: "none",
|
||||
},
|
||||
w.start,
|
||||
);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{
|
||||
x: j2,
|
||||
textShadow:
|
||||
"-" +
|
||||
(shadowMag * 0.7).toFixed(1) +
|
||||
"px 0 #ff003c, " +
|
||||
(shadowMag * 0.7).toFixed(1) +
|
||||
"px 0 #00e5ff",
|
||||
duration: 0.038,
|
||||
ease: "none",
|
||||
},
|
||||
w.start + 0.045,
|
||||
);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{
|
||||
x: j3,
|
||||
textShadow: sm + "px 0 #ff003c, -" + sm + "px 0 #00e5ff",
|
||||
duration: 0.03,
|
||||
ease: "none",
|
||||
},
|
||||
w.start + 0.083,
|
||||
);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{
|
||||
x: 0,
|
||||
textShadow: "none",
|
||||
color: isKW ? "#ffffff" : "#00e5ff",
|
||||
duration: 0.05,
|
||||
ease: "power2.out",
|
||||
},
|
||||
w.start + 0.113,
|
||||
);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ color: "rgba(180,230,255,0.4)", textShadow: "none", duration: 0.12 },
|
||||
w.end,
|
||||
);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, x: 8, duration: 0.15 }, g.end - 0.15);
|
||||
tl.set(grp, { opacity: 0, visibility: "hidden" }, g.end);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, x: 8, duration: 0.15 }, g.end - 0.15);
|
||||
tl.set(grp, { opacity: 0, visibility: 'hidden' }, g.end);
|
||||
});
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines['glitch-rgb'] = tl;
|
||||
})();
|
||||
tl.seek(0);
|
||||
window.__timelines["glitch-rgb"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+229
-124
@@ -6,50 +6,89 @@
|
||||
<title>Glitch RGB</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#glitch-rgb {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#gl-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.gl-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.45); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
.gl-scanlines {
|
||||
position: absolute; inset: 0; z-index: 5; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 5;
|
||||
pointer-events: none;
|
||||
background: repeating-linear-gradient(
|
||||
to bottom,
|
||||
transparent 0px, transparent 3px,
|
||||
rgba(0,0,0,0.08) 3px, rgba(0,0,0,0.08) 4px
|
||||
transparent 0px,
|
||||
transparent 3px,
|
||||
rgba(0, 0, 0, 0.08) 3px,
|
||||
rgba(0, 0, 0, 0.08) 4px
|
||||
);
|
||||
}
|
||||
#gl-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.gl-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 100px;
|
||||
opacity: 0; visibility: hidden;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 100px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.gl-word {
|
||||
font-family: 'Space Grotesk', sans-serif;
|
||||
font-weight: 700; font-size: 88px;
|
||||
font-family: "Space Grotesk", sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 88px;
|
||||
text-transform: uppercase;
|
||||
color: rgba(180,230,255,0.45);
|
||||
display: inline-block; letter-spacing: 0.05em; line-height: 1;
|
||||
color: rgba(180, 230, 255, 0.45);
|
||||
display: inline-block;
|
||||
letter-spacing: 0.05em;
|
||||
line-height: 1;
|
||||
will-change: transform, text-shadow, color;
|
||||
}
|
||||
</style>
|
||||
@@ -64,124 +103,190 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="gl-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="gl-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="gl-overlay"></div>
|
||||
<div class="gl-scanlines"></div>
|
||||
<div id="gl-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
function mulberry32(seed) {
|
||||
return function() {
|
||||
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
|
||||
var t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
||||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
function mulberry32(seed) {
|
||||
return function () {
|
||||
seed |= 0;
|
||||
seed = (seed + 0x6d2b79f5) | 0;
|
||||
var t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
|
||||
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
// Keywords get white + glow on activation
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
// Keywords get white + glow on activation
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var RAW_GROUPS = [
|
||||
[0,3],[4,7],[8,8],[9,12],[13,15],[16,16],[17,19],[20,22],[23,24],[25,27]
|
||||
];
|
||||
var GROUPS = RAW_GROUPS.map(function(pair, gi) {
|
||||
var ws = pair[0], we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi+1][0]].start : 8.0;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.35, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
var BASE_FONT = 88;
|
||||
var container = document.getElementById('gl-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'gl-group';
|
||||
grp.id = 'gl-grp-' + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement('span');
|
||||
span.className = 'gl-word';
|
||||
span.id = 'gl-w-' + wi;
|
||||
span.textContent = w.text.toUpperCase();
|
||||
span.style.fontSize = BASE_FONT + 'px';
|
||||
grp.appendChild(span);
|
||||
var RAW_GROUPS = [
|
||||
[0, 3],
|
||||
[4, 7],
|
||||
[8, 8],
|
||||
[9, 12],
|
||||
[13, 15],
|
||||
[16, 16],
|
||||
[17, 19],
|
||||
[20, 22],
|
||||
[23, 24],
|
||||
[25, 27],
|
||||
];
|
||||
var GROUPS = RAW_GROUPS.map(function (pair, gi) {
|
||||
var ws = pair[0],
|
||||
we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : 8.0;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.35, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
var BASE_FONT = 88;
|
||||
var container = document.getElementById("gl-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
tl.set(grp, { visibility: 'visible' }, g.start);
|
||||
tl.fromTo(grp,
|
||||
{ opacity: 0, x: -8 },
|
||||
{ opacity: 1, x: 0, duration: 0.18, ease: 'power3.out' },
|
||||
g.start
|
||||
);
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "gl-group";
|
||||
grp.id = "gl-grp-" + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordEl = document.getElementById('gl-w-' + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
var rng = mulberry32(wi * 777 + 13);
|
||||
var j1 = (rng() - 0.5) * 10;
|
||||
var j2 = (rng() - 0.5) * 8;
|
||||
var j3 = (rng() - 0.5) * 6;
|
||||
var shadowMag = 3 + rng() * 4;
|
||||
var sm = shadowMag.toFixed(1);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement("span");
|
||||
span.className = "gl-word";
|
||||
span.id = "gl-w-" + wi;
|
||||
span.textContent = w.text.toUpperCase();
|
||||
span.style.fontSize = BASE_FONT + "px";
|
||||
grp.appendChild(span);
|
||||
});
|
||||
|
||||
tl.to(wordEl, { x: j1, color: '#ffffff', textShadow: sm + 'px 0 #ff003c, -' + sm + 'px 0 #00e5ff', duration: 0.045, ease: 'none' }, w.start);
|
||||
tl.to(wordEl, { x: j2, textShadow: '-' + (shadowMag * 0.7).toFixed(1) + 'px 0 #ff003c, ' + (shadowMag * 0.7).toFixed(1) + 'px 0 #00e5ff', duration: 0.038, ease: 'none' }, w.start + 0.045);
|
||||
tl.to(wordEl, { x: j3, textShadow: sm + 'px 0 #ff003c, -' + sm + 'px 0 #00e5ff', duration: 0.03, ease: 'none' }, w.start + 0.083);
|
||||
tl.to(wordEl, { x: 0, textShadow: 'none', color: isKW ? '#ffffff' : '#00e5ff', duration: 0.05, ease: 'power2.out' }, w.start + 0.113);
|
||||
tl.to(wordEl, { color: 'rgba(180,230,255,0.4)', textShadow: 'none', duration: 0.12 }, w.end);
|
||||
container.appendChild(grp);
|
||||
|
||||
tl.set(grp, { visibility: "visible" }, g.start);
|
||||
tl.fromTo(
|
||||
grp,
|
||||
{ opacity: 0, x: -8 },
|
||||
{ opacity: 1, x: 0, duration: 0.18, ease: "power3.out" },
|
||||
g.start,
|
||||
);
|
||||
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordEl = document.getElementById("gl-w-" + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
var rng = mulberry32(wi * 777 + 13);
|
||||
var j1 = (rng() - 0.5) * 10;
|
||||
var j2 = (rng() - 0.5) * 8;
|
||||
var j3 = (rng() - 0.5) * 6;
|
||||
var shadowMag = 3 + rng() * 4;
|
||||
var sm = shadowMag.toFixed(1);
|
||||
|
||||
tl.to(
|
||||
wordEl,
|
||||
{
|
||||
x: j1,
|
||||
color: "#ffffff",
|
||||
textShadow: sm + "px 0 #ff003c, -" + sm + "px 0 #00e5ff",
|
||||
duration: 0.045,
|
||||
ease: "none",
|
||||
},
|
||||
w.start,
|
||||
);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{
|
||||
x: j2,
|
||||
textShadow:
|
||||
"-" +
|
||||
(shadowMag * 0.7).toFixed(1) +
|
||||
"px 0 #ff003c, " +
|
||||
(shadowMag * 0.7).toFixed(1) +
|
||||
"px 0 #00e5ff",
|
||||
duration: 0.038,
|
||||
ease: "none",
|
||||
},
|
||||
w.start + 0.045,
|
||||
);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{
|
||||
x: j3,
|
||||
textShadow: sm + "px 0 #ff003c, -" + sm + "px 0 #00e5ff",
|
||||
duration: 0.03,
|
||||
ease: "none",
|
||||
},
|
||||
w.start + 0.083,
|
||||
);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{
|
||||
x: 0,
|
||||
textShadow: "none",
|
||||
color: isKW ? "#ffffff" : "#00e5ff",
|
||||
duration: 0.05,
|
||||
ease: "power2.out",
|
||||
},
|
||||
w.start + 0.113,
|
||||
);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ color: "rgba(180,230,255,0.4)", textShadow: "none", duration: 0.12 },
|
||||
w.end,
|
||||
);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, x: 8, duration: 0.15 }, g.end - 0.15);
|
||||
tl.set(grp, { opacity: 0, visibility: "hidden" }, g.end);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, x: 8, duration: 0.15 }, g.end - 0.15);
|
||||
tl.set(grp, { opacity: 0, visibility: 'hidden' }, g.end);
|
||||
});
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines['glitch-rgb'] = tl;
|
||||
})();
|
||||
tl.seek(0);
|
||||
window.__timelines["glitch-rgb"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+173
-131
@@ -6,40 +6,74 @@
|
||||
<title>Gradient Fill</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@900&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Nunito:wght@900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#gradient-fill {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#gr-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.gr-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.42); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.42);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#gr-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.gr-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 80px;
|
||||
opacity: 0; visibility: hidden;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 80px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.gr-word {
|
||||
font-family: 'Nunito', sans-serif;
|
||||
font-weight: 900; font-size: 100px;
|
||||
display: inline-block; letter-spacing: 0.04em; line-height: 1;
|
||||
font-family: "Nunito", sans-serif;
|
||||
font-weight: 900;
|
||||
font-size: 100px;
|
||||
display: inline-block;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
@@ -57,131 +91,139 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="gr-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="gr-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="gr-overlay"></div>
|
||||
<div id="gr-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
var GROUPS = [
|
||||
{wordStart:0, wordEnd:3, start:0.0, end:1.05},
|
||||
{wordStart:4, wordEnd:7, start:1.1, end:2.05},
|
||||
{wordStart:8, wordEnd:8, start:2.1, end:2.6},
|
||||
{wordStart:9, wordEnd:12, start:2.65, end:3.5},
|
||||
{wordStart:13, wordEnd:15, start:3.55, end:4.4},
|
||||
{wordStart:16, wordEnd:16, start:3.95, end:4.75},
|
||||
{wordStart:17, wordEnd:19, start:4.9, end:5.4},
|
||||
{wordStart:20, wordEnd:22, start:5.65, end:6.2},
|
||||
{wordStart:23, wordEnd:24, start:6.35, end:6.75},
|
||||
{wordStart:25, wordEnd:27, start:6.8, end:7.8},
|
||||
];
|
||||
var GROUPS = [
|
||||
{ wordStart: 0, wordEnd: 3, start: 0.0, end: 1.05 },
|
||||
{ wordStart: 4, wordEnd: 7, start: 1.1, end: 2.05 },
|
||||
{ wordStart: 8, wordEnd: 8, start: 2.1, end: 2.6 },
|
||||
{ wordStart: 9, wordEnd: 12, start: 2.65, end: 3.5 },
|
||||
{ wordStart: 13, wordEnd: 15, start: 3.55, end: 4.4 },
|
||||
{ wordStart: 16, wordEnd: 16, start: 3.95, end: 4.75 },
|
||||
{ wordStart: 17, wordEnd: 19, start: 4.9, end: 5.4 },
|
||||
{ wordStart: 20, wordEnd: 22, start: 5.65, end: 6.2 },
|
||||
{ wordStart: 23, wordEnd: 24, start: 6.35, end: 6.75 },
|
||||
{ wordStart: 25, wordEnd: 27, start: 6.8, end: 7.8 },
|
||||
];
|
||||
|
||||
// Enhanced gradient palette with accent for keywords
|
||||
var GRADS = [
|
||||
"linear-gradient(135deg,#FF6B6B,#FFD700)",
|
||||
"linear-gradient(135deg,#4ADE80,#22D3EE)",
|
||||
"linear-gradient(135deg,#818CF8,#E879F9)",
|
||||
"linear-gradient(135deg,#FFD700,#FF6B35)",
|
||||
"linear-gradient(135deg,#22D3EE,#4ADE80)",
|
||||
"linear-gradient(135deg,#E879F9,#818CF8)",
|
||||
"linear-gradient(135deg,#FF3366,#FF6B35)"
|
||||
];
|
||||
var KEYWORD_GRADS = {
|
||||
8: "linear-gradient(135deg,#FF6B6B,#FFD700,#FF6B6B)", // HyperFrames
|
||||
12: "linear-gradient(135deg,#22D3EE,#ffffff,#22D3EE)", // HTML
|
||||
15: "linear-gradient(135deg,#818CF8,#E879F9,#818CF8)", // professional
|
||||
24: "linear-gradient(135deg,#00F5D4,#22D3EE,#00F5D4)", // code
|
||||
27: "linear-gradient(135deg,#FFD700,#FF6B35,#FFD700)" // cinema.
|
||||
};
|
||||
// Enhanced gradient palette with accent for keywords
|
||||
var GRADS = [
|
||||
"linear-gradient(135deg,#FF6B6B,#FFD700)",
|
||||
"linear-gradient(135deg,#4ADE80,#22D3EE)",
|
||||
"linear-gradient(135deg,#818CF8,#E879F9)",
|
||||
"linear-gradient(135deg,#FFD700,#FF6B35)",
|
||||
"linear-gradient(135deg,#22D3EE,#4ADE80)",
|
||||
"linear-gradient(135deg,#E879F9,#818CF8)",
|
||||
"linear-gradient(135deg,#FF3366,#FF6B35)",
|
||||
];
|
||||
var KEYWORD_GRADS = {
|
||||
8: "linear-gradient(135deg,#FF6B6B,#FFD700,#FF6B6B)", // HyperFrames
|
||||
12: "linear-gradient(135deg,#22D3EE,#ffffff,#22D3EE)", // HTML
|
||||
15: "linear-gradient(135deg,#818CF8,#E879F9,#818CF8)", // professional
|
||||
24: "linear-gradient(135deg,#00F5D4,#22D3EE,#00F5D4)", // code
|
||||
27: "linear-gradient(135deg,#FFD700,#FF6B35,#FFD700)", // cinema.
|
||||
};
|
||||
|
||||
var container = document.getElementById('gr-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
var container = document.getElementById("gr-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'gr-group';
|
||||
grp.id = 'gr-grp-' + gi;
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "gr-group";
|
||||
grp.id = "gr-grp-" + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement('span');
|
||||
span.className = 'gr-word';
|
||||
span.id = 'gr-w-' + wi;
|
||||
span.textContent = w.text;
|
||||
span.style.fontSize = '100px';
|
||||
var grad = KEYWORD_GRADS[wi] || GRADS[wi % 7];
|
||||
span.style.background = grad;
|
||||
span.style.webkitBackgroundClip = 'text';
|
||||
span.style.backgroundClip = 'text';
|
||||
span.style.color = 'transparent';
|
||||
grp.appendChild(span);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement("span");
|
||||
span.className = "gr-word";
|
||||
span.id = "gr-w-" + wi;
|
||||
span.textContent = w.text;
|
||||
span.style.fontSize = "100px";
|
||||
var grad = KEYWORD_GRADS[wi] || GRADS[wi % 7];
|
||||
span.style.background = grad;
|
||||
span.style.webkitBackgroundClip = "text";
|
||||
span.style.backgroundClip = "text";
|
||||
span.style.color = "transparent";
|
||||
grp.appendChild(span);
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
|
||||
var gs = g.start;
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var el = document.getElementById("gr-w-" + wi);
|
||||
tl.set(el, { opacity: 0, y: 55, scale: 0.35 }, gs);
|
||||
tl.fromTo(
|
||||
el,
|
||||
{ y: 55, scale: 0.35, opacity: 0 },
|
||||
{ y: 0, scale: 1, opacity: 0.35, duration: 0.55, ease: "elastic.out(1.6,0.4)" },
|
||||
gs + i * 0.05,
|
||||
);
|
||||
});
|
||||
|
||||
tl.set(grp, { visibility: "visible", opacity: 1 }, gs);
|
||||
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var el = document.getElementById("gr-w-" + wi);
|
||||
tl.to(el, { opacity: 1, scale: 1.1, duration: 0.08 }, w.start);
|
||||
tl.to(el, { opacity: 0.3, scale: 1, duration: 0.08 }, w.end);
|
||||
});
|
||||
|
||||
tl.to(grp, { y: -26, opacity: 0, duration: 0.18 }, g.end - 0.18);
|
||||
tl.set(grp, { opacity: 0, visibility: "hidden" }, g.end);
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
|
||||
var gs = g.start;
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var el = document.getElementById('gr-w-' + wi);
|
||||
tl.set(el, { opacity: 0, y: 55, scale: 0.35 }, gs);
|
||||
tl.fromTo(el,
|
||||
{ y: 55, scale: 0.35, opacity: 0 },
|
||||
{ y: 0, scale: 1, opacity: 0.35, duration: 0.55, ease: 'elastic.out(1.6,0.4)' },
|
||||
gs + i * 0.05
|
||||
);
|
||||
});
|
||||
|
||||
tl.set(grp, { visibility: 'visible', opacity: 1 }, gs);
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var el = document.getElementById('gr-w-' + wi);
|
||||
tl.to(el, { opacity: 1, scale: 1.1, duration: 0.08 }, w.start);
|
||||
tl.to(el, { opacity: 0.3, scale: 1, duration: 0.08 }, w.end);
|
||||
});
|
||||
|
||||
tl.to(grp, { y: -26, opacity: 0, duration: 0.18 }, g.end - 0.18);
|
||||
tl.set(grp, { opacity: 0, visibility: 'hidden' }, g.end);
|
||||
});
|
||||
|
||||
window.__timelines['gradient-fill'] = tl;
|
||||
})();
|
||||
window.__timelines["gradient-fill"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+173
-131
@@ -6,40 +6,74 @@
|
||||
<title>Gradient Fill</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@900&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Nunito:wght@900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#gradient-fill {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#gr-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.gr-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.42); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.42);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#gr-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.gr-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 80px;
|
||||
opacity: 0; visibility: hidden;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 80px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.gr-word {
|
||||
font-family: 'Nunito', sans-serif;
|
||||
font-weight: 900; font-size: 100px;
|
||||
display: inline-block; letter-spacing: 0.04em; line-height: 1;
|
||||
font-family: "Nunito", sans-serif;
|
||||
font-weight: 900;
|
||||
font-size: 100px;
|
||||
display: inline-block;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
@@ -57,131 +91,139 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="gr-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="gr-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="gr-overlay"></div>
|
||||
<div id="gr-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
var GROUPS = [
|
||||
{wordStart:0, wordEnd:3, start:0.0, end:1.05},
|
||||
{wordStart:4, wordEnd:7, start:1.1, end:2.05},
|
||||
{wordStart:8, wordEnd:8, start:2.1, end:2.6},
|
||||
{wordStart:9, wordEnd:12, start:2.65, end:3.5},
|
||||
{wordStart:13, wordEnd:15, start:3.55, end:4.4},
|
||||
{wordStart:16, wordEnd:16, start:3.95, end:4.75},
|
||||
{wordStart:17, wordEnd:19, start:4.9, end:5.4},
|
||||
{wordStart:20, wordEnd:22, start:5.65, end:6.2},
|
||||
{wordStart:23, wordEnd:24, start:6.35, end:6.75},
|
||||
{wordStart:25, wordEnd:27, start:6.8, end:7.8},
|
||||
];
|
||||
var GROUPS = [
|
||||
{ wordStart: 0, wordEnd: 3, start: 0.0, end: 1.05 },
|
||||
{ wordStart: 4, wordEnd: 7, start: 1.1, end: 2.05 },
|
||||
{ wordStart: 8, wordEnd: 8, start: 2.1, end: 2.6 },
|
||||
{ wordStart: 9, wordEnd: 12, start: 2.65, end: 3.5 },
|
||||
{ wordStart: 13, wordEnd: 15, start: 3.55, end: 4.4 },
|
||||
{ wordStart: 16, wordEnd: 16, start: 3.95, end: 4.75 },
|
||||
{ wordStart: 17, wordEnd: 19, start: 4.9, end: 5.4 },
|
||||
{ wordStart: 20, wordEnd: 22, start: 5.65, end: 6.2 },
|
||||
{ wordStart: 23, wordEnd: 24, start: 6.35, end: 6.75 },
|
||||
{ wordStart: 25, wordEnd: 27, start: 6.8, end: 7.8 },
|
||||
];
|
||||
|
||||
// Enhanced gradient palette with accent for keywords
|
||||
var GRADS = [
|
||||
"linear-gradient(135deg,#FF6B6B,#FFD700)",
|
||||
"linear-gradient(135deg,#4ADE80,#22D3EE)",
|
||||
"linear-gradient(135deg,#818CF8,#E879F9)",
|
||||
"linear-gradient(135deg,#FFD700,#FF6B35)",
|
||||
"linear-gradient(135deg,#22D3EE,#4ADE80)",
|
||||
"linear-gradient(135deg,#E879F9,#818CF8)",
|
||||
"linear-gradient(135deg,#FF3366,#FF6B35)"
|
||||
];
|
||||
var KEYWORD_GRADS = {
|
||||
8: "linear-gradient(135deg,#FF6B6B,#FFD700,#FF6B6B)", // HyperFrames
|
||||
12: "linear-gradient(135deg,#22D3EE,#ffffff,#22D3EE)", // HTML
|
||||
15: "linear-gradient(135deg,#818CF8,#E879F9,#818CF8)", // professional
|
||||
24: "linear-gradient(135deg,#00F5D4,#22D3EE,#00F5D4)", // code
|
||||
27: "linear-gradient(135deg,#FFD700,#FF6B35,#FFD700)" // cinema.
|
||||
};
|
||||
// Enhanced gradient palette with accent for keywords
|
||||
var GRADS = [
|
||||
"linear-gradient(135deg,#FF6B6B,#FFD700)",
|
||||
"linear-gradient(135deg,#4ADE80,#22D3EE)",
|
||||
"linear-gradient(135deg,#818CF8,#E879F9)",
|
||||
"linear-gradient(135deg,#FFD700,#FF6B35)",
|
||||
"linear-gradient(135deg,#22D3EE,#4ADE80)",
|
||||
"linear-gradient(135deg,#E879F9,#818CF8)",
|
||||
"linear-gradient(135deg,#FF3366,#FF6B35)",
|
||||
];
|
||||
var KEYWORD_GRADS = {
|
||||
8: "linear-gradient(135deg,#FF6B6B,#FFD700,#FF6B6B)", // HyperFrames
|
||||
12: "linear-gradient(135deg,#22D3EE,#ffffff,#22D3EE)", // HTML
|
||||
15: "linear-gradient(135deg,#818CF8,#E879F9,#818CF8)", // professional
|
||||
24: "linear-gradient(135deg,#00F5D4,#22D3EE,#00F5D4)", // code
|
||||
27: "linear-gradient(135deg,#FFD700,#FF6B35,#FFD700)", // cinema.
|
||||
};
|
||||
|
||||
var container = document.getElementById('gr-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
var container = document.getElementById("gr-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'gr-group';
|
||||
grp.id = 'gr-grp-' + gi;
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "gr-group";
|
||||
grp.id = "gr-grp-" + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement('span');
|
||||
span.className = 'gr-word';
|
||||
span.id = 'gr-w-' + wi;
|
||||
span.textContent = w.text;
|
||||
span.style.fontSize = '100px';
|
||||
var grad = KEYWORD_GRADS[wi] || GRADS[wi % 7];
|
||||
span.style.background = grad;
|
||||
span.style.webkitBackgroundClip = 'text';
|
||||
span.style.backgroundClip = 'text';
|
||||
span.style.color = 'transparent';
|
||||
grp.appendChild(span);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement("span");
|
||||
span.className = "gr-word";
|
||||
span.id = "gr-w-" + wi;
|
||||
span.textContent = w.text;
|
||||
span.style.fontSize = "100px";
|
||||
var grad = KEYWORD_GRADS[wi] || GRADS[wi % 7];
|
||||
span.style.background = grad;
|
||||
span.style.webkitBackgroundClip = "text";
|
||||
span.style.backgroundClip = "text";
|
||||
span.style.color = "transparent";
|
||||
grp.appendChild(span);
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
|
||||
var gs = g.start;
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var el = document.getElementById("gr-w-" + wi);
|
||||
tl.set(el, { opacity: 0, y: 55, scale: 0.35 }, gs);
|
||||
tl.fromTo(
|
||||
el,
|
||||
{ y: 55, scale: 0.35, opacity: 0 },
|
||||
{ y: 0, scale: 1, opacity: 0.35, duration: 0.55, ease: "elastic.out(1.6,0.4)" },
|
||||
gs + i * 0.05,
|
||||
);
|
||||
});
|
||||
|
||||
tl.set(grp, { visibility: "visible", opacity: 1 }, gs);
|
||||
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var el = document.getElementById("gr-w-" + wi);
|
||||
tl.to(el, { opacity: 1, scale: 1.1, duration: 0.08 }, w.start);
|
||||
tl.to(el, { opacity: 0.3, scale: 1, duration: 0.08 }, w.end);
|
||||
});
|
||||
|
||||
tl.to(grp, { y: -26, opacity: 0, duration: 0.18 }, g.end - 0.18);
|
||||
tl.set(grp, { opacity: 0, visibility: "hidden" }, g.end);
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
|
||||
var gs = g.start;
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var el = document.getElementById('gr-w-' + wi);
|
||||
tl.set(el, { opacity: 0, y: 55, scale: 0.35 }, gs);
|
||||
tl.fromTo(el,
|
||||
{ y: 55, scale: 0.35, opacity: 0 },
|
||||
{ y: 0, scale: 1, opacity: 0.35, duration: 0.55, ease: 'elastic.out(1.6,0.4)' },
|
||||
gs + i * 0.05
|
||||
);
|
||||
});
|
||||
|
||||
tl.set(grp, { visibility: 'visible', opacity: 1 }, gs);
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var el = document.getElementById('gr-w-' + wi);
|
||||
tl.to(el, { opacity: 1, scale: 1.1, duration: 0.08 }, w.start);
|
||||
tl.to(el, { opacity: 0.3, scale: 1, duration: 0.08 }, w.end);
|
||||
});
|
||||
|
||||
tl.to(grp, { y: -26, opacity: 0, duration: 0.18 }, g.end - 0.18);
|
||||
tl.set(grp, { opacity: 0, visibility: 'hidden' }, g.end);
|
||||
});
|
||||
|
||||
window.__timelines['gradient-fill'] = tl;
|
||||
})();
|
||||
window.__timelines["gradient-fill"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+146
-108
@@ -9,35 +9,61 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Anton&display=swap" rel="stylesheet" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#kinetic-slam {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#kt-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.kt-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.45); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#kt-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.kt-word {
|
||||
font-family: 'Anton', sans-serif;
|
||||
font-family: "Anton", sans-serif;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
color: #ffffff;
|
||||
position: absolute; left: 0; width: 100%;
|
||||
text-align: center; top: 50%;
|
||||
letter-spacing: 0.04em; line-height: 1;
|
||||
opacity: 0; visibility: hidden;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
top: 50%;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -51,107 +77,119 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="kt-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="kt-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="kt-overlay"></div>
|
||||
<div id="kt-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
function mulberry32(seed) {
|
||||
return function() {
|
||||
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
|
||||
var t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
||||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var container = document.getElementById('kt-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
WORDS.forEach(function(w, wi) {
|
||||
var el = document.createElement('div');
|
||||
el.className = 'kt-word';
|
||||
el.id = 'kt-w-' + wi;
|
||||
el.textContent = w.text.toUpperCase();
|
||||
el.style.fontSize = '220px';
|
||||
if (KEYWORDS.has(wi)) el.style.color = '#FFD700';
|
||||
container.appendChild(el);
|
||||
|
||||
gsap.set(el, { yPercent: -50 });
|
||||
|
||||
var entranceMode = wi % 4;
|
||||
tl.set(el, { visibility: 'visible' }, w.start);
|
||||
if (entranceMode === 0) {
|
||||
tl.fromTo(el,
|
||||
{ y: -120, opacity: 0 },
|
||||
{ y: 0, opacity: 1, duration: 0.22, ease: 'back.out(1.7)' },
|
||||
w.start
|
||||
);
|
||||
} else if (entranceMode === 1) {
|
||||
tl.fromTo(el,
|
||||
{ x: -300, opacity: 0 },
|
||||
{ x: 0, opacity: 1, duration: 0.2, ease: 'expo.out' },
|
||||
w.start
|
||||
);
|
||||
} else if (entranceMode === 2) {
|
||||
tl.fromTo(el,
|
||||
{ x: 300, opacity: 0 },
|
||||
{ x: 0, opacity: 1, duration: 0.2, ease: 'expo.out' },
|
||||
w.start
|
||||
);
|
||||
} else {
|
||||
tl.fromTo(el,
|
||||
{ scale: 0.4, opacity: 0 },
|
||||
{ scale: 1, opacity: 1, duration: 0.24, ease: 'back.out(2.2)' },
|
||||
w.start
|
||||
);
|
||||
function mulberry32(seed) {
|
||||
return function () {
|
||||
seed |= 0;
|
||||
seed = (seed + 0x6d2b79f5) | 0;
|
||||
var t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
|
||||
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
tl.to(el, { opacity: 0, duration: 0.1, ease: 'power2.in' }, w.end);
|
||||
tl.set(el, { opacity: 0, visibility: 'hidden' }, w.end + 0.1);
|
||||
});
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines['kinetic-slam'] = tl;
|
||||
})();
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var container = document.getElementById("kt-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
WORDS.forEach(function (w, wi) {
|
||||
var el = document.createElement("div");
|
||||
el.className = "kt-word";
|
||||
el.id = "kt-w-" + wi;
|
||||
el.textContent = w.text.toUpperCase();
|
||||
el.style.fontSize = "220px";
|
||||
if (KEYWORDS.has(wi)) el.style.color = "#FFD700";
|
||||
container.appendChild(el);
|
||||
|
||||
gsap.set(el, { yPercent: -50 });
|
||||
|
||||
var entranceMode = wi % 4;
|
||||
tl.set(el, { visibility: "visible" }, w.start);
|
||||
if (entranceMode === 0) {
|
||||
tl.fromTo(
|
||||
el,
|
||||
{ y: -120, opacity: 0 },
|
||||
{ y: 0, opacity: 1, duration: 0.22, ease: "back.out(1.7)" },
|
||||
w.start,
|
||||
);
|
||||
} else if (entranceMode === 1) {
|
||||
tl.fromTo(
|
||||
el,
|
||||
{ x: -300, opacity: 0 },
|
||||
{ x: 0, opacity: 1, duration: 0.2, ease: "expo.out" },
|
||||
w.start,
|
||||
);
|
||||
} else if (entranceMode === 2) {
|
||||
tl.fromTo(
|
||||
el,
|
||||
{ x: 300, opacity: 0 },
|
||||
{ x: 0, opacity: 1, duration: 0.2, ease: "expo.out" },
|
||||
w.start,
|
||||
);
|
||||
} else {
|
||||
tl.fromTo(
|
||||
el,
|
||||
{ scale: 0.4, opacity: 0 },
|
||||
{ scale: 1, opacity: 1, duration: 0.24, ease: "back.out(2.2)" },
|
||||
w.start,
|
||||
);
|
||||
}
|
||||
|
||||
tl.to(el, { opacity: 0, duration: 0.1, ease: "power2.in" }, w.end);
|
||||
tl.set(el, { opacity: 0, visibility: "hidden" }, w.end + 0.1);
|
||||
});
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines["kinetic-slam"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+146
-108
@@ -9,35 +9,61 @@
|
||||
<link href="https://fonts.googleapis.com/css2?family=Anton&display=swap" rel="stylesheet" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#kinetic-slam {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#kt-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.kt-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.45); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#kt-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.kt-word {
|
||||
font-family: 'Anton', sans-serif;
|
||||
font-family: "Anton", sans-serif;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
color: #ffffff;
|
||||
position: absolute; left: 0; width: 100%;
|
||||
text-align: center; top: 50%;
|
||||
letter-spacing: 0.04em; line-height: 1;
|
||||
opacity: 0; visibility: hidden;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
top: 50%;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -51,107 +77,119 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="kt-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="kt-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="kt-overlay"></div>
|
||||
<div id="kt-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
function mulberry32(seed) {
|
||||
return function() {
|
||||
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
|
||||
var t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
||||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var container = document.getElementById('kt-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
WORDS.forEach(function(w, wi) {
|
||||
var el = document.createElement('div');
|
||||
el.className = 'kt-word';
|
||||
el.id = 'kt-w-' + wi;
|
||||
el.textContent = w.text.toUpperCase();
|
||||
el.style.fontSize = '220px';
|
||||
if (KEYWORDS.has(wi)) el.style.color = '#FFD700';
|
||||
container.appendChild(el);
|
||||
|
||||
gsap.set(el, { yPercent: -50 });
|
||||
|
||||
var entranceMode = wi % 4;
|
||||
tl.set(el, { visibility: 'visible' }, w.start);
|
||||
if (entranceMode === 0) {
|
||||
tl.fromTo(el,
|
||||
{ y: -120, opacity: 0 },
|
||||
{ y: 0, opacity: 1, duration: 0.22, ease: 'back.out(1.7)' },
|
||||
w.start
|
||||
);
|
||||
} else if (entranceMode === 1) {
|
||||
tl.fromTo(el,
|
||||
{ x: -300, opacity: 0 },
|
||||
{ x: 0, opacity: 1, duration: 0.2, ease: 'expo.out' },
|
||||
w.start
|
||||
);
|
||||
} else if (entranceMode === 2) {
|
||||
tl.fromTo(el,
|
||||
{ x: 300, opacity: 0 },
|
||||
{ x: 0, opacity: 1, duration: 0.2, ease: 'expo.out' },
|
||||
w.start
|
||||
);
|
||||
} else {
|
||||
tl.fromTo(el,
|
||||
{ scale: 0.4, opacity: 0 },
|
||||
{ scale: 1, opacity: 1, duration: 0.24, ease: 'back.out(2.2)' },
|
||||
w.start
|
||||
);
|
||||
function mulberry32(seed) {
|
||||
return function () {
|
||||
seed |= 0;
|
||||
seed = (seed + 0x6d2b79f5) | 0;
|
||||
var t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
|
||||
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
tl.to(el, { opacity: 0, duration: 0.1, ease: 'power2.in' }, w.end);
|
||||
tl.set(el, { opacity: 0, visibility: 'hidden' }, w.end + 0.1);
|
||||
});
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines['kinetic-slam'] = tl;
|
||||
})();
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var container = document.getElementById("kt-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
WORDS.forEach(function (w, wi) {
|
||||
var el = document.createElement("div");
|
||||
el.className = "kt-word";
|
||||
el.id = "kt-w-" + wi;
|
||||
el.textContent = w.text.toUpperCase();
|
||||
el.style.fontSize = "220px";
|
||||
if (KEYWORDS.has(wi)) el.style.color = "#FFD700";
|
||||
container.appendChild(el);
|
||||
|
||||
gsap.set(el, { yPercent: -50 });
|
||||
|
||||
var entranceMode = wi % 4;
|
||||
tl.set(el, { visibility: "visible" }, w.start);
|
||||
if (entranceMode === 0) {
|
||||
tl.fromTo(
|
||||
el,
|
||||
{ y: -120, opacity: 0 },
|
||||
{ y: 0, opacity: 1, duration: 0.22, ease: "back.out(1.7)" },
|
||||
w.start,
|
||||
);
|
||||
} else if (entranceMode === 1) {
|
||||
tl.fromTo(
|
||||
el,
|
||||
{ x: -300, opacity: 0 },
|
||||
{ x: 0, opacity: 1, duration: 0.2, ease: "expo.out" },
|
||||
w.start,
|
||||
);
|
||||
} else if (entranceMode === 2) {
|
||||
tl.fromTo(
|
||||
el,
|
||||
{ x: 300, opacity: 0 },
|
||||
{ x: 0, opacity: 1, duration: 0.2, ease: "expo.out" },
|
||||
w.start,
|
||||
);
|
||||
} else {
|
||||
tl.fromTo(
|
||||
el,
|
||||
{ scale: 0.4, opacity: 0 },
|
||||
{ scale: 1, opacity: 1, duration: 0.24, ease: "back.out(2.2)" },
|
||||
w.start,
|
||||
);
|
||||
}
|
||||
|
||||
tl.to(el, { opacity: 0, duration: 0.1, ease: "power2.in" }, w.end);
|
||||
tl.set(el, { opacity: 0, visibility: "hidden" }, w.end + 0.1);
|
||||
});
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines["kinetic-slam"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+189
-140
@@ -6,45 +6,86 @@
|
||||
<title>Matrix Decode</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #000;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
#matrix-decode {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #000;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
#sc-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.sc-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.85); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#sc-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.sc-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 80px;
|
||||
opacity: 0; visibility: hidden;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 80px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.sc-word-wrap {
|
||||
font-family: 'Space Grotesk', sans-serif;
|
||||
font-weight: 700; font-size: 96px;
|
||||
color: #00FF41;
|
||||
display: inline-block; letter-spacing: 0.04em; line-height: 1; position: relative;
|
||||
font-family: "Space Grotesk", sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 96px;
|
||||
color: #00ff41;
|
||||
display: inline-block;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
}
|
||||
.sc-real {
|
||||
display: none;
|
||||
}
|
||||
.sc-scr0 {
|
||||
display: none;
|
||||
}
|
||||
.sc-scr1 {
|
||||
display: none;
|
||||
}
|
||||
.sc-real { display: none; }
|
||||
.sc-scr0 { display: none; }
|
||||
.sc-scr1 { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -57,141 +98,149 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="sc-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="sc-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="sc-overlay"></div>
|
||||
<div id="sc-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
function mulberry32(seed) {
|
||||
return function() {
|
||||
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
|
||||
var t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
||||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
var ALPHANUM = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
|
||||
function scrambleChars(seed) {
|
||||
var rng = mulberry32(seed);
|
||||
var result = '';
|
||||
for (var i = 0; i < 4; i++) {
|
||||
result += ALPHANUM[Math.floor(rng() * ALPHANUM.length)];
|
||||
function mulberry32(seed) {
|
||||
return function () {
|
||||
seed |= 0;
|
||||
seed = (seed + 0x6d2b79f5) | 0;
|
||||
var t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
|
||||
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var ALPHANUM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
var GROUPS = [
|
||||
{wordStart:0, wordEnd:3, start:0.0, end:1.05},
|
||||
{wordStart:4, wordEnd:7, start:1.1, end:2.05},
|
||||
{wordStart:8, wordEnd:8, start:2.1, end:2.6},
|
||||
{wordStart:9, wordEnd:12, start:2.65, end:3.5},
|
||||
{wordStart:13, wordEnd:15, start:3.55, end:4.4},
|
||||
{wordStart:16, wordEnd:16, start:3.95, end:4.75},
|
||||
{wordStart:17, wordEnd:19, start:4.9, end:5.4},
|
||||
{wordStart:20, wordEnd:22, start:5.65, end:6.2},
|
||||
{wordStart:23, wordEnd:24, start:6.35, end:6.75},
|
||||
{wordStart:25, wordEnd:27, start:6.8, end:7.8},
|
||||
];
|
||||
function scrambleChars(seed) {
|
||||
var rng = mulberry32(seed);
|
||||
var result = "";
|
||||
for (var i = 0; i < 4; i++) {
|
||||
result += ALPHANUM[Math.floor(rng() * ALPHANUM.length)];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var container = document.getElementById('sc-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'sc-group';
|
||||
grp.id = 'sc-grp-' + gi;
|
||||
var GROUPS = [
|
||||
{ wordStart: 0, wordEnd: 3, start: 0.0, end: 1.05 },
|
||||
{ wordStart: 4, wordEnd: 7, start: 1.1, end: 2.05 },
|
||||
{ wordStart: 8, wordEnd: 8, start: 2.1, end: 2.6 },
|
||||
{ wordStart: 9, wordEnd: 12, start: 2.65, end: 3.5 },
|
||||
{ wordStart: 13, wordEnd: 15, start: 3.55, end: 4.4 },
|
||||
{ wordStart: 16, wordEnd: 16, start: 3.95, end: 4.75 },
|
||||
{ wordStart: 17, wordEnd: 19, start: 4.9, end: 5.4 },
|
||||
{ wordStart: 20, wordEnd: 22, start: 5.65, end: 6.2 },
|
||||
{ wordStart: 23, wordEnd: 24, start: 6.35, end: 6.75 },
|
||||
{ wordStart: 25, wordEnd: 27, start: 6.8, end: 7.8 },
|
||||
];
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordWrap = document.createElement('span');
|
||||
wordWrap.className = 'sc-word-wrap';
|
||||
wordWrap.id = 'sc-ww-' + wi;
|
||||
wordWrap.style.fontSize = '96px';
|
||||
var container = document.getElementById("sc-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
var real = document.createElement('span');
|
||||
real.className = 'sc-real';
|
||||
real.id = 'sc-real-' + wi;
|
||||
real.textContent = w.text;
|
||||
wordWrap.appendChild(real);
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "sc-group";
|
||||
grp.id = "sc-grp-" + gi;
|
||||
|
||||
var scr0 = document.createElement('span');
|
||||
scr0.className = 'sc-scr0';
|
||||
scr0.id = 'sc-scr0-' + wi;
|
||||
scr0.textContent = scrambleChars(wi * 1000 + 0);
|
||||
wordWrap.appendChild(scr0);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordWrap = document.createElement("span");
|
||||
wordWrap.className = "sc-word-wrap";
|
||||
wordWrap.id = "sc-ww-" + wi;
|
||||
wordWrap.style.fontSize = "96px";
|
||||
|
||||
var scr1 = document.createElement('span');
|
||||
scr1.className = 'sc-scr1';
|
||||
scr1.id = 'sc-scr1-' + wi;
|
||||
scr1.textContent = scrambleChars(wi * 1000 + 1);
|
||||
wordWrap.appendChild(scr1);
|
||||
var real = document.createElement("span");
|
||||
real.className = "sc-real";
|
||||
real.id = "sc-real-" + wi;
|
||||
real.textContent = w.text;
|
||||
wordWrap.appendChild(real);
|
||||
|
||||
grp.appendChild(wordWrap);
|
||||
var scr0 = document.createElement("span");
|
||||
scr0.className = "sc-scr0";
|
||||
scr0.id = "sc-scr0-" + wi;
|
||||
scr0.textContent = scrambleChars(wi * 1000 + 0);
|
||||
wordWrap.appendChild(scr0);
|
||||
|
||||
var scr1 = document.createElement("span");
|
||||
scr1.className = "sc-scr1";
|
||||
scr1.id = "sc-scr1-" + wi;
|
||||
scr1.textContent = scrambleChars(wi * 1000 + 1);
|
||||
wordWrap.appendChild(scr1);
|
||||
|
||||
grp.appendChild(wordWrap);
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
|
||||
tl.set(grp, { visibility: "visible", opacity: 0 }, g.start);
|
||||
tl.fromTo(grp, { opacity: 0 }, { opacity: 1, duration: 0.1 }, g.start);
|
||||
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var realEl = document.getElementById("sc-real-" + wi);
|
||||
var scr0El = document.getElementById("sc-scr0-" + wi);
|
||||
var scr1El = document.getElementById("sc-scr1-" + wi);
|
||||
|
||||
tl.set(scr0El, { display: "inline" }, w.start);
|
||||
tl.set(scr1El, { display: "inline" }, w.start + 0.05);
|
||||
tl.set(scr0El, { display: "none" }, w.start + 0.05);
|
||||
tl.set(realEl, { display: "inline" }, w.start + 0.1);
|
||||
tl.set(scr1El, { display: "none" }, w.start + 0.1);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, duration: 0.12 }, g.end - 0.12);
|
||||
tl.set(grp, { opacity: 0, visibility: "hidden" }, g.end);
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
|
||||
tl.set(grp, { visibility: 'visible', opacity: 0 }, g.start);
|
||||
tl.fromTo(grp, { opacity: 0 }, { opacity: 1, duration: 0.1 }, g.start);
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var realEl = document.getElementById('sc-real-' + wi);
|
||||
var scr0El = document.getElementById('sc-scr0-' + wi);
|
||||
var scr1El = document.getElementById('sc-scr1-' + wi);
|
||||
|
||||
tl.set(scr0El, { display: 'inline' }, w.start);
|
||||
tl.set(scr1El, { display: 'inline' }, w.start + 0.05);
|
||||
tl.set(scr0El, { display: 'none' }, w.start + 0.05);
|
||||
tl.set(realEl, { display: 'inline' }, w.start + 0.1);
|
||||
tl.set(scr1El, { display: 'none' }, w.start + 0.1);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, duration: 0.12 }, g.end - 0.12);
|
||||
tl.set(grp, { opacity: 0, visibility: 'hidden' }, g.end);
|
||||
});
|
||||
|
||||
window.__timelines['matrix-decode'] = tl;
|
||||
})();
|
||||
window.__timelines["matrix-decode"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+189
-140
@@ -6,45 +6,86 @@
|
||||
<title>Matrix Decode</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #000;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
#matrix-decode {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #000;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
#sc-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.sc-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.85); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#sc-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.sc-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 80px;
|
||||
opacity: 0; visibility: hidden;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 80px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.sc-word-wrap {
|
||||
font-family: 'Space Grotesk', sans-serif;
|
||||
font-weight: 700; font-size: 96px;
|
||||
color: #00FF41;
|
||||
display: inline-block; letter-spacing: 0.04em; line-height: 1; position: relative;
|
||||
font-family: "Space Grotesk", sans-serif;
|
||||
font-weight: 700;
|
||||
font-size: 96px;
|
||||
color: #00ff41;
|
||||
display: inline-block;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
}
|
||||
.sc-real {
|
||||
display: none;
|
||||
}
|
||||
.sc-scr0 {
|
||||
display: none;
|
||||
}
|
||||
.sc-scr1 {
|
||||
display: none;
|
||||
}
|
||||
.sc-real { display: none; }
|
||||
.sc-scr0 { display: none; }
|
||||
.sc-scr1 { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -57,141 +98,149 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="sc-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="sc-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="sc-overlay"></div>
|
||||
<div id="sc-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
function mulberry32(seed) {
|
||||
return function() {
|
||||
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
|
||||
var t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
||||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
var ALPHANUM = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
|
||||
function scrambleChars(seed) {
|
||||
var rng = mulberry32(seed);
|
||||
var result = '';
|
||||
for (var i = 0; i < 4; i++) {
|
||||
result += ALPHANUM[Math.floor(rng() * ALPHANUM.length)];
|
||||
function mulberry32(seed) {
|
||||
return function () {
|
||||
seed |= 0;
|
||||
seed = (seed + 0x6d2b79f5) | 0;
|
||||
var t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
|
||||
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var ALPHANUM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
var GROUPS = [
|
||||
{wordStart:0, wordEnd:3, start:0.0, end:1.05},
|
||||
{wordStart:4, wordEnd:7, start:1.1, end:2.05},
|
||||
{wordStart:8, wordEnd:8, start:2.1, end:2.6},
|
||||
{wordStart:9, wordEnd:12, start:2.65, end:3.5},
|
||||
{wordStart:13, wordEnd:15, start:3.55, end:4.4},
|
||||
{wordStart:16, wordEnd:16, start:3.95, end:4.75},
|
||||
{wordStart:17, wordEnd:19, start:4.9, end:5.4},
|
||||
{wordStart:20, wordEnd:22, start:5.65, end:6.2},
|
||||
{wordStart:23, wordEnd:24, start:6.35, end:6.75},
|
||||
{wordStart:25, wordEnd:27, start:6.8, end:7.8},
|
||||
];
|
||||
function scrambleChars(seed) {
|
||||
var rng = mulberry32(seed);
|
||||
var result = "";
|
||||
for (var i = 0; i < 4; i++) {
|
||||
result += ALPHANUM[Math.floor(rng() * ALPHANUM.length)];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var container = document.getElementById('sc-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'sc-group';
|
||||
grp.id = 'sc-grp-' + gi;
|
||||
var GROUPS = [
|
||||
{ wordStart: 0, wordEnd: 3, start: 0.0, end: 1.05 },
|
||||
{ wordStart: 4, wordEnd: 7, start: 1.1, end: 2.05 },
|
||||
{ wordStart: 8, wordEnd: 8, start: 2.1, end: 2.6 },
|
||||
{ wordStart: 9, wordEnd: 12, start: 2.65, end: 3.5 },
|
||||
{ wordStart: 13, wordEnd: 15, start: 3.55, end: 4.4 },
|
||||
{ wordStart: 16, wordEnd: 16, start: 3.95, end: 4.75 },
|
||||
{ wordStart: 17, wordEnd: 19, start: 4.9, end: 5.4 },
|
||||
{ wordStart: 20, wordEnd: 22, start: 5.65, end: 6.2 },
|
||||
{ wordStart: 23, wordEnd: 24, start: 6.35, end: 6.75 },
|
||||
{ wordStart: 25, wordEnd: 27, start: 6.8, end: 7.8 },
|
||||
];
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordWrap = document.createElement('span');
|
||||
wordWrap.className = 'sc-word-wrap';
|
||||
wordWrap.id = 'sc-ww-' + wi;
|
||||
wordWrap.style.fontSize = '96px';
|
||||
var container = document.getElementById("sc-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
var real = document.createElement('span');
|
||||
real.className = 'sc-real';
|
||||
real.id = 'sc-real-' + wi;
|
||||
real.textContent = w.text;
|
||||
wordWrap.appendChild(real);
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "sc-group";
|
||||
grp.id = "sc-grp-" + gi;
|
||||
|
||||
var scr0 = document.createElement('span');
|
||||
scr0.className = 'sc-scr0';
|
||||
scr0.id = 'sc-scr0-' + wi;
|
||||
scr0.textContent = scrambleChars(wi * 1000 + 0);
|
||||
wordWrap.appendChild(scr0);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordWrap = document.createElement("span");
|
||||
wordWrap.className = "sc-word-wrap";
|
||||
wordWrap.id = "sc-ww-" + wi;
|
||||
wordWrap.style.fontSize = "96px";
|
||||
|
||||
var scr1 = document.createElement('span');
|
||||
scr1.className = 'sc-scr1';
|
||||
scr1.id = 'sc-scr1-' + wi;
|
||||
scr1.textContent = scrambleChars(wi * 1000 + 1);
|
||||
wordWrap.appendChild(scr1);
|
||||
var real = document.createElement("span");
|
||||
real.className = "sc-real";
|
||||
real.id = "sc-real-" + wi;
|
||||
real.textContent = w.text;
|
||||
wordWrap.appendChild(real);
|
||||
|
||||
grp.appendChild(wordWrap);
|
||||
var scr0 = document.createElement("span");
|
||||
scr0.className = "sc-scr0";
|
||||
scr0.id = "sc-scr0-" + wi;
|
||||
scr0.textContent = scrambleChars(wi * 1000 + 0);
|
||||
wordWrap.appendChild(scr0);
|
||||
|
||||
var scr1 = document.createElement("span");
|
||||
scr1.className = "sc-scr1";
|
||||
scr1.id = "sc-scr1-" + wi;
|
||||
scr1.textContent = scrambleChars(wi * 1000 + 1);
|
||||
wordWrap.appendChild(scr1);
|
||||
|
||||
grp.appendChild(wordWrap);
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
|
||||
tl.set(grp, { visibility: "visible", opacity: 0 }, g.start);
|
||||
tl.fromTo(grp, { opacity: 0 }, { opacity: 1, duration: 0.1 }, g.start);
|
||||
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var realEl = document.getElementById("sc-real-" + wi);
|
||||
var scr0El = document.getElementById("sc-scr0-" + wi);
|
||||
var scr1El = document.getElementById("sc-scr1-" + wi);
|
||||
|
||||
tl.set(scr0El, { display: "inline" }, w.start);
|
||||
tl.set(scr1El, { display: "inline" }, w.start + 0.05);
|
||||
tl.set(scr0El, { display: "none" }, w.start + 0.05);
|
||||
tl.set(realEl, { display: "inline" }, w.start + 0.1);
|
||||
tl.set(scr1El, { display: "none" }, w.start + 0.1);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, duration: 0.12 }, g.end - 0.12);
|
||||
tl.set(grp, { opacity: 0, visibility: "hidden" }, g.end);
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
|
||||
tl.set(grp, { visibility: 'visible', opacity: 0 }, g.start);
|
||||
tl.fromTo(grp, { opacity: 0 }, { opacity: 1, duration: 0.1 }, g.start);
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var realEl = document.getElementById('sc-real-' + wi);
|
||||
var scr0El = document.getElementById('sc-scr0-' + wi);
|
||||
var scr1El = document.getElementById('sc-scr1-' + wi);
|
||||
|
||||
tl.set(scr0El, { display: 'inline' }, w.start);
|
||||
tl.set(scr1El, { display: 'inline' }, w.start + 0.05);
|
||||
tl.set(scr0El, { display: 'none' }, w.start + 0.05);
|
||||
tl.set(realEl, { display: 'inline' }, w.start + 0.1);
|
||||
tl.set(scr1El, { display: 'none' }, w.start + 0.1);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, duration: 0.12 }, g.end - 0.12);
|
||||
tl.set(grp, { opacity: 0, visibility: 'hidden' }, g.end);
|
||||
});
|
||||
|
||||
window.__timelines['matrix-decode'] = tl;
|
||||
})();
|
||||
window.__timelines["matrix-decode"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+186
-57
@@ -6,7 +6,10 @@
|
||||
<title>Neon Accent</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@800&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@800&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*,
|
||||
@@ -154,44 +157,94 @@
|
||||
var PRIMARY_COLOR = "#FFFFFF";
|
||||
var ACCENT_COLORS = ["#53FF01", "#FF0002", "#FCFF00"];
|
||||
var TRANSITION_WORDS = new Set([
|
||||
"the", "a", "an", "and", "or", "but", "is", "are", "was", "were",
|
||||
"to", "of", "in", "on", "at", "for", "with", "by", "from", "as",
|
||||
"it", "its", "this", "that", "these", "those", "be", "been",
|
||||
"have", "has", "had", "do", "does", "did", "will", "would", "could",
|
||||
"should", "may", "might", "must", "can", "if", "then", "so", "just",
|
||||
"not", "no", "yes", "up", "out", "about", "lets", "you", "write", "render"
|
||||
"the",
|
||||
"a",
|
||||
"an",
|
||||
"and",
|
||||
"or",
|
||||
"but",
|
||||
"is",
|
||||
"are",
|
||||
"was",
|
||||
"were",
|
||||
"to",
|
||||
"of",
|
||||
"in",
|
||||
"on",
|
||||
"at",
|
||||
"for",
|
||||
"with",
|
||||
"by",
|
||||
"from",
|
||||
"as",
|
||||
"it",
|
||||
"its",
|
||||
"this",
|
||||
"that",
|
||||
"these",
|
||||
"those",
|
||||
"be",
|
||||
"been",
|
||||
"have",
|
||||
"has",
|
||||
"had",
|
||||
"do",
|
||||
"does",
|
||||
"did",
|
||||
"will",
|
||||
"would",
|
||||
"could",
|
||||
"should",
|
||||
"may",
|
||||
"might",
|
||||
"must",
|
||||
"can",
|
||||
"if",
|
||||
"then",
|
||||
"so",
|
||||
"just",
|
||||
"not",
|
||||
"no",
|
||||
"yes",
|
||||
"up",
|
||||
"out",
|
||||
"about",
|
||||
"lets",
|
||||
"you",
|
||||
"write",
|
||||
"render",
|
||||
]);
|
||||
var KEYWORDS = new Set(["hyperframes", "html", "professional", "code", "cinema"]);
|
||||
|
||||
var TRANSCRIPT = [
|
||||
{"text": "Every", "start": 0.0, "end": 0.3},
|
||||
{"text": "great", "start": 0.3, "end": 0.55},
|
||||
{"text": "video", "start": 0.55, "end": 0.85},
|
||||
{"text": "starts", "start": 0.85, "end": 1.1},
|
||||
{"text": "with", "start": 1.1, "end": 1.25},
|
||||
{"text": "a", "start": 1.25, "end": 1.35},
|
||||
{"text": "single", "start": 1.35, "end": 1.65},
|
||||
{"text": "frame.", "start": 1.65, "end": 2.0},
|
||||
{"text": "HyperFrames", "start": 2.1, "end": 2.65},
|
||||
{"text": "lets", "start": 2.65, "end": 2.85},
|
||||
{"text": "you", "start": 2.85, "end": 2.95},
|
||||
{"text": "write", "start": 2.95, "end": 3.15},
|
||||
{"text": "HTML", "start": 3.15, "end": 3.55},
|
||||
{"text": "and", "start": 3.55, "end": 3.65},
|
||||
{"text": "render", "start": 3.65, "end": 3.95},
|
||||
{"text": "professional", "start": 3.95, "end": 4.45},
|
||||
{"text": "video.", "start": 4.45, "end": 4.8},
|
||||
{"text": "No", "start": 4.9, "end": 5.05},
|
||||
{"text": "timeline.", "start": 5.05, "end": 5.45},
|
||||
{"text": "No", "start": 5.5, "end": 5.65},
|
||||
{"text": "drag", "start": 5.65, "end": 5.85},
|
||||
{"text": "and", "start": 5.85, "end": 5.95},
|
||||
{"text": "drop.", "start": 5.95, "end": 6.25},
|
||||
{"text": "Just", "start": 6.35, "end": 6.55},
|
||||
{"text": "code", "start": 6.55, "end": 6.8},
|
||||
{"text": "that", "start": 6.8, "end": 6.95},
|
||||
{"text": "becomes", "start": 6.95, "end": 7.3},
|
||||
{"text": "cinema.", "start": 7.3, "end": 7.7}
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
gsap.registerPlugin && gsap.registerPlugin();
|
||||
@@ -201,13 +254,17 @@
|
||||
}
|
||||
|
||||
function normalizeWords(rawWords) {
|
||||
return rawWords.map(function (item) {
|
||||
return {
|
||||
text: cleanText(item.word || item.text),
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
};
|
||||
}).filter(function (word) { return word.text.length > 0; });
|
||||
return rawWords
|
||||
.map(function (item) {
|
||||
return {
|
||||
text: cleanText(item.word || item.text),
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
};
|
||||
})
|
||||
.filter(function (word) {
|
||||
return word.text.length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
var measureCanvas = document.createElement("canvas");
|
||||
@@ -247,24 +304,42 @@
|
||||
|
||||
function measureLineWidth(words, colors, fontSize) {
|
||||
return words.reduce(function (total, word, index) {
|
||||
return total + measureWord(word, colors[index] || PRIMARY_COLOR, fontSize) + (index ? WORD_SPACING : 0);
|
||||
return (
|
||||
total +
|
||||
measureWord(word, colors[index] || PRIMARY_COLOR, fontSize) +
|
||||
(index ? WORD_SPACING : 0)
|
||||
);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function splitLinesForGroup(words, colors, fontSize) {
|
||||
var maxLineWidth = SAFE_ZONE_WIDTH;
|
||||
if (words.some(function (word, i) { return measureWord(word, colors[i] || PRIMARY_COLOR, fontSize) > maxLineWidth; })) return null;
|
||||
if (measureLineWidth(words, colors, fontSize) <= maxLineWidth) return [{ words: words, colors: colors }];
|
||||
if (
|
||||
words.some(function (word, i) {
|
||||
return measureWord(word, colors[i] || PRIMARY_COLOR, fontSize) > maxLineWidth;
|
||||
})
|
||||
)
|
||||
return null;
|
||||
if (measureLineWidth(words, colors, fontSize) <= maxLineWidth)
|
||||
return [{ words: words, colors: colors }];
|
||||
var best = null;
|
||||
var bestDiff = Infinity;
|
||||
for (var split = 1; split < words.length; split++) {
|
||||
var fw = words.slice(0, split), sw = words.slice(split);
|
||||
var fc = colors.slice(0, split), sc = colors.slice(split);
|
||||
var fw = words.slice(0, split),
|
||||
sw = words.slice(split);
|
||||
var fc = colors.slice(0, split),
|
||||
sc = colors.slice(split);
|
||||
var fW = measureLineWidth(fw, fc, fontSize);
|
||||
var sW = measureLineWidth(sw, sc, fontSize);
|
||||
if (fW <= maxLineWidth && sW <= maxLineWidth) {
|
||||
var diff = Math.abs(fW - sW);
|
||||
if (diff < bestDiff) { best = [{ words: fw, colors: fc }, { words: sw, colors: sc }]; bestDiff = diff; }
|
||||
if (diff < bestDiff) {
|
||||
best = [
|
||||
{ words: fw, colors: fc },
|
||||
{ words: sw, colors: sc },
|
||||
];
|
||||
bestDiff = diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best;
|
||||
@@ -287,7 +362,12 @@
|
||||
current.push(word);
|
||||
var punctuation = /[,.:!?]$/.test(word.text);
|
||||
var pause = nextWord ? nextWord.start - word.end : 0;
|
||||
if (!nextWord || punctuation || pause >= PAUSE_THRESHOLD || current.length >= MAX_WORDS_PER_GROUP) {
|
||||
if (
|
||||
!nextWord ||
|
||||
punctuation ||
|
||||
pause >= PAUSE_THRESHOLD ||
|
||||
current.length >= MAX_WORDS_PER_GROUP
|
||||
) {
|
||||
groups.push(makeGroup(current, groups.length));
|
||||
current = [];
|
||||
}
|
||||
@@ -299,11 +379,16 @@
|
||||
function makeGroup(words, groupIndex) {
|
||||
var colors = assignWordColors(words, groupIndex);
|
||||
var fontSize = BASE_FONT_SIZE;
|
||||
while (fontSize > MIN_FONT_SIZE && !splitLinesForGroup(words, colors, fontSize)) { fontSize -= 2; }
|
||||
while (fontSize > MIN_FONT_SIZE && !splitLinesForGroup(words, colors, fontSize)) {
|
||||
fontSize -= 2;
|
||||
}
|
||||
return {
|
||||
words: words.slice(), colors: colors, fontSize: fontSize,
|
||||
words: words.slice(),
|
||||
colors: colors,
|
||||
fontSize: fontSize,
|
||||
lines: splitLinesForGroup(words, colors, fontSize) || [{ words: words, colors: colors }],
|
||||
start: words[0].start, end: words[words.length - 1].end,
|
||||
start: words[0].start,
|
||||
end: words[words.length - 1].end,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -312,7 +397,32 @@
|
||||
var r = parseInt(hex.slice(0, 2), 16);
|
||||
var g = parseInt(hex.slice(2, 4), 16);
|
||||
var b = parseInt(hex.slice(4, 6), 16);
|
||||
var glow = "0 0 4px rgba(" + r + "," + g + "," + b + ",1), 0 0 10px rgba(" + r + "," + g + "," + b + ",0.9), 0 0 20px rgba(" + r + "," + g + "," + b + ",0.7), 0 0 40px rgba(" + r + "," + g + "," + b + ",0.4)";
|
||||
var glow =
|
||||
"0 0 4px rgba(" +
|
||||
r +
|
||||
"," +
|
||||
g +
|
||||
"," +
|
||||
b +
|
||||
",1), 0 0 10px rgba(" +
|
||||
r +
|
||||
"," +
|
||||
g +
|
||||
"," +
|
||||
b +
|
||||
",0.9), 0 0 20px rgba(" +
|
||||
r +
|
||||
"," +
|
||||
g +
|
||||
"," +
|
||||
b +
|
||||
",0.7), 0 0 40px rgba(" +
|
||||
r +
|
||||
"," +
|
||||
g +
|
||||
"," +
|
||||
b +
|
||||
",0.4)";
|
||||
return "0 8px 16px rgba(0,0,0,0.8), 0 16px 40px rgba(0,0,0,0.6), " + glow;
|
||||
}
|
||||
|
||||
@@ -333,7 +443,8 @@
|
||||
wordEl.className = color === PRIMARY_COLOR ? "caption-word" : "caption-word accent";
|
||||
wordEl.textContent = word.text.toUpperCase();
|
||||
wordEl.style.color = color;
|
||||
wordEl.style.fontSize = color === PRIMARY_COLOR ? group.fontSize + "px" : group.fontSize * 1.2 + "px";
|
||||
wordEl.style.fontSize =
|
||||
color === PRIMARY_COLOR ? group.fontSize + "px" : group.fontSize * 1.2 + "px";
|
||||
wordEl.style.textShadow = shadowForColor(color);
|
||||
lineEl.appendChild(wordEl);
|
||||
});
|
||||
@@ -358,7 +469,9 @@
|
||||
return Math.max(0, group.start - entryLead);
|
||||
});
|
||||
|
||||
var allGroupEls = GROUPS.map(function (_, i) { return document.getElementById("caption-group-" + i); });
|
||||
var allGroupEls = GROUPS.map(function (_, i) {
|
||||
return document.getElementById("caption-group-" + i);
|
||||
});
|
||||
|
||||
GROUPS.forEach(function (group, groupIndex) {
|
||||
var groupEl = allGroupEls[groupIndex];
|
||||
@@ -373,8 +486,24 @@
|
||||
});
|
||||
|
||||
tl.set(groupEl, { opacity: 0, scale: 0.65, x: 0, y: 0 }, visibleStart);
|
||||
tl.to(groupEl, { opacity: 1, scale: 1, duration: ENTRY_DURATION, ease: "power3.out", force3D: true }, visibleStart);
|
||||
tl.to(groupEl, { x: D, y: D, duration: WIGGLE_CYCLE / 2, ease: "sine.inOut", yoyo: true, repeat: Math.max(0, wiggleCycles * 2 - 1), force3D: true }, visibleStart);
|
||||
tl.to(
|
||||
groupEl,
|
||||
{ opacity: 1, scale: 1, duration: ENTRY_DURATION, ease: "power3.out", force3D: true },
|
||||
visibleStart,
|
||||
);
|
||||
tl.to(
|
||||
groupEl,
|
||||
{
|
||||
x: D,
|
||||
y: D,
|
||||
duration: WIGGLE_CYCLE / 2,
|
||||
ease: "sine.inOut",
|
||||
yoyo: true,
|
||||
repeat: Math.max(0, wiggleCycles * 2 - 1),
|
||||
force3D: true,
|
||||
},
|
||||
visibleStart,
|
||||
);
|
||||
tl.set(groupEl, { opacity: 0 }, visibleEnd);
|
||||
});
|
||||
|
||||
|
||||
+186
-57
@@ -6,7 +6,10 @@
|
||||
<title>Neon Accent</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@800&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@800&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*,
|
||||
@@ -154,44 +157,94 @@
|
||||
var PRIMARY_COLOR = "#FFFFFF";
|
||||
var ACCENT_COLORS = ["#53FF01", "#FF0002", "#FCFF00"];
|
||||
var TRANSITION_WORDS = new Set([
|
||||
"the", "a", "an", "and", "or", "but", "is", "are", "was", "were",
|
||||
"to", "of", "in", "on", "at", "for", "with", "by", "from", "as",
|
||||
"it", "its", "this", "that", "these", "those", "be", "been",
|
||||
"have", "has", "had", "do", "does", "did", "will", "would", "could",
|
||||
"should", "may", "might", "must", "can", "if", "then", "so", "just",
|
||||
"not", "no", "yes", "up", "out", "about", "lets", "you", "write", "render"
|
||||
"the",
|
||||
"a",
|
||||
"an",
|
||||
"and",
|
||||
"or",
|
||||
"but",
|
||||
"is",
|
||||
"are",
|
||||
"was",
|
||||
"were",
|
||||
"to",
|
||||
"of",
|
||||
"in",
|
||||
"on",
|
||||
"at",
|
||||
"for",
|
||||
"with",
|
||||
"by",
|
||||
"from",
|
||||
"as",
|
||||
"it",
|
||||
"its",
|
||||
"this",
|
||||
"that",
|
||||
"these",
|
||||
"those",
|
||||
"be",
|
||||
"been",
|
||||
"have",
|
||||
"has",
|
||||
"had",
|
||||
"do",
|
||||
"does",
|
||||
"did",
|
||||
"will",
|
||||
"would",
|
||||
"could",
|
||||
"should",
|
||||
"may",
|
||||
"might",
|
||||
"must",
|
||||
"can",
|
||||
"if",
|
||||
"then",
|
||||
"so",
|
||||
"just",
|
||||
"not",
|
||||
"no",
|
||||
"yes",
|
||||
"up",
|
||||
"out",
|
||||
"about",
|
||||
"lets",
|
||||
"you",
|
||||
"write",
|
||||
"render",
|
||||
]);
|
||||
var KEYWORDS = new Set(["hyperframes", "html", "professional", "code", "cinema"]);
|
||||
|
||||
var TRANSCRIPT = [
|
||||
{"text": "Every", "start": 0.0, "end": 0.3},
|
||||
{"text": "great", "start": 0.3, "end": 0.55},
|
||||
{"text": "video", "start": 0.55, "end": 0.85},
|
||||
{"text": "starts", "start": 0.85, "end": 1.1},
|
||||
{"text": "with", "start": 1.1, "end": 1.25},
|
||||
{"text": "a", "start": 1.25, "end": 1.35},
|
||||
{"text": "single", "start": 1.35, "end": 1.65},
|
||||
{"text": "frame.", "start": 1.65, "end": 2.0},
|
||||
{"text": "HyperFrames", "start": 2.1, "end": 2.65},
|
||||
{"text": "lets", "start": 2.65, "end": 2.85},
|
||||
{"text": "you", "start": 2.85, "end": 2.95},
|
||||
{"text": "write", "start": 2.95, "end": 3.15},
|
||||
{"text": "HTML", "start": 3.15, "end": 3.55},
|
||||
{"text": "and", "start": 3.55, "end": 3.65},
|
||||
{"text": "render", "start": 3.65, "end": 3.95},
|
||||
{"text": "professional", "start": 3.95, "end": 4.45},
|
||||
{"text": "video.", "start": 4.45, "end": 4.8},
|
||||
{"text": "No", "start": 4.9, "end": 5.05},
|
||||
{"text": "timeline.", "start": 5.05, "end": 5.45},
|
||||
{"text": "No", "start": 5.5, "end": 5.65},
|
||||
{"text": "drag", "start": 5.65, "end": 5.85},
|
||||
{"text": "and", "start": 5.85, "end": 5.95},
|
||||
{"text": "drop.", "start": 5.95, "end": 6.25},
|
||||
{"text": "Just", "start": 6.35, "end": 6.55},
|
||||
{"text": "code", "start": 6.55, "end": 6.8},
|
||||
{"text": "that", "start": 6.8, "end": 6.95},
|
||||
{"text": "becomes", "start": 6.95, "end": 7.3},
|
||||
{"text": "cinema.", "start": 7.3, "end": 7.7}
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
gsap.registerPlugin && gsap.registerPlugin();
|
||||
@@ -201,13 +254,17 @@
|
||||
}
|
||||
|
||||
function normalizeWords(rawWords) {
|
||||
return rawWords.map(function (item) {
|
||||
return {
|
||||
text: cleanText(item.word || item.text),
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
};
|
||||
}).filter(function (word) { return word.text.length > 0; });
|
||||
return rawWords
|
||||
.map(function (item) {
|
||||
return {
|
||||
text: cleanText(item.word || item.text),
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
};
|
||||
})
|
||||
.filter(function (word) {
|
||||
return word.text.length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
var measureCanvas = document.createElement("canvas");
|
||||
@@ -247,24 +304,42 @@
|
||||
|
||||
function measureLineWidth(words, colors, fontSize) {
|
||||
return words.reduce(function (total, word, index) {
|
||||
return total + measureWord(word, colors[index] || PRIMARY_COLOR, fontSize) + (index ? WORD_SPACING : 0);
|
||||
return (
|
||||
total +
|
||||
measureWord(word, colors[index] || PRIMARY_COLOR, fontSize) +
|
||||
(index ? WORD_SPACING : 0)
|
||||
);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function splitLinesForGroup(words, colors, fontSize) {
|
||||
var maxLineWidth = SAFE_ZONE_WIDTH;
|
||||
if (words.some(function (word, i) { return measureWord(word, colors[i] || PRIMARY_COLOR, fontSize) > maxLineWidth; })) return null;
|
||||
if (measureLineWidth(words, colors, fontSize) <= maxLineWidth) return [{ words: words, colors: colors }];
|
||||
if (
|
||||
words.some(function (word, i) {
|
||||
return measureWord(word, colors[i] || PRIMARY_COLOR, fontSize) > maxLineWidth;
|
||||
})
|
||||
)
|
||||
return null;
|
||||
if (measureLineWidth(words, colors, fontSize) <= maxLineWidth)
|
||||
return [{ words: words, colors: colors }];
|
||||
var best = null;
|
||||
var bestDiff = Infinity;
|
||||
for (var split = 1; split < words.length; split++) {
|
||||
var fw = words.slice(0, split), sw = words.slice(split);
|
||||
var fc = colors.slice(0, split), sc = colors.slice(split);
|
||||
var fw = words.slice(0, split),
|
||||
sw = words.slice(split);
|
||||
var fc = colors.slice(0, split),
|
||||
sc = colors.slice(split);
|
||||
var fW = measureLineWidth(fw, fc, fontSize);
|
||||
var sW = measureLineWidth(sw, sc, fontSize);
|
||||
if (fW <= maxLineWidth && sW <= maxLineWidth) {
|
||||
var diff = Math.abs(fW - sW);
|
||||
if (diff < bestDiff) { best = [{ words: fw, colors: fc }, { words: sw, colors: sc }]; bestDiff = diff; }
|
||||
if (diff < bestDiff) {
|
||||
best = [
|
||||
{ words: fw, colors: fc },
|
||||
{ words: sw, colors: sc },
|
||||
];
|
||||
bestDiff = diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best;
|
||||
@@ -287,7 +362,12 @@
|
||||
current.push(word);
|
||||
var punctuation = /[,.:!?]$/.test(word.text);
|
||||
var pause = nextWord ? nextWord.start - word.end : 0;
|
||||
if (!nextWord || punctuation || pause >= PAUSE_THRESHOLD || current.length >= MAX_WORDS_PER_GROUP) {
|
||||
if (
|
||||
!nextWord ||
|
||||
punctuation ||
|
||||
pause >= PAUSE_THRESHOLD ||
|
||||
current.length >= MAX_WORDS_PER_GROUP
|
||||
) {
|
||||
groups.push(makeGroup(current, groups.length));
|
||||
current = [];
|
||||
}
|
||||
@@ -299,11 +379,16 @@
|
||||
function makeGroup(words, groupIndex) {
|
||||
var colors = assignWordColors(words, groupIndex);
|
||||
var fontSize = BASE_FONT_SIZE;
|
||||
while (fontSize > MIN_FONT_SIZE && !splitLinesForGroup(words, colors, fontSize)) { fontSize -= 2; }
|
||||
while (fontSize > MIN_FONT_SIZE && !splitLinesForGroup(words, colors, fontSize)) {
|
||||
fontSize -= 2;
|
||||
}
|
||||
return {
|
||||
words: words.slice(), colors: colors, fontSize: fontSize,
|
||||
words: words.slice(),
|
||||
colors: colors,
|
||||
fontSize: fontSize,
|
||||
lines: splitLinesForGroup(words, colors, fontSize) || [{ words: words, colors: colors }],
|
||||
start: words[0].start, end: words[words.length - 1].end,
|
||||
start: words[0].start,
|
||||
end: words[words.length - 1].end,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -312,7 +397,32 @@
|
||||
var r = parseInt(hex.slice(0, 2), 16);
|
||||
var g = parseInt(hex.slice(2, 4), 16);
|
||||
var b = parseInt(hex.slice(4, 6), 16);
|
||||
var glow = "0 0 4px rgba(" + r + "," + g + "," + b + ",1), 0 0 10px rgba(" + r + "," + g + "," + b + ",0.9), 0 0 20px rgba(" + r + "," + g + "," + b + ",0.7), 0 0 40px rgba(" + r + "," + g + "," + b + ",0.4)";
|
||||
var glow =
|
||||
"0 0 4px rgba(" +
|
||||
r +
|
||||
"," +
|
||||
g +
|
||||
"," +
|
||||
b +
|
||||
",1), 0 0 10px rgba(" +
|
||||
r +
|
||||
"," +
|
||||
g +
|
||||
"," +
|
||||
b +
|
||||
",0.9), 0 0 20px rgba(" +
|
||||
r +
|
||||
"," +
|
||||
g +
|
||||
"," +
|
||||
b +
|
||||
",0.7), 0 0 40px rgba(" +
|
||||
r +
|
||||
"," +
|
||||
g +
|
||||
"," +
|
||||
b +
|
||||
",0.4)";
|
||||
return "0 8px 16px rgba(0,0,0,0.8), 0 16px 40px rgba(0,0,0,0.6), " + glow;
|
||||
}
|
||||
|
||||
@@ -333,7 +443,8 @@
|
||||
wordEl.className = color === PRIMARY_COLOR ? "caption-word" : "caption-word accent";
|
||||
wordEl.textContent = word.text.toUpperCase();
|
||||
wordEl.style.color = color;
|
||||
wordEl.style.fontSize = color === PRIMARY_COLOR ? group.fontSize + "px" : group.fontSize * 1.2 + "px";
|
||||
wordEl.style.fontSize =
|
||||
color === PRIMARY_COLOR ? group.fontSize + "px" : group.fontSize * 1.2 + "px";
|
||||
wordEl.style.textShadow = shadowForColor(color);
|
||||
lineEl.appendChild(wordEl);
|
||||
});
|
||||
@@ -358,7 +469,9 @@
|
||||
return Math.max(0, group.start - entryLead);
|
||||
});
|
||||
|
||||
var allGroupEls = GROUPS.map(function (_, i) { return document.getElementById("caption-group-" + i); });
|
||||
var allGroupEls = GROUPS.map(function (_, i) {
|
||||
return document.getElementById("caption-group-" + i);
|
||||
});
|
||||
|
||||
GROUPS.forEach(function (group, groupIndex) {
|
||||
var groupEl = allGroupEls[groupIndex];
|
||||
@@ -373,8 +486,24 @@
|
||||
});
|
||||
|
||||
tl.set(groupEl, { opacity: 0, scale: 0.65, x: 0, y: 0 }, visibleStart);
|
||||
tl.to(groupEl, { opacity: 1, scale: 1, duration: ENTRY_DURATION, ease: "power3.out", force3D: true }, visibleStart);
|
||||
tl.to(groupEl, { x: D, y: D, duration: WIGGLE_CYCLE / 2, ease: "sine.inOut", yoyo: true, repeat: Math.max(0, wiggleCycles * 2 - 1), force3D: true }, visibleStart);
|
||||
tl.to(
|
||||
groupEl,
|
||||
{ opacity: 1, scale: 1, duration: ENTRY_DURATION, ease: "power3.out", force3D: true },
|
||||
visibleStart,
|
||||
);
|
||||
tl.to(
|
||||
groupEl,
|
||||
{
|
||||
x: D,
|
||||
y: D,
|
||||
duration: WIGGLE_CYCLE / 2,
|
||||
ease: "sine.inOut",
|
||||
yoyo: true,
|
||||
repeat: Math.max(0, wiggleCycles * 2 - 1),
|
||||
force3D: true,
|
||||
},
|
||||
visibleStart,
|
||||
);
|
||||
tl.set(groupEl, { opacity: 0 }, visibleEnd);
|
||||
});
|
||||
|
||||
|
||||
+159
-108
@@ -6,42 +6,76 @@
|
||||
<title>Neon Glow</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@900&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Outfit:wght@900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #000;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
#neon-glow {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #000;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
#ne-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.ne-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.75); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#ne-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.ne-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 80px;
|
||||
opacity: 0; visibility: hidden;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 80px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.ne-word {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-weight: 900; font-size: 96px;
|
||||
font-family: "Outfit", sans-serif;
|
||||
font-weight: 900;
|
||||
font-size: 96px;
|
||||
text-transform: uppercase;
|
||||
color: rgba(0,255,240,0.14);
|
||||
display: inline-block; letter-spacing: 0.04em; line-height: 1;
|
||||
color: rgba(0, 255, 240, 0.14);
|
||||
display: inline-block;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -55,107 +89,124 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="ne-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="ne-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="ne-overlay"></div>
|
||||
<div id="ne-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
var GROUPS = [
|
||||
{wordStart:0, wordEnd:3, start:0.0, end:1.05},
|
||||
{wordStart:4, wordEnd:7, start:1.1, end:2.05},
|
||||
{wordStart:8, wordEnd:8, start:2.1, end:2.6},
|
||||
{wordStart:9, wordEnd:12, start:2.65, end:3.5},
|
||||
{wordStart:13, wordEnd:15, start:3.55, end:4.4},
|
||||
{wordStart:16, wordEnd:16, start:3.95, end:4.75},
|
||||
{wordStart:17, wordEnd:19, start:4.9, end:5.4},
|
||||
{wordStart:20, wordEnd:22, start:5.65, end:6.2},
|
||||
{wordStart:23, wordEnd:24, start:6.35, end:6.75},
|
||||
{wordStart:25, wordEnd:27, start:6.8, end:7.8},
|
||||
];
|
||||
var GROUPS = [
|
||||
{ wordStart: 0, wordEnd: 3, start: 0.0, end: 1.05 },
|
||||
{ wordStart: 4, wordEnd: 7, start: 1.1, end: 2.05 },
|
||||
{ wordStart: 8, wordEnd: 8, start: 2.1, end: 2.6 },
|
||||
{ wordStart: 9, wordEnd: 12, start: 2.65, end: 3.5 },
|
||||
{ wordStart: 13, wordEnd: 15, start: 3.55, end: 4.4 },
|
||||
{ wordStart: 16, wordEnd: 16, start: 3.95, end: 4.75 },
|
||||
{ wordStart: 17, wordEnd: 19, start: 4.9, end: 5.4 },
|
||||
{ wordStart: 20, wordEnd: 22, start: 5.65, end: 6.2 },
|
||||
{ wordStart: 23, wordEnd: 24, start: 6.35, end: 6.75 },
|
||||
{ wordStart: 25, wordEnd: 27, start: 6.8, end: 7.8 },
|
||||
];
|
||||
|
||||
// Keywords get pink glow; others get cyan glow
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
// Keywords get pink glow; others get cyan glow
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var container = document.getElementById('ne-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
var container = document.getElementById("ne-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'ne-group';
|
||||
grp.id = 'ne-grp-' + gi;
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "ne-group";
|
||||
grp.id = "ne-grp-" + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement('span');
|
||||
span.className = 'ne-word';
|
||||
span.id = 'ne-w-' + wi;
|
||||
span.textContent = w.text;
|
||||
span.style.fontSize = '96px';
|
||||
grp.appendChild(span);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement("span");
|
||||
span.className = "ne-word";
|
||||
span.id = "ne-w-" + wi;
|
||||
span.textContent = w.text;
|
||||
span.style.fontSize = "96px";
|
||||
grp.appendChild(span);
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
|
||||
tl.set(grp, { visibility: "visible", opacity: 0 }, g.start);
|
||||
tl.fromTo(grp, { opacity: 0 }, { opacity: 1, duration: 0.05, ease: "steps(1)" }, g.start);
|
||||
tl.fromTo(grp, { x: -8 }, { x: 0, duration: 0.14, ease: "power3.out" }, g.start + 0.05);
|
||||
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var el = document.getElementById("ne-w-" + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
var activeColor = isKW ? "#FF0099" : "#00FFF0";
|
||||
tl.to(
|
||||
el,
|
||||
{
|
||||
color: activeColor,
|
||||
textShadow:
|
||||
"0 0 10px " +
|
||||
activeColor +
|
||||
", 0 0 35px " +
|
||||
activeColor +
|
||||
", 0 0 90px " +
|
||||
activeColor,
|
||||
duration: 0.06,
|
||||
},
|
||||
w.start,
|
||||
);
|
||||
tl.to(el, { color: "rgba(0,255,240,0.14)", textShadow: "none", duration: 0.06 }, w.end);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, x: 6, duration: 0.1, ease: "steps(1)" }, g.end - 0.1);
|
||||
tl.set(grp, { opacity: 0, visibility: "hidden" }, g.end);
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
|
||||
tl.set(grp, { visibility: 'visible', opacity: 0 }, g.start);
|
||||
tl.fromTo(grp, { opacity: 0 }, { opacity: 1, duration: 0.05, ease: 'steps(1)' }, g.start);
|
||||
tl.fromTo(grp, { x: -8 }, { x: 0, duration: 0.14, ease: 'power3.out' }, g.start + 0.05);
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var el = document.getElementById('ne-w-' + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
var activeColor = isKW ? '#FF0099' : '#00FFF0';
|
||||
tl.to(el, {
|
||||
color: activeColor,
|
||||
textShadow: '0 0 10px ' + activeColor + ', 0 0 35px ' + activeColor + ', 0 0 90px ' + activeColor,
|
||||
duration: 0.06
|
||||
}, w.start);
|
||||
tl.to(el, { color: 'rgba(0,255,240,0.14)', textShadow: 'none', duration: 0.06 }, w.end);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, x: 6, duration: 0.1, ease: 'steps(1)' }, g.end - 0.1);
|
||||
tl.set(grp, { opacity: 0, visibility: 'hidden' }, g.end);
|
||||
});
|
||||
|
||||
window.__timelines['neon-glow'] = tl;
|
||||
})();
|
||||
window.__timelines["neon-glow"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+159
-108
@@ -6,42 +6,76 @@
|
||||
<title>Neon Glow</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@900&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Outfit:wght@900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #000;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
#neon-glow {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #000;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
#ne-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.ne-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.75); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#ne-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.ne-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 80px;
|
||||
opacity: 0; visibility: hidden;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 80px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.ne-word {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-weight: 900; font-size: 96px;
|
||||
font-family: "Outfit", sans-serif;
|
||||
font-weight: 900;
|
||||
font-size: 96px;
|
||||
text-transform: uppercase;
|
||||
color: rgba(0,255,240,0.14);
|
||||
display: inline-block; letter-spacing: 0.04em; line-height: 1;
|
||||
color: rgba(0, 255, 240, 0.14);
|
||||
display: inline-block;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -55,107 +89,124 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="ne-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="ne-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="ne-overlay"></div>
|
||||
<div id="ne-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
var GROUPS = [
|
||||
{wordStart:0, wordEnd:3, start:0.0, end:1.05},
|
||||
{wordStart:4, wordEnd:7, start:1.1, end:2.05},
|
||||
{wordStart:8, wordEnd:8, start:2.1, end:2.6},
|
||||
{wordStart:9, wordEnd:12, start:2.65, end:3.5},
|
||||
{wordStart:13, wordEnd:15, start:3.55, end:4.4},
|
||||
{wordStart:16, wordEnd:16, start:3.95, end:4.75},
|
||||
{wordStart:17, wordEnd:19, start:4.9, end:5.4},
|
||||
{wordStart:20, wordEnd:22, start:5.65, end:6.2},
|
||||
{wordStart:23, wordEnd:24, start:6.35, end:6.75},
|
||||
{wordStart:25, wordEnd:27, start:6.8, end:7.8},
|
||||
];
|
||||
var GROUPS = [
|
||||
{ wordStart: 0, wordEnd: 3, start: 0.0, end: 1.05 },
|
||||
{ wordStart: 4, wordEnd: 7, start: 1.1, end: 2.05 },
|
||||
{ wordStart: 8, wordEnd: 8, start: 2.1, end: 2.6 },
|
||||
{ wordStart: 9, wordEnd: 12, start: 2.65, end: 3.5 },
|
||||
{ wordStart: 13, wordEnd: 15, start: 3.55, end: 4.4 },
|
||||
{ wordStart: 16, wordEnd: 16, start: 3.95, end: 4.75 },
|
||||
{ wordStart: 17, wordEnd: 19, start: 4.9, end: 5.4 },
|
||||
{ wordStart: 20, wordEnd: 22, start: 5.65, end: 6.2 },
|
||||
{ wordStart: 23, wordEnd: 24, start: 6.35, end: 6.75 },
|
||||
{ wordStart: 25, wordEnd: 27, start: 6.8, end: 7.8 },
|
||||
];
|
||||
|
||||
// Keywords get pink glow; others get cyan glow
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
// Keywords get pink glow; others get cyan glow
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var container = document.getElementById('ne-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
var container = document.getElementById("ne-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'ne-group';
|
||||
grp.id = 'ne-grp-' + gi;
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "ne-group";
|
||||
grp.id = "ne-grp-" + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement('span');
|
||||
span.className = 'ne-word';
|
||||
span.id = 'ne-w-' + wi;
|
||||
span.textContent = w.text;
|
||||
span.style.fontSize = '96px';
|
||||
grp.appendChild(span);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement("span");
|
||||
span.className = "ne-word";
|
||||
span.id = "ne-w-" + wi;
|
||||
span.textContent = w.text;
|
||||
span.style.fontSize = "96px";
|
||||
grp.appendChild(span);
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
|
||||
tl.set(grp, { visibility: "visible", opacity: 0 }, g.start);
|
||||
tl.fromTo(grp, { opacity: 0 }, { opacity: 1, duration: 0.05, ease: "steps(1)" }, g.start);
|
||||
tl.fromTo(grp, { x: -8 }, { x: 0, duration: 0.14, ease: "power3.out" }, g.start + 0.05);
|
||||
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var el = document.getElementById("ne-w-" + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
var activeColor = isKW ? "#FF0099" : "#00FFF0";
|
||||
tl.to(
|
||||
el,
|
||||
{
|
||||
color: activeColor,
|
||||
textShadow:
|
||||
"0 0 10px " +
|
||||
activeColor +
|
||||
", 0 0 35px " +
|
||||
activeColor +
|
||||
", 0 0 90px " +
|
||||
activeColor,
|
||||
duration: 0.06,
|
||||
},
|
||||
w.start,
|
||||
);
|
||||
tl.to(el, { color: "rgba(0,255,240,0.14)", textShadow: "none", duration: 0.06 }, w.end);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, x: 6, duration: 0.1, ease: "steps(1)" }, g.end - 0.1);
|
||||
tl.set(grp, { opacity: 0, visibility: "hidden" }, g.end);
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
|
||||
tl.set(grp, { visibility: 'visible', opacity: 0 }, g.start);
|
||||
tl.fromTo(grp, { opacity: 0 }, { opacity: 1, duration: 0.05, ease: 'steps(1)' }, g.start);
|
||||
tl.fromTo(grp, { x: -8 }, { x: 0, duration: 0.14, ease: 'power3.out' }, g.start + 0.05);
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var el = document.getElementById('ne-w-' + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
var activeColor = isKW ? '#FF0099' : '#00FFF0';
|
||||
tl.to(el, {
|
||||
color: activeColor,
|
||||
textShadow: '0 0 10px ' + activeColor + ', 0 0 35px ' + activeColor + ', 0 0 90px ' + activeColor,
|
||||
duration: 0.06
|
||||
}, w.start);
|
||||
tl.to(el, { color: 'rgba(0,255,240,0.14)', textShadow: 'none', duration: 0.06 }, w.end);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, x: 6, duration: 0.1, ease: 'steps(1)' }, g.end - 0.1);
|
||||
tl.set(grp, { opacity: 0, visibility: 'hidden' }, g.end);
|
||||
});
|
||||
|
||||
window.__timelines['neon-glow'] = tl;
|
||||
})();
|
||||
window.__timelines["neon-glow"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
<title>Parallax Layers</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*,
|
||||
@@ -113,9 +116,9 @@
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
line-height: 0.9;
|
||||
color: #E50914;
|
||||
-webkit-text-stroke: 5px #E50914;
|
||||
text-shadow: 2px 4px 4px #A30610;
|
||||
color: #e50914;
|
||||
-webkit-text-stroke: 5px #e50914;
|
||||
text-shadow: 2px 4px 4px #a30610;
|
||||
}
|
||||
|
||||
.word--front-normal {
|
||||
@@ -123,8 +126,10 @@
|
||||
font-size: 130px;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
color: #EEEEEE;
|
||||
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6), 0 4px 24px rgba(0, 0, 0, 0.35);
|
||||
color: #eeeeee;
|
||||
text-shadow:
|
||||
0 2px 12px rgba(0, 0, 0, 0.6),
|
||||
0 4px 24px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.word--front-italic {
|
||||
@@ -132,8 +137,10 @@
|
||||
font-size: 130px;
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
color: #EEEEEE;
|
||||
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6), 0 4px 24px rgba(0, 0, 0, 0.35);
|
||||
color: #eeeeee;
|
||||
text-shadow:
|
||||
0 2px 12px rgba(0, 0, 0, 0.6),
|
||||
0 4px 24px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -175,48 +182,48 @@
|
||||
var SLIDE_DUR = 0.2;
|
||||
|
||||
var W = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
// behind=red 3D emphasis words, front=normal white words
|
||||
var BLOCKS = [
|
||||
{ behind: null, front: [[0],[1],[2]] },
|
||||
{ behind: [[3]], front: [[4],[5]] },
|
||||
{ behind: [[6]], front: [[7]] },
|
||||
{ behind: [[8]], front: [[9],[10],[11]] },
|
||||
{ behind: [[12]], front: [[13],[14]] },
|
||||
{ behind: [[15]], front: [[16]] },
|
||||
{ behind: null, front: [[17],[18]] },
|
||||
{ behind: null, front: [[19],[20],[21],[22]] },
|
||||
{ behind: [[24]], front: [[23],[25],[26]] },
|
||||
{ behind: [[27]], front: null },
|
||||
{ behind: null, front: [[0], [1], [2]] },
|
||||
{ behind: [[3]], front: [[4], [5]] },
|
||||
{ behind: [[6]], front: [[7]] },
|
||||
{ behind: [[8]], front: [[9], [10], [11]] },
|
||||
{ behind: [[12]], front: [[13], [14]] },
|
||||
{ behind: [[15]], front: [[16]] },
|
||||
{ behind: null, front: [[17], [18]] },
|
||||
{ behind: null, front: [[19], [20], [21], [22]] },
|
||||
{ behind: [[24]], front: [[23], [25], [26]] },
|
||||
{ behind: [[27]], front: null },
|
||||
];
|
||||
|
||||
var behindStage = document.getElementById("behind-stage");
|
||||
@@ -259,8 +266,12 @@
|
||||
frontStage.appendChild(fEl);
|
||||
});
|
||||
|
||||
var allBehind = BLOCKS.map(function (_, i) { return document.getElementById("bb" + i); });
|
||||
var allFront = BLOCKS.map(function (_, i) { return document.getElementById("fb" + i); });
|
||||
var allBehind = BLOCKS.map(function (_, i) {
|
||||
return document.getElementById("bb" + i);
|
||||
});
|
||||
var allFront = BLOCKS.map(function (_, i) {
|
||||
return document.getElementById("fb" + i);
|
||||
});
|
||||
|
||||
function applyBehindScales() {
|
||||
BLOCKS.forEach(function (block, bi) {
|
||||
@@ -293,8 +304,12 @@
|
||||
var bEl = allBehind[bi];
|
||||
var fEl = allFront[bi];
|
||||
|
||||
allBehind.forEach(function (other, oi) { if (oi !== bi) tl.set(other, { opacity: 0 }, start); });
|
||||
allFront.forEach(function (other, oi) { if (oi !== bi) tl.set(other, { opacity: 0 }, start); });
|
||||
allBehind.forEach(function (other, oi) {
|
||||
if (oi !== bi) tl.set(other, { opacity: 0 }, start);
|
||||
});
|
||||
allFront.forEach(function (other, oi) {
|
||||
if (oi !== bi) tl.set(other, { opacity: 0 }, start);
|
||||
});
|
||||
|
||||
if (block.behind) {
|
||||
tl.set(bEl, { opacity: 1 }, start);
|
||||
@@ -323,7 +338,9 @@
|
||||
tl.to({}, { duration: DURATION }, 0);
|
||||
window.__timelines["parallax-layers"] = tl;
|
||||
|
||||
document.fonts.ready.then(function () { applyBehindScales(); });
|
||||
document.fonts.ready.then(function () {
|
||||
applyBehindScales();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+68
-51
@@ -6,7 +6,10 @@
|
||||
<title>Parallax Layers</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*,
|
||||
@@ -113,9 +116,9 @@
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
line-height: 0.9;
|
||||
color: #E50914;
|
||||
-webkit-text-stroke: 5px #E50914;
|
||||
text-shadow: 2px 4px 4px #A30610;
|
||||
color: #e50914;
|
||||
-webkit-text-stroke: 5px #e50914;
|
||||
text-shadow: 2px 4px 4px #a30610;
|
||||
}
|
||||
|
||||
.word--front-normal {
|
||||
@@ -123,8 +126,10 @@
|
||||
font-size: 130px;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
color: #EEEEEE;
|
||||
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6), 0 4px 24px rgba(0, 0, 0, 0.35);
|
||||
color: #eeeeee;
|
||||
text-shadow:
|
||||
0 2px 12px rgba(0, 0, 0, 0.6),
|
||||
0 4px 24px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.word--front-italic {
|
||||
@@ -132,8 +137,10 @@
|
||||
font-size: 130px;
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
color: #EEEEEE;
|
||||
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.6), 0 4px 24px rgba(0, 0, 0, 0.35);
|
||||
color: #eeeeee;
|
||||
text-shadow:
|
||||
0 2px 12px rgba(0, 0, 0, 0.6),
|
||||
0 4px 24px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -175,48 +182,48 @@
|
||||
var SLIDE_DUR = 0.2;
|
||||
|
||||
var W = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
// behind=red 3D emphasis words, front=normal white words
|
||||
var BLOCKS = [
|
||||
{ behind: null, front: [[0],[1],[2]] },
|
||||
{ behind: [[3]], front: [[4],[5]] },
|
||||
{ behind: [[6]], front: [[7]] },
|
||||
{ behind: [[8]], front: [[9],[10],[11]] },
|
||||
{ behind: [[12]], front: [[13],[14]] },
|
||||
{ behind: [[15]], front: [[16]] },
|
||||
{ behind: null, front: [[17],[18]] },
|
||||
{ behind: null, front: [[19],[20],[21],[22]] },
|
||||
{ behind: [[24]], front: [[23],[25],[26]] },
|
||||
{ behind: [[27]], front: null },
|
||||
{ behind: null, front: [[0], [1], [2]] },
|
||||
{ behind: [[3]], front: [[4], [5]] },
|
||||
{ behind: [[6]], front: [[7]] },
|
||||
{ behind: [[8]], front: [[9], [10], [11]] },
|
||||
{ behind: [[12]], front: [[13], [14]] },
|
||||
{ behind: [[15]], front: [[16]] },
|
||||
{ behind: null, front: [[17], [18]] },
|
||||
{ behind: null, front: [[19], [20], [21], [22]] },
|
||||
{ behind: [[24]], front: [[23], [25], [26]] },
|
||||
{ behind: [[27]], front: null },
|
||||
];
|
||||
|
||||
var behindStage = document.getElementById("behind-stage");
|
||||
@@ -259,8 +266,12 @@
|
||||
frontStage.appendChild(fEl);
|
||||
});
|
||||
|
||||
var allBehind = BLOCKS.map(function (_, i) { return document.getElementById("bb" + i); });
|
||||
var allFront = BLOCKS.map(function (_, i) { return document.getElementById("fb" + i); });
|
||||
var allBehind = BLOCKS.map(function (_, i) {
|
||||
return document.getElementById("bb" + i);
|
||||
});
|
||||
var allFront = BLOCKS.map(function (_, i) {
|
||||
return document.getElementById("fb" + i);
|
||||
});
|
||||
|
||||
function applyBehindScales() {
|
||||
BLOCKS.forEach(function (block, bi) {
|
||||
@@ -293,8 +304,12 @@
|
||||
var bEl = allBehind[bi];
|
||||
var fEl = allFront[bi];
|
||||
|
||||
allBehind.forEach(function (other, oi) { if (oi !== bi) tl.set(other, { opacity: 0 }, start); });
|
||||
allFront.forEach(function (other, oi) { if (oi !== bi) tl.set(other, { opacity: 0 }, start); });
|
||||
allBehind.forEach(function (other, oi) {
|
||||
if (oi !== bi) tl.set(other, { opacity: 0 }, start);
|
||||
});
|
||||
allFront.forEach(function (other, oi) {
|
||||
if (oi !== bi) tl.set(other, { opacity: 0 }, start);
|
||||
});
|
||||
|
||||
if (block.behind) {
|
||||
tl.set(bEl, { opacity: 1 }, start);
|
||||
@@ -323,7 +338,9 @@
|
||||
tl.to({}, { duration: DURATION }, 0);
|
||||
window.__timelines["parallax-layers"] = tl;
|
||||
|
||||
document.fonts.ready.then(function () { applyBehindScales(); });
|
||||
document.fonts.ready.then(function () {
|
||||
applyBehindScales();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+230
-150
@@ -6,47 +6,87 @@
|
||||
<title>Particle Burst</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@900&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Outfit:wght@900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#particle-burst {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#bs-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.bs-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.45); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#bs-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.bs-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 100px;
|
||||
opacity: 0; visibility: hidden;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 100px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.bs-word {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-weight: 900; font-size: 88px;
|
||||
font-family: "Outfit", sans-serif;
|
||||
font-weight: 900;
|
||||
font-size: 88px;
|
||||
text-transform: uppercase;
|
||||
color: rgba(255,255,255,0.45);
|
||||
display: inline-block; letter-spacing: 0.05em; line-height: 1;
|
||||
color: rgba(255, 255, 255, 0.45);
|
||||
display: inline-block;
|
||||
letter-spacing: 0.05em;
|
||||
line-height: 1;
|
||||
}
|
||||
.bs-particle {
|
||||
position: absolute; width: 10px; height: 10px;
|
||||
border-radius: 50%; opacity: 0; pointer-events: none; z-index: 20;
|
||||
left: 960px; bottom: 180px;
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
z-index: 20;
|
||||
left: 960px;
|
||||
bottom: 180px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -60,153 +100,193 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="bs-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="bs-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="bs-overlay"></div>
|
||||
<div id="bs-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
function mulberry32(seed) {
|
||||
return function() {
|
||||
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
|
||||
var t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
||||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
function mulberry32(seed) {
|
||||
return function () {
|
||||
seed |= 0;
|
||||
seed = (seed + 0x6d2b79f5) | 0;
|
||||
var t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
|
||||
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
// Keywords get particle burst + gold color
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
// Keywords get particle burst + gold color
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var RAW_GROUPS = [
|
||||
[0,3],[4,7],[8,8],[9,12],[13,15],[16,16],[17,19],[20,22],[23,24],[25,27]
|
||||
];
|
||||
var GROUPS = RAW_GROUPS.map(function(pair, gi) {
|
||||
var ws = pair[0], we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi+1][0]].start : 8.0;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.35, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
var PARTICLE_COLORS = ['#FFD700','#FF6B35','#FF3C78','#9B5DE5','#00BBF9','#00F5D4','#ffffff','#F15BB5'];
|
||||
var NUM_PARTICLES = 10;
|
||||
|
||||
var container = document.getElementById('bs-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'bs-group';
|
||||
grp.id = 'bs-grp-' + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement('span');
|
||||
span.className = 'bs-word';
|
||||
span.id = 'bs-w-' + wi;
|
||||
span.textContent = w.text.toUpperCase();
|
||||
span.style.fontSize = '88px';
|
||||
grp.appendChild(span);
|
||||
var RAW_GROUPS = [
|
||||
[0, 3],
|
||||
[4, 7],
|
||||
[8, 8],
|
||||
[9, 12],
|
||||
[13, 15],
|
||||
[16, 16],
|
||||
[17, 19],
|
||||
[20, 22],
|
||||
[23, 24],
|
||||
[25, 27],
|
||||
];
|
||||
var GROUPS = RAW_GROUPS.map(function (pair, gi) {
|
||||
var ws = pair[0],
|
||||
we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : 8.0;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.35, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
});
|
||||
var PARTICLE_COLORS = [
|
||||
"#FFD700",
|
||||
"#FF6B35",
|
||||
"#FF3C78",
|
||||
"#9B5DE5",
|
||||
"#00BBF9",
|
||||
"#00F5D4",
|
||||
"#ffffff",
|
||||
"#F15BB5",
|
||||
];
|
||||
var NUM_PARTICLES = 10;
|
||||
|
||||
// Create particles for keyword words
|
||||
var particleData = {};
|
||||
WORDS.forEach(function(w, wi) {
|
||||
if (!KEYWORDS.has(wi)) return;
|
||||
var rng = mulberry32(wi * 137 + 99);
|
||||
particleData[wi] = [];
|
||||
for (var p = 0; p < NUM_PARTICLES; p++) {
|
||||
var angle = (p / NUM_PARTICLES) * Math.PI * 2 + rng() * 0.6;
|
||||
var dist = 120 + rng() * 200;
|
||||
var sz = 4 + rng() * 8;
|
||||
var dx = Math.cos(angle) * dist;
|
||||
var dy = -Math.sin(angle) * dist;
|
||||
var dot = document.createElement('div');
|
||||
dot.className = 'bs-particle';
|
||||
dot.id = 'bs-p-' + wi + '-' + p;
|
||||
dot.style.backgroundColor = PARTICLE_COLORS[p % PARTICLE_COLORS.length];
|
||||
dot.style.width = sz.toFixed(1) + 'px';
|
||||
dot.style.height = sz.toFixed(1) + 'px';
|
||||
container.appendChild(dot);
|
||||
particleData[wi].push({ el: dot, dx: dx, dy: dy });
|
||||
}
|
||||
});
|
||||
var container = document.getElementById("bs-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var grp = document.getElementById('bs-grp-' + gi);
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "bs-group";
|
||||
grp.id = "bs-grp-" + gi;
|
||||
|
||||
tl.set(grp, { visibility: 'visible' }, g.start);
|
||||
tl.fromTo(grp,
|
||||
{ opacity: 0, scale: 0.92 },
|
||||
{ opacity: 1, scale: 1, duration: 0.2, ease: 'back.out(1.5)' },
|
||||
g.start
|
||||
);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement("span");
|
||||
span.className = "bs-word";
|
||||
span.id = "bs-w-" + wi;
|
||||
span.textContent = w.text.toUpperCase();
|
||||
span.style.fontSize = "88px";
|
||||
grp.appendChild(span);
|
||||
});
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordEl = document.getElementById('bs-w-' + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
container.appendChild(grp);
|
||||
});
|
||||
|
||||
tl.to(wordEl, { color: isKW ? '#FFD700' : '#ffffff', scale: isKW ? 1.12 : 1.05, duration: 0.08 }, w.start);
|
||||
tl.to(wordEl, { color: 'rgba(255,255,255,0.4)', scale: 1.0, duration: 0.1 }, w.end);
|
||||
|
||||
if (isKW && particleData[wi]) {
|
||||
particleData[wi].forEach(function(pd, pi) {
|
||||
tl.set(pd.el, { x: 0, y: 0, opacity: 0 }, w.start);
|
||||
tl.to(pd.el, { x: pd.dx, y: pd.dy, opacity: 1, duration: 0.12, ease: 'power3.out' }, w.start + pi * 0.018);
|
||||
tl.to(pd.el, { opacity: 0, duration: 0.45, ease: 'power1.in' }, w.start + 0.12 + pi * 0.018);
|
||||
tl.set(pd.el, { opacity: 0, x: 0, y: 0 }, w.start + 0.7);
|
||||
});
|
||||
// Create particles for keyword words
|
||||
var particleData = {};
|
||||
WORDS.forEach(function (w, wi) {
|
||||
if (!KEYWORDS.has(wi)) return;
|
||||
var rng = mulberry32(wi * 137 + 99);
|
||||
particleData[wi] = [];
|
||||
for (var p = 0; p < NUM_PARTICLES; p++) {
|
||||
var angle = (p / NUM_PARTICLES) * Math.PI * 2 + rng() * 0.6;
|
||||
var dist = 120 + rng() * 200;
|
||||
var sz = 4 + rng() * 8;
|
||||
var dx = Math.cos(angle) * dist;
|
||||
var dy = -Math.sin(angle) * dist;
|
||||
var dot = document.createElement("div");
|
||||
dot.className = "bs-particle";
|
||||
dot.id = "bs-p-" + wi + "-" + p;
|
||||
dot.style.backgroundColor = PARTICLE_COLORS[p % PARTICLE_COLORS.length];
|
||||
dot.style.width = sz.toFixed(1) + "px";
|
||||
dot.style.height = sz.toFixed(1) + "px";
|
||||
container.appendChild(dot);
|
||||
particleData[wi].push({ el: dot, dx: dx, dy: dy });
|
||||
}
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, duration: 0.14, ease: 'power2.in' }, g.end - 0.14);
|
||||
tl.set(grp, { opacity: 0, visibility: 'hidden' }, g.end);
|
||||
});
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var grp = document.getElementById("bs-grp-" + gi);
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines['particle-burst'] = tl;
|
||||
})();
|
||||
tl.set(grp, { visibility: "visible" }, g.start);
|
||||
tl.fromTo(
|
||||
grp,
|
||||
{ opacity: 0, scale: 0.92 },
|
||||
{ opacity: 1, scale: 1, duration: 0.2, ease: "back.out(1.5)" },
|
||||
g.start,
|
||||
);
|
||||
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordEl = document.getElementById("bs-w-" + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ color: isKW ? "#FFD700" : "#ffffff", scale: isKW ? 1.12 : 1.05, duration: 0.08 },
|
||||
w.start,
|
||||
);
|
||||
tl.to(wordEl, { color: "rgba(255,255,255,0.4)", scale: 1.0, duration: 0.1 }, w.end);
|
||||
|
||||
if (isKW && particleData[wi]) {
|
||||
particleData[wi].forEach(function (pd, pi) {
|
||||
tl.set(pd.el, { x: 0, y: 0, opacity: 0 }, w.start);
|
||||
tl.to(
|
||||
pd.el,
|
||||
{ x: pd.dx, y: pd.dy, opacity: 1, duration: 0.12, ease: "power3.out" },
|
||||
w.start + pi * 0.018,
|
||||
);
|
||||
tl.to(
|
||||
pd.el,
|
||||
{ opacity: 0, duration: 0.45, ease: "power1.in" },
|
||||
w.start + 0.12 + pi * 0.018,
|
||||
);
|
||||
tl.set(pd.el, { opacity: 0, x: 0, y: 0 }, w.start + 0.7);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, duration: 0.14, ease: "power2.in" }, g.end - 0.14);
|
||||
tl.set(grp, { opacity: 0, visibility: "hidden" }, g.end);
|
||||
});
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines["particle-burst"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+230
-150
@@ -6,47 +6,87 @@
|
||||
<title>Particle Burst</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@900&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Outfit:wght@900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#particle-burst {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #0a0a0a;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #0a0a0a;
|
||||
}
|
||||
#bs-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.bs-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.45); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#bs-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.bs-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 100px;
|
||||
opacity: 0; visibility: hidden;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 100px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.bs-word {
|
||||
font-family: 'Outfit', sans-serif;
|
||||
font-weight: 900; font-size: 88px;
|
||||
font-family: "Outfit", sans-serif;
|
||||
font-weight: 900;
|
||||
font-size: 88px;
|
||||
text-transform: uppercase;
|
||||
color: rgba(255,255,255,0.45);
|
||||
display: inline-block; letter-spacing: 0.05em; line-height: 1;
|
||||
color: rgba(255, 255, 255, 0.45);
|
||||
display: inline-block;
|
||||
letter-spacing: 0.05em;
|
||||
line-height: 1;
|
||||
}
|
||||
.bs-particle {
|
||||
position: absolute; width: 10px; height: 10px;
|
||||
border-radius: 50%; opacity: 0; pointer-events: none; z-index: 20;
|
||||
left: 960px; bottom: 180px;
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
z-index: 20;
|
||||
left: 960px;
|
||||
bottom: 180px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -60,153 +100,193 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="bs-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="bs-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="bs-overlay"></div>
|
||||
<div id="bs-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
function mulberry32(seed) {
|
||||
return function() {
|
||||
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
|
||||
var t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
||||
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
||||
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
function mulberry32(seed) {
|
||||
return function () {
|
||||
seed |= 0;
|
||||
seed = (seed + 0x6d2b79f5) | 0;
|
||||
var t = Math.imul(seed ^ (seed >>> 15), 1 | seed);
|
||||
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
|
||||
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
||||
};
|
||||
}
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
// Keywords get particle burst + gold color
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
// Keywords get particle burst + gold color
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var RAW_GROUPS = [
|
||||
[0,3],[4,7],[8,8],[9,12],[13,15],[16,16],[17,19],[20,22],[23,24],[25,27]
|
||||
];
|
||||
var GROUPS = RAW_GROUPS.map(function(pair, gi) {
|
||||
var ws = pair[0], we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi+1][0]].start : 8.0;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.35, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
var PARTICLE_COLORS = ['#FFD700','#FF6B35','#FF3C78','#9B5DE5','#00BBF9','#00F5D4','#ffffff','#F15BB5'];
|
||||
var NUM_PARTICLES = 10;
|
||||
|
||||
var container = document.getElementById('bs-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'bs-group';
|
||||
grp.id = 'bs-grp-' + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement('span');
|
||||
span.className = 'bs-word';
|
||||
span.id = 'bs-w-' + wi;
|
||||
span.textContent = w.text.toUpperCase();
|
||||
span.style.fontSize = '88px';
|
||||
grp.appendChild(span);
|
||||
var RAW_GROUPS = [
|
||||
[0, 3],
|
||||
[4, 7],
|
||||
[8, 8],
|
||||
[9, 12],
|
||||
[13, 15],
|
||||
[16, 16],
|
||||
[17, 19],
|
||||
[20, 22],
|
||||
[23, 24],
|
||||
[25, 27],
|
||||
];
|
||||
var GROUPS = RAW_GROUPS.map(function (pair, gi) {
|
||||
var ws = pair[0],
|
||||
we = pair[1];
|
||||
var nextStart = gi + 1 < RAW_GROUPS.length ? WORDS[RAW_GROUPS[gi + 1][0]].start : 8.0;
|
||||
var gEnd = Math.min(WORDS[we].end + 0.35, nextStart - 0.05);
|
||||
return { wordStart: ws, wordEnd: we, start: WORDS[ws].start, end: gEnd };
|
||||
});
|
||||
|
||||
container.appendChild(grp);
|
||||
});
|
||||
var PARTICLE_COLORS = [
|
||||
"#FFD700",
|
||||
"#FF6B35",
|
||||
"#FF3C78",
|
||||
"#9B5DE5",
|
||||
"#00BBF9",
|
||||
"#00F5D4",
|
||||
"#ffffff",
|
||||
"#F15BB5",
|
||||
];
|
||||
var NUM_PARTICLES = 10;
|
||||
|
||||
// Create particles for keyword words
|
||||
var particleData = {};
|
||||
WORDS.forEach(function(w, wi) {
|
||||
if (!KEYWORDS.has(wi)) return;
|
||||
var rng = mulberry32(wi * 137 + 99);
|
||||
particleData[wi] = [];
|
||||
for (var p = 0; p < NUM_PARTICLES; p++) {
|
||||
var angle = (p / NUM_PARTICLES) * Math.PI * 2 + rng() * 0.6;
|
||||
var dist = 120 + rng() * 200;
|
||||
var sz = 4 + rng() * 8;
|
||||
var dx = Math.cos(angle) * dist;
|
||||
var dy = -Math.sin(angle) * dist;
|
||||
var dot = document.createElement('div');
|
||||
dot.className = 'bs-particle';
|
||||
dot.id = 'bs-p-' + wi + '-' + p;
|
||||
dot.style.backgroundColor = PARTICLE_COLORS[p % PARTICLE_COLORS.length];
|
||||
dot.style.width = sz.toFixed(1) + 'px';
|
||||
dot.style.height = sz.toFixed(1) + 'px';
|
||||
container.appendChild(dot);
|
||||
particleData[wi].push({ el: dot, dx: dx, dy: dy });
|
||||
}
|
||||
});
|
||||
var container = document.getElementById("bs-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var grp = document.getElementById('bs-grp-' + gi);
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "bs-group";
|
||||
grp.id = "bs-grp-" + gi;
|
||||
|
||||
tl.set(grp, { visibility: 'visible' }, g.start);
|
||||
tl.fromTo(grp,
|
||||
{ opacity: 0, scale: 0.92 },
|
||||
{ opacity: 1, scale: 1, duration: 0.2, ease: 'back.out(1.5)' },
|
||||
g.start
|
||||
);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var span = document.createElement("span");
|
||||
span.className = "bs-word";
|
||||
span.id = "bs-w-" + wi;
|
||||
span.textContent = w.text.toUpperCase();
|
||||
span.style.fontSize = "88px";
|
||||
grp.appendChild(span);
|
||||
});
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordEl = document.getElementById('bs-w-' + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
container.appendChild(grp);
|
||||
});
|
||||
|
||||
tl.to(wordEl, { color: isKW ? '#FFD700' : '#ffffff', scale: isKW ? 1.12 : 1.05, duration: 0.08 }, w.start);
|
||||
tl.to(wordEl, { color: 'rgba(255,255,255,0.4)', scale: 1.0, duration: 0.1 }, w.end);
|
||||
|
||||
if (isKW && particleData[wi]) {
|
||||
particleData[wi].forEach(function(pd, pi) {
|
||||
tl.set(pd.el, { x: 0, y: 0, opacity: 0 }, w.start);
|
||||
tl.to(pd.el, { x: pd.dx, y: pd.dy, opacity: 1, duration: 0.12, ease: 'power3.out' }, w.start + pi * 0.018);
|
||||
tl.to(pd.el, { opacity: 0, duration: 0.45, ease: 'power1.in' }, w.start + 0.12 + pi * 0.018);
|
||||
tl.set(pd.el, { opacity: 0, x: 0, y: 0 }, w.start + 0.7);
|
||||
});
|
||||
// Create particles for keyword words
|
||||
var particleData = {};
|
||||
WORDS.forEach(function (w, wi) {
|
||||
if (!KEYWORDS.has(wi)) return;
|
||||
var rng = mulberry32(wi * 137 + 99);
|
||||
particleData[wi] = [];
|
||||
for (var p = 0; p < NUM_PARTICLES; p++) {
|
||||
var angle = (p / NUM_PARTICLES) * Math.PI * 2 + rng() * 0.6;
|
||||
var dist = 120 + rng() * 200;
|
||||
var sz = 4 + rng() * 8;
|
||||
var dx = Math.cos(angle) * dist;
|
||||
var dy = -Math.sin(angle) * dist;
|
||||
var dot = document.createElement("div");
|
||||
dot.className = "bs-particle";
|
||||
dot.id = "bs-p-" + wi + "-" + p;
|
||||
dot.style.backgroundColor = PARTICLE_COLORS[p % PARTICLE_COLORS.length];
|
||||
dot.style.width = sz.toFixed(1) + "px";
|
||||
dot.style.height = sz.toFixed(1) + "px";
|
||||
container.appendChild(dot);
|
||||
particleData[wi].push({ el: dot, dx: dx, dy: dy });
|
||||
}
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, duration: 0.14, ease: 'power2.in' }, g.end - 0.14);
|
||||
tl.set(grp, { opacity: 0, visibility: 'hidden' }, g.end);
|
||||
});
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var grp = document.getElementById("bs-grp-" + gi);
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines['particle-burst'] = tl;
|
||||
})();
|
||||
tl.set(grp, { visibility: "visible" }, g.start);
|
||||
tl.fromTo(
|
||||
grp,
|
||||
{ opacity: 0, scale: 0.92 },
|
||||
{ opacity: 1, scale: 1, duration: 0.2, ease: "back.out(1.5)" },
|
||||
g.start,
|
||||
);
|
||||
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordEl = document.getElementById("bs-w-" + wi);
|
||||
var isKW = KEYWORDS.has(wi);
|
||||
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ color: isKW ? "#FFD700" : "#ffffff", scale: isKW ? 1.12 : 1.05, duration: 0.08 },
|
||||
w.start,
|
||||
);
|
||||
tl.to(wordEl, { color: "rgba(255,255,255,0.4)", scale: 1.0, duration: 0.1 }, w.end);
|
||||
|
||||
if (isKW && particleData[wi]) {
|
||||
particleData[wi].forEach(function (pd, pi) {
|
||||
tl.set(pd.el, { x: 0, y: 0, opacity: 0 }, w.start);
|
||||
tl.to(
|
||||
pd.el,
|
||||
{ x: pd.dx, y: pd.dy, opacity: 1, duration: 0.12, ease: "power3.out" },
|
||||
w.start + pi * 0.018,
|
||||
);
|
||||
tl.to(
|
||||
pd.el,
|
||||
{ opacity: 0, duration: 0.45, ease: "power1.in" },
|
||||
w.start + 0.12 + pi * 0.018,
|
||||
);
|
||||
tl.set(pd.el, { opacity: 0, x: 0, y: 0 }, w.start + 0.7);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, duration: 0.14, ease: "power2.in" }, g.end - 0.14);
|
||||
tl.set(grp, { opacity: 0, visibility: "hidden" }, g.end);
|
||||
});
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines["particle-burst"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
<title>Pill Karaoke</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@700&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Poppins:wght@700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*,
|
||||
@@ -165,45 +168,49 @@
|
||||
var WORD_FADE_LEAD = 0.05;
|
||||
|
||||
var TRANSCRIPT = [
|
||||
{"text": "Every", "start": 0.0, "end": 0.3},
|
||||
{"text": "great", "start": 0.3, "end": 0.55},
|
||||
{"text": "video", "start": 0.55, "end": 0.85},
|
||||
{"text": "starts", "start": 0.85, "end": 1.1},
|
||||
{"text": "with", "start": 1.1, "end": 1.25},
|
||||
{"text": "a", "start": 1.25, "end": 1.35},
|
||||
{"text": "single", "start": 1.35, "end": 1.65},
|
||||
{"text": "frame.", "start": 1.65, "end": 2.0},
|
||||
{"text": "HyperFrames", "start": 2.1, "end": 2.65},
|
||||
{"text": "lets", "start": 2.65, "end": 2.85},
|
||||
{"text": "you", "start": 2.85, "end": 2.95},
|
||||
{"text": "write", "start": 2.95, "end": 3.15},
|
||||
{"text": "HTML", "start": 3.15, "end": 3.55},
|
||||
{"text": "and", "start": 3.55, "end": 3.65},
|
||||
{"text": "render", "start": 3.65, "end": 3.95},
|
||||
{"text": "professional", "start": 3.95, "end": 4.45},
|
||||
{"text": "video.", "start": 4.45, "end": 4.8},
|
||||
{"text": "No", "start": 4.9, "end": 5.05},
|
||||
{"text": "timeline.", "start": 5.05, "end": 5.45},
|
||||
{"text": "No", "start": 5.5, "end": 5.65},
|
||||
{"text": "drag", "start": 5.65, "end": 5.85},
|
||||
{"text": "and", "start": 5.85, "end": 5.95},
|
||||
{"text": "drop.", "start": 5.95, "end": 6.25},
|
||||
{"text": "Just", "start": 6.35, "end": 6.55},
|
||||
{"text": "code", "start": 6.55, "end": 6.8},
|
||||
{"text": "that", "start": 6.8, "end": 6.95},
|
||||
{"text": "becomes", "start": 6.95, "end": 7.3},
|
||||
{"text": "cinema.", "start": 7.3, "end": 7.7}
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
function normalizeWords(rawWords) {
|
||||
return rawWords.map(function (item) {
|
||||
var text = String(item.word || item.text || "").trim();
|
||||
return {
|
||||
text: text,
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
};
|
||||
}).filter(function (w) { return w.text.length > 0; });
|
||||
return rawWords
|
||||
.map(function (item) {
|
||||
var text = String(item.word || item.text || "").trim();
|
||||
return {
|
||||
text: text,
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
};
|
||||
})
|
||||
.filter(function (w) {
|
||||
return w.text.length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
var measureCanvas = document.createElement("canvas");
|
||||
@@ -216,13 +223,19 @@
|
||||
|
||||
function measureLineWidth(words, fontSize) {
|
||||
return words.reduce(function (total, word, index) {
|
||||
return total + measureWordWidth(word.text.toLowerCase(), fontSize) + (index ? WORD_SPACING : 0);
|
||||
return (
|
||||
total + measureWordWidth(word.text.toLowerCase(), fontSize) + (index ? WORD_SPACING : 0)
|
||||
);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function splitLinesForGroup(words, fontSize) {
|
||||
var maxLineWidth = PILL_MAX_WIDTH - PILL_MIN_PADDING_X * 2;
|
||||
if (words.some(function (w) { return measureWordWidth(w.text.toLowerCase(), fontSize) > maxLineWidth; })) {
|
||||
if (
|
||||
words.some(function (w) {
|
||||
return measureWordWidth(w.text.toLowerCase(), fontSize) > maxLineWidth;
|
||||
})
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
if (measureLineWidth(words, fontSize) <= maxLineWidth) return [words];
|
||||
@@ -269,7 +282,11 @@
|
||||
var wouldExceedTwoLines = !fitsInTwoLinesAtSize(testGroup, BASE_FONT_SIZE);
|
||||
if (wouldExceedMaxWords || wouldExceedTwoLines) {
|
||||
if (current.length) {
|
||||
groups.push({ words: current.slice(), start: current[0].start, end: current[current.length - 1].end });
|
||||
groups.push({
|
||||
words: current.slice(),
|
||||
start: current[0].start,
|
||||
end: current[current.length - 1].end,
|
||||
});
|
||||
}
|
||||
current = [word];
|
||||
return;
|
||||
@@ -280,17 +297,28 @@
|
||||
var hasNaturalPause = pauseDuration >= PAUSE_THRESHOLD;
|
||||
var maxWordsReached = current.length >= MAX_WORDS_PER_GROUP;
|
||||
if (maxWordsReached || !nextWord || hasPunctuation || hasNaturalPause) {
|
||||
groups.push({ words: current.slice(), start: current[0].start, end: current[current.length - 1].end });
|
||||
groups.push({
|
||||
words: current.slice(),
|
||||
start: current[0].start,
|
||||
end: current[current.length - 1].end,
|
||||
});
|
||||
current = [];
|
||||
}
|
||||
});
|
||||
if (current.length) groups.push({ words: current.slice(), start: current[0].start, end: current[current.length - 1].end });
|
||||
if (current.length)
|
||||
groups.push({
|
||||
words: current.slice(),
|
||||
start: current[0].start,
|
||||
end: current[current.length - 1].end,
|
||||
});
|
||||
return groups;
|
||||
}
|
||||
|
||||
function fontSizeForGroup(words) {
|
||||
var size = BASE_FONT_SIZE;
|
||||
while (size > MIN_FONT_SIZE && !fitsInTwoLinesAtSize(words, size)) { size -= 2; }
|
||||
while (size > MIN_FONT_SIZE && !fitsInTwoLinesAtSize(words, size)) {
|
||||
size -= 2;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -342,7 +370,9 @@
|
||||
var groupEl = document.getElementById("caption-group-" + groupIndex);
|
||||
var nextGroup = GROUPS[groupIndex + 1];
|
||||
var isLastGroup = groupIndex === GROUPS.length - 1;
|
||||
var effectiveEnd = isLastGroup ? DURATION : Math.min(nextGroup.start, group.end + GROUP_END_BUFFER);
|
||||
var effectiveEnd = isLastGroup
|
||||
? DURATION
|
||||
: Math.min(nextGroup.start, group.end + GROUP_END_BUFFER);
|
||||
var visibleStart = Math.max(0, group.start);
|
||||
var visibleEnd = Math.max(visibleStart + 0.01, effectiveEnd);
|
||||
|
||||
@@ -355,7 +385,11 @@
|
||||
var wordStart = Math.max(visibleStart, word.start - WORD_FADE_LEAD);
|
||||
tl.set(wordEl, { color: isFirstWord ? COLOR_ACTIVE : COLOR_INACTIVE }, visibleStart);
|
||||
if (isFirstWord) return;
|
||||
tl.to(wordEl, { color: COLOR_ACTIVE, duration: COLOR_FADE_DURATION, ease: "none" }, wordStart);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ color: COLOR_ACTIVE, duration: COLOR_FADE_DURATION, ease: "none" },
|
||||
wordStart,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+79
-45
@@ -6,7 +6,10 @@
|
||||
<title>Pill Karaoke</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@700&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Poppins:wght@700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*,
|
||||
@@ -165,45 +168,49 @@
|
||||
var WORD_FADE_LEAD = 0.05;
|
||||
|
||||
var TRANSCRIPT = [
|
||||
{"text": "Every", "start": 0.0, "end": 0.3},
|
||||
{"text": "great", "start": 0.3, "end": 0.55},
|
||||
{"text": "video", "start": 0.55, "end": 0.85},
|
||||
{"text": "starts", "start": 0.85, "end": 1.1},
|
||||
{"text": "with", "start": 1.1, "end": 1.25},
|
||||
{"text": "a", "start": 1.25, "end": 1.35},
|
||||
{"text": "single", "start": 1.35, "end": 1.65},
|
||||
{"text": "frame.", "start": 1.65, "end": 2.0},
|
||||
{"text": "HyperFrames", "start": 2.1, "end": 2.65},
|
||||
{"text": "lets", "start": 2.65, "end": 2.85},
|
||||
{"text": "you", "start": 2.85, "end": 2.95},
|
||||
{"text": "write", "start": 2.95, "end": 3.15},
|
||||
{"text": "HTML", "start": 3.15, "end": 3.55},
|
||||
{"text": "and", "start": 3.55, "end": 3.65},
|
||||
{"text": "render", "start": 3.65, "end": 3.95},
|
||||
{"text": "professional", "start": 3.95, "end": 4.45},
|
||||
{"text": "video.", "start": 4.45, "end": 4.8},
|
||||
{"text": "No", "start": 4.9, "end": 5.05},
|
||||
{"text": "timeline.", "start": 5.05, "end": 5.45},
|
||||
{"text": "No", "start": 5.5, "end": 5.65},
|
||||
{"text": "drag", "start": 5.65, "end": 5.85},
|
||||
{"text": "and", "start": 5.85, "end": 5.95},
|
||||
{"text": "drop.", "start": 5.95, "end": 6.25},
|
||||
{"text": "Just", "start": 6.35, "end": 6.55},
|
||||
{"text": "code", "start": 6.55, "end": 6.8},
|
||||
{"text": "that", "start": 6.8, "end": 6.95},
|
||||
{"text": "becomes", "start": 6.95, "end": 7.3},
|
||||
{"text": "cinema.", "start": 7.3, "end": 7.7}
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
function normalizeWords(rawWords) {
|
||||
return rawWords.map(function (item) {
|
||||
var text = String(item.word || item.text || "").trim();
|
||||
return {
|
||||
text: text,
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
};
|
||||
}).filter(function (w) { return w.text.length > 0; });
|
||||
return rawWords
|
||||
.map(function (item) {
|
||||
var text = String(item.word || item.text || "").trim();
|
||||
return {
|
||||
text: text,
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
};
|
||||
})
|
||||
.filter(function (w) {
|
||||
return w.text.length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
var measureCanvas = document.createElement("canvas");
|
||||
@@ -216,13 +223,19 @@
|
||||
|
||||
function measureLineWidth(words, fontSize) {
|
||||
return words.reduce(function (total, word, index) {
|
||||
return total + measureWordWidth(word.text.toLowerCase(), fontSize) + (index ? WORD_SPACING : 0);
|
||||
return (
|
||||
total + measureWordWidth(word.text.toLowerCase(), fontSize) + (index ? WORD_SPACING : 0)
|
||||
);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function splitLinesForGroup(words, fontSize) {
|
||||
var maxLineWidth = PILL_MAX_WIDTH - PILL_MIN_PADDING_X * 2;
|
||||
if (words.some(function (w) { return measureWordWidth(w.text.toLowerCase(), fontSize) > maxLineWidth; })) {
|
||||
if (
|
||||
words.some(function (w) {
|
||||
return measureWordWidth(w.text.toLowerCase(), fontSize) > maxLineWidth;
|
||||
})
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
if (measureLineWidth(words, fontSize) <= maxLineWidth) return [words];
|
||||
@@ -269,7 +282,11 @@
|
||||
var wouldExceedTwoLines = !fitsInTwoLinesAtSize(testGroup, BASE_FONT_SIZE);
|
||||
if (wouldExceedMaxWords || wouldExceedTwoLines) {
|
||||
if (current.length) {
|
||||
groups.push({ words: current.slice(), start: current[0].start, end: current[current.length - 1].end });
|
||||
groups.push({
|
||||
words: current.slice(),
|
||||
start: current[0].start,
|
||||
end: current[current.length - 1].end,
|
||||
});
|
||||
}
|
||||
current = [word];
|
||||
return;
|
||||
@@ -280,17 +297,28 @@
|
||||
var hasNaturalPause = pauseDuration >= PAUSE_THRESHOLD;
|
||||
var maxWordsReached = current.length >= MAX_WORDS_PER_GROUP;
|
||||
if (maxWordsReached || !nextWord || hasPunctuation || hasNaturalPause) {
|
||||
groups.push({ words: current.slice(), start: current[0].start, end: current[current.length - 1].end });
|
||||
groups.push({
|
||||
words: current.slice(),
|
||||
start: current[0].start,
|
||||
end: current[current.length - 1].end,
|
||||
});
|
||||
current = [];
|
||||
}
|
||||
});
|
||||
if (current.length) groups.push({ words: current.slice(), start: current[0].start, end: current[current.length - 1].end });
|
||||
if (current.length)
|
||||
groups.push({
|
||||
words: current.slice(),
|
||||
start: current[0].start,
|
||||
end: current[current.length - 1].end,
|
||||
});
|
||||
return groups;
|
||||
}
|
||||
|
||||
function fontSizeForGroup(words) {
|
||||
var size = BASE_FONT_SIZE;
|
||||
while (size > MIN_FONT_SIZE && !fitsInTwoLinesAtSize(words, size)) { size -= 2; }
|
||||
while (size > MIN_FONT_SIZE && !fitsInTwoLinesAtSize(words, size)) {
|
||||
size -= 2;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -342,7 +370,9 @@
|
||||
var groupEl = document.getElementById("caption-group-" + groupIndex);
|
||||
var nextGroup = GROUPS[groupIndex + 1];
|
||||
var isLastGroup = groupIndex === GROUPS.length - 1;
|
||||
var effectiveEnd = isLastGroup ? DURATION : Math.min(nextGroup.start, group.end + GROUP_END_BUFFER);
|
||||
var effectiveEnd = isLastGroup
|
||||
? DURATION
|
||||
: Math.min(nextGroup.start, group.end + GROUP_END_BUFFER);
|
||||
var visibleStart = Math.max(0, group.start);
|
||||
var visibleEnd = Math.max(visibleStart + 0.01, effectiveEnd);
|
||||
|
||||
@@ -355,7 +385,11 @@
|
||||
var wordStart = Math.max(visibleStart, word.start - WORD_FADE_LEAD);
|
||||
tl.set(wordEl, { color: isFirstWord ? COLOR_ACTIVE : COLOR_INACTIVE }, visibleStart);
|
||||
if (isFirstWord) return;
|
||||
tl.to(wordEl, { color: COLOR_ACTIVE, duration: COLOR_FADE_DURATION, ease: "none" }, wordStart);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ color: COLOR_ACTIVE, duration: COLOR_FADE_DURATION, ease: "none" },
|
||||
wordStart,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+121
-84
@@ -25,25 +25,46 @@
|
||||
mask-image: url("/assets/texture-mask-text/masks/lava.png");
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #0a0805;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #0a0805;
|
||||
}
|
||||
#texture-lava {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #0a0805;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #0a0805;
|
||||
}
|
||||
#lv-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.lv-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.55); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.55);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#lv-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Lava-specific overrides for texture mask */
|
||||
@@ -59,18 +80,22 @@
|
||||
|
||||
.lv-shadow {
|
||||
position: absolute;
|
||||
left: 0; width: 100%; text-align: center;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
top: 50%;
|
||||
filter: drop-shadow(0 4px 24px rgba(255,100,20,0.55));
|
||||
opacity: 0; visibility: hidden;
|
||||
filter: drop-shadow(0 4px 24px rgba(255, 100, 20, 0.55));
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.lv-word {
|
||||
font-family: 'Anton', sans-serif;
|
||||
font-family: "Anton", sans-serif;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
color: #FFD0A0;
|
||||
color: #ffd0a0;
|
||||
display: inline-block;
|
||||
letter-spacing: 0.04em; line-height: 1;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -84,89 +109,101 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="lv-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="lv-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="lv-overlay"></div>
|
||||
<div id="lv-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var container = document.getElementById('lv-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
var container = document.getElementById("lv-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
WORDS.forEach(function(w, wi) {
|
||||
var txt = w.text.toUpperCase();
|
||||
var fontSize = 200;
|
||||
WORDS.forEach(function (w, wi) {
|
||||
var txt = w.text.toUpperCase();
|
||||
var fontSize = 200;
|
||||
|
||||
var shadow = document.createElement('div');
|
||||
shadow.className = 'lv-shadow';
|
||||
shadow.id = 'lv-shadow-' + wi;
|
||||
gsap.set(shadow, { yPercent: -50 });
|
||||
var shadow = document.createElement("div");
|
||||
shadow.className = "lv-shadow";
|
||||
shadow.id = "lv-shadow-" + wi;
|
||||
gsap.set(shadow, { yPercent: -50 });
|
||||
|
||||
var wordEl = document.createElement('div');
|
||||
wordEl.className = 'hf-texture-text hf-texture-lava lv-texture-override lv-word';
|
||||
wordEl.id = 'lv-word-' + wi;
|
||||
wordEl.textContent = txt;
|
||||
wordEl.style.fontSize = fontSize + 'px';
|
||||
if (KEYWORDS.has(wi)) wordEl.style.color = '#FFAA44';
|
||||
var wordEl = document.createElement("div");
|
||||
wordEl.className = "hf-texture-text hf-texture-lava lv-texture-override lv-word";
|
||||
wordEl.id = "lv-word-" + wi;
|
||||
wordEl.textContent = txt;
|
||||
wordEl.style.fontSize = fontSize + "px";
|
||||
if (KEYWORDS.has(wi)) wordEl.style.color = "#FFAA44";
|
||||
|
||||
shadow.appendChild(wordEl);
|
||||
container.appendChild(shadow);
|
||||
shadow.appendChild(wordEl);
|
||||
container.appendChild(shadow);
|
||||
|
||||
var dur = Math.max(w.end - w.start + 0.3, 0.4);
|
||||
var dur = Math.max(w.end - w.start + 0.3, 0.4);
|
||||
|
||||
tl.set(shadow, { visibility: 'visible', opacity: 0 }, w.start);
|
||||
tl.fromTo(shadow,
|
||||
{ opacity: 0, scale: 0.88 },
|
||||
{ opacity: 1, scale: 1, duration: 0.18, ease: 'power3.out' },
|
||||
w.start
|
||||
);
|
||||
tl.set(wordEl, { '--mask-position': '0% 50%' }, w.start);
|
||||
tl.to(wordEl, { '--mask-position': '100% 50%', duration: dur, ease: 'sine.inOut' }, w.start);
|
||||
tl.set(shadow, { visibility: "visible", opacity: 0 }, w.start);
|
||||
tl.fromTo(
|
||||
shadow,
|
||||
{ opacity: 0, scale: 0.88 },
|
||||
{ opacity: 1, scale: 1, duration: 0.18, ease: "power3.out" },
|
||||
w.start,
|
||||
);
|
||||
tl.set(wordEl, { "--mask-position": "0% 50%" }, w.start);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ "--mask-position": "100% 50%", duration: dur, ease: "sine.inOut" },
|
||||
w.start,
|
||||
);
|
||||
|
||||
tl.to(shadow, { opacity: 0, scale: 1.08, duration: 0.1, ease: 'power2.in' }, w.end);
|
||||
tl.set(shadow, { opacity: 0, visibility: 'hidden' }, w.end + 0.1);
|
||||
});
|
||||
tl.to(shadow, { opacity: 0, scale: 1.08, duration: 0.1, ease: "power2.in" }, w.end);
|
||||
tl.set(shadow, { opacity: 0, visibility: "hidden" }, w.end + 0.1);
|
||||
});
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines['texture-lava'] = tl;
|
||||
})();
|
||||
tl.seek(0);
|
||||
window.__timelines["texture-lava"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+121
-84
@@ -25,25 +25,46 @@
|
||||
mask-image: url("/assets/texture-mask-text/masks/lava.png");
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #0a0805;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #0a0805;
|
||||
}
|
||||
#texture-lava {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #0a0805;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #0a0805;
|
||||
}
|
||||
#lv-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.lv-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.55); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.55);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#lv-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Lava-specific overrides for texture mask */
|
||||
@@ -59,18 +80,22 @@
|
||||
|
||||
.lv-shadow {
|
||||
position: absolute;
|
||||
left: 0; width: 100%; text-align: center;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
top: 50%;
|
||||
filter: drop-shadow(0 4px 24px rgba(255,100,20,0.55));
|
||||
opacity: 0; visibility: hidden;
|
||||
filter: drop-shadow(0 4px 24px rgba(255, 100, 20, 0.55));
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.lv-word {
|
||||
font-family: 'Anton', sans-serif;
|
||||
font-family: "Anton", sans-serif;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
color: #FFD0A0;
|
||||
color: #ffd0a0;
|
||||
display: inline-block;
|
||||
letter-spacing: 0.04em; line-height: 1;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -84,89 +109,101 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="lv-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="lv-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="lv-overlay"></div>
|
||||
<div id="lv-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
var KEYWORDS = new Set([8, 12, 15, 24, 27]); // HyperFrames, HTML, professional, code, cinema.
|
||||
|
||||
var container = document.getElementById('lv-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
var container = document.getElementById("lv-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
WORDS.forEach(function(w, wi) {
|
||||
var txt = w.text.toUpperCase();
|
||||
var fontSize = 200;
|
||||
WORDS.forEach(function (w, wi) {
|
||||
var txt = w.text.toUpperCase();
|
||||
var fontSize = 200;
|
||||
|
||||
var shadow = document.createElement('div');
|
||||
shadow.className = 'lv-shadow';
|
||||
shadow.id = 'lv-shadow-' + wi;
|
||||
gsap.set(shadow, { yPercent: -50 });
|
||||
var shadow = document.createElement("div");
|
||||
shadow.className = "lv-shadow";
|
||||
shadow.id = "lv-shadow-" + wi;
|
||||
gsap.set(shadow, { yPercent: -50 });
|
||||
|
||||
var wordEl = document.createElement('div');
|
||||
wordEl.className = 'hf-texture-text hf-texture-lava lv-texture-override lv-word';
|
||||
wordEl.id = 'lv-word-' + wi;
|
||||
wordEl.textContent = txt;
|
||||
wordEl.style.fontSize = fontSize + 'px';
|
||||
if (KEYWORDS.has(wi)) wordEl.style.color = '#FFAA44';
|
||||
var wordEl = document.createElement("div");
|
||||
wordEl.className = "hf-texture-text hf-texture-lava lv-texture-override lv-word";
|
||||
wordEl.id = "lv-word-" + wi;
|
||||
wordEl.textContent = txt;
|
||||
wordEl.style.fontSize = fontSize + "px";
|
||||
if (KEYWORDS.has(wi)) wordEl.style.color = "#FFAA44";
|
||||
|
||||
shadow.appendChild(wordEl);
|
||||
container.appendChild(shadow);
|
||||
shadow.appendChild(wordEl);
|
||||
container.appendChild(shadow);
|
||||
|
||||
var dur = Math.max(w.end - w.start + 0.3, 0.4);
|
||||
var dur = Math.max(w.end - w.start + 0.3, 0.4);
|
||||
|
||||
tl.set(shadow, { visibility: 'visible', opacity: 0 }, w.start);
|
||||
tl.fromTo(shadow,
|
||||
{ opacity: 0, scale: 0.88 },
|
||||
{ opacity: 1, scale: 1, duration: 0.18, ease: 'power3.out' },
|
||||
w.start
|
||||
);
|
||||
tl.set(wordEl, { '--mask-position': '0% 50%' }, w.start);
|
||||
tl.to(wordEl, { '--mask-position': '100% 50%', duration: dur, ease: 'sine.inOut' }, w.start);
|
||||
tl.set(shadow, { visibility: "visible", opacity: 0 }, w.start);
|
||||
tl.fromTo(
|
||||
shadow,
|
||||
{ opacity: 0, scale: 0.88 },
|
||||
{ opacity: 1, scale: 1, duration: 0.18, ease: "power3.out" },
|
||||
w.start,
|
||||
);
|
||||
tl.set(wordEl, { "--mask-position": "0% 50%" }, w.start);
|
||||
tl.to(
|
||||
wordEl,
|
||||
{ "--mask-position": "100% 50%", duration: dur, ease: "sine.inOut" },
|
||||
w.start,
|
||||
);
|
||||
|
||||
tl.to(shadow, { opacity: 0, scale: 1.08, duration: 0.1, ease: 'power2.in' }, w.end);
|
||||
tl.set(shadow, { opacity: 0, visibility: 'hidden' }, w.end + 0.1);
|
||||
});
|
||||
tl.to(shadow, { opacity: 0, scale: 1.08, duration: 0.1, ease: "power2.in" }, w.end);
|
||||
tl.set(shadow, { opacity: 0, visibility: "hidden" }, w.end + 0.1);
|
||||
});
|
||||
|
||||
tl.seek(0);
|
||||
window.__timelines['texture-lava'] = tl;
|
||||
})();
|
||||
tl.seek(0);
|
||||
window.__timelines["texture-lava"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+165
-120
@@ -6,49 +6,87 @@
|
||||
<title>Typewriter</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@700&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #000;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
#typewriter {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #000;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
#tw-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.tw-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.85); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#tw-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.tw-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 80px;
|
||||
opacity: 0; visibility: hidden;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 80px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.tw-word {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-weight: 700; font-size: 76px;
|
||||
color: #00FF41;
|
||||
text-shadow: 0 0 12px rgba(0,255,65,0.5);
|
||||
display: inline-block; letter-spacing: 0.04em; line-height: 1; white-space: nowrap;
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-weight: 700;
|
||||
font-size: 76px;
|
||||
color: #00ff41;
|
||||
text-shadow: 0 0 12px rgba(0, 255, 65, 0.5);
|
||||
display: inline-block;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.tw-char {
|
||||
display: none;
|
||||
}
|
||||
.tw-char { display: none; }
|
||||
.tw-cursor {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-weight: 700; font-size: 76px;
|
||||
color: #00FF41;
|
||||
text-shadow: 0 0 12px rgba(0,255,65,0.5);
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-weight: 700;
|
||||
font-size: 76px;
|
||||
color: #00ff41;
|
||||
text-shadow: 0 0 12px rgba(0, 255, 65, 0.5);
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -63,119 +101,126 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="tw-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="tw-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="tw-overlay"></div>
|
||||
<div id="tw-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
var GROUPS = [
|
||||
{wordStart:0, wordEnd:3, start:0.0, end:1.1},
|
||||
{wordStart:4, wordEnd:7, start:1.1, end:2.05},
|
||||
{wordStart:8, wordEnd:8, start:2.1, end:2.6},
|
||||
{wordStart:9, wordEnd:12, start:2.65, end:3.5},
|
||||
{wordStart:13, wordEnd:15, start:3.55, end:4.4},
|
||||
{wordStart:16, wordEnd:16, start:3.95, end:4.75},
|
||||
{wordStart:17, wordEnd:19, start:4.9, end:5.4},
|
||||
{wordStart:20, wordEnd:22, start:5.65, end:6.2},
|
||||
{wordStart:23, wordEnd:24, start:6.35, end:6.75},
|
||||
{wordStart:25, wordEnd:27, start:6.8, end:7.8},
|
||||
];
|
||||
var GROUPS = [
|
||||
{ wordStart: 0, wordEnd: 3, start: 0.0, end: 1.1 },
|
||||
{ wordStart: 4, wordEnd: 7, start: 1.1, end: 2.05 },
|
||||
{ wordStart: 8, wordEnd: 8, start: 2.1, end: 2.6 },
|
||||
{ wordStart: 9, wordEnd: 12, start: 2.65, end: 3.5 },
|
||||
{ wordStart: 13, wordEnd: 15, start: 3.55, end: 4.4 },
|
||||
{ wordStart: 16, wordEnd: 16, start: 3.95, end: 4.75 },
|
||||
{ wordStart: 17, wordEnd: 19, start: 4.9, end: 5.4 },
|
||||
{ wordStart: 20, wordEnd: 22, start: 5.65, end: 6.2 },
|
||||
{ wordStart: 23, wordEnd: 24, start: 6.35, end: 6.75 },
|
||||
{ wordStart: 25, wordEnd: 27, start: 6.8, end: 7.8 },
|
||||
];
|
||||
|
||||
var container = document.getElementById('tw-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
var container = document.getElementById("tw-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var fontSize = 76;
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'tw-group';
|
||||
grp.id = 'tw-grp-' + gi;
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var fontSize = 76;
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "tw-group";
|
||||
grp.id = "tw-grp-" + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordWrap = document.createElement('span');
|
||||
wordWrap.className = 'tw-word';
|
||||
wordWrap.id = 'tw-w-' + wi;
|
||||
wordWrap.style.fontSize = fontSize + 'px';
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordWrap = document.createElement("span");
|
||||
wordWrap.className = "tw-word";
|
||||
wordWrap.id = "tw-w-" + wi;
|
||||
wordWrap.style.fontSize = fontSize + "px";
|
||||
|
||||
w.text.split('').forEach(function(c, ci) {
|
||||
var charEl = document.createElement('span');
|
||||
charEl.className = 'tw-char';
|
||||
charEl.id = 'tw-c-' + wi + '-' + ci;
|
||||
charEl.textContent = c;
|
||||
wordWrap.appendChild(charEl);
|
||||
w.text.split("").forEach(function (c, ci) {
|
||||
var charEl = document.createElement("span");
|
||||
charEl.className = "tw-char";
|
||||
charEl.id = "tw-c-" + wi + "-" + ci;
|
||||
charEl.textContent = c;
|
||||
wordWrap.appendChild(charEl);
|
||||
});
|
||||
|
||||
var cursor = document.createElement("span");
|
||||
cursor.className = "tw-cursor";
|
||||
cursor.id = "tw-cur-" + wi;
|
||||
cursor.textContent = "_";
|
||||
cursor.style.fontSize = fontSize + "px";
|
||||
wordWrap.appendChild(cursor);
|
||||
grp.appendChild(wordWrap);
|
||||
});
|
||||
|
||||
var cursor = document.createElement('span');
|
||||
cursor.className = 'tw-cursor';
|
||||
cursor.id = 'tw-cur-' + wi;
|
||||
cursor.textContent = '_';
|
||||
cursor.style.fontSize = fontSize + 'px';
|
||||
wordWrap.appendChild(cursor);
|
||||
grp.appendChild(wordWrap);
|
||||
});
|
||||
container.appendChild(grp);
|
||||
|
||||
container.appendChild(grp);
|
||||
tl.set(grp, { visibility: "visible", opacity: 1 }, g.start);
|
||||
|
||||
tl.set(grp, { visibility: 'visible', opacity: 1 }, g.start);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var chars = w.text.split("");
|
||||
var wordDuration = Math.max(w.end - w.start, 0.1);
|
||||
var charCount = chars.length;
|
||||
var cursorEl = document.getElementById("tw-cur-" + wi);
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var chars = w.text.split('');
|
||||
var wordDuration = Math.max(w.end - w.start, 0.1);
|
||||
var charCount = chars.length;
|
||||
var cursorEl = document.getElementById('tw-cur-' + wi);
|
||||
|
||||
tl.set(cursorEl, { display: 'inline' }, w.start);
|
||||
chars.forEach(function(c, ci) {
|
||||
var charEl = document.getElementById('tw-c-' + wi + '-' + ci);
|
||||
tl.set(charEl, { display: 'inline' }, w.start + ci * (wordDuration / charCount));
|
||||
tl.set(cursorEl, { display: "inline" }, w.start);
|
||||
chars.forEach(function (c, ci) {
|
||||
var charEl = document.getElementById("tw-c-" + wi + "-" + ci);
|
||||
tl.set(charEl, { display: "inline" }, w.start + ci * (wordDuration / charCount));
|
||||
});
|
||||
tl.set(cursorEl, { display: "none" }, w.end);
|
||||
});
|
||||
tl.set(cursorEl, { display: 'none' }, w.end);
|
||||
|
||||
tl.to(grp, { opacity: 0, duration: 0.2 }, g.end - 0.2);
|
||||
tl.set(grp, { opacity: 0, visibility: "hidden" }, g.end);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, duration: 0.2 }, g.end - 0.2);
|
||||
tl.set(grp, { opacity: 0, visibility: 'hidden' }, g.end);
|
||||
});
|
||||
|
||||
window.__timelines['typewriter'] = tl;
|
||||
})();
|
||||
window.__timelines["typewriter"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+165
-120
@@ -6,49 +6,87 @@
|
||||
<title>Typewriter</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@700&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
html, body {
|
||||
width: 1920px; height: 1080px; margin: 0;
|
||||
overflow: hidden; background: #000;
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
#typewriter {
|
||||
position: relative; width: 1920px; height: 1080px;
|
||||
overflow: hidden; background: #000;
|
||||
position: relative;
|
||||
width: 1920px;
|
||||
height: 1080px;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
}
|
||||
#tw-video {
|
||||
position: absolute; inset: 0; z-index: 0;
|
||||
width: 100%; height: 100%; object-fit: cover;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.tw-overlay {
|
||||
position: absolute; inset: 0;
|
||||
background: rgba(0,0,0,0.85); z-index: 1; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
#tw-container {
|
||||
position: absolute; inset: 0; z-index: 10; pointer-events: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
pointer-events: none;
|
||||
}
|
||||
.tw-group {
|
||||
position: absolute;
|
||||
bottom: 120px; left: 0; width: 100%;
|
||||
display: flex; flex-wrap: wrap; align-items: flex-end;
|
||||
justify-content: center; gap: 24px; padding: 0 80px;
|
||||
opacity: 0; visibility: hidden;
|
||||
bottom: 120px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
padding: 0 80px;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.tw-word {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-weight: 700; font-size: 76px;
|
||||
color: #00FF41;
|
||||
text-shadow: 0 0 12px rgba(0,255,65,0.5);
|
||||
display: inline-block; letter-spacing: 0.04em; line-height: 1; white-space: nowrap;
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-weight: 700;
|
||||
font-size: 76px;
|
||||
color: #00ff41;
|
||||
text-shadow: 0 0 12px rgba(0, 255, 65, 0.5);
|
||||
display: inline-block;
|
||||
letter-spacing: 0.04em;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.tw-char {
|
||||
display: none;
|
||||
}
|
||||
.tw-char { display: none; }
|
||||
.tw-cursor {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-weight: 700; font-size: 76px;
|
||||
color: #00FF41;
|
||||
text-shadow: 0 0 12px rgba(0,255,65,0.5);
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
font-weight: 700;
|
||||
font-size: 76px;
|
||||
color: #00ff41;
|
||||
text-shadow: 0 0 12px rgba(0, 255, 65, 0.5);
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -63,119 +101,126 @@
|
||||
data-width="1920"
|
||||
data-height="1080"
|
||||
>
|
||||
<video id="tw-video" muted playsinline
|
||||
data-start="0" data-duration="8" data-track-index="0" data-has-audio="false"></video>
|
||||
<video
|
||||
id="tw-video"
|
||||
muted
|
||||
playsinline
|
||||
data-start="0"
|
||||
data-duration="8"
|
||||
data-track-index="0"
|
||||
data-has-audio="false"
|
||||
></video>
|
||||
<div class="tw-overlay"></div>
|
||||
<div id="tw-container"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
(function () {
|
||||
window.__timelines = window.__timelines || {};
|
||||
|
||||
var WORDS = [
|
||||
{text:"Every", start:0.0, end:0.3},
|
||||
{text:"great", start:0.3, end:0.55},
|
||||
{text:"video", start:0.55, end:0.85},
|
||||
{text:"starts", start:0.85, end:1.1},
|
||||
{text:"with", start:1.1, end:1.25},
|
||||
{text:"a", start:1.25, end:1.35},
|
||||
{text:"single", start:1.35, end:1.65},
|
||||
{text:"frame.", start:1.65, end:2.0},
|
||||
{text:"HyperFrames", start:2.1, end:2.65},
|
||||
{text:"lets", start:2.65, end:2.85},
|
||||
{text:"you", start:2.85, end:2.95},
|
||||
{text:"write", start:2.95, end:3.15},
|
||||
{text:"HTML", start:3.15, end:3.55},
|
||||
{text:"and", start:3.55, end:3.65},
|
||||
{text:"render", start:3.65, end:3.95},
|
||||
{text:"professional",start:3.95, end:4.45},
|
||||
{text:"video.", start:4.45, end:4.8},
|
||||
{text:"No", start:4.9, end:5.05},
|
||||
{text:"timeline.", start:5.05, end:5.45},
|
||||
{text:"No", start:5.5, end:5.65},
|
||||
{text:"drag", start:5.65, end:5.85},
|
||||
{text:"and", start:5.85, end:5.95},
|
||||
{text:"drop.", start:5.95, end:6.25},
|
||||
{text:"Just", start:6.35, end:6.55},
|
||||
{text:"code", start:6.55, end:6.8},
|
||||
{text:"that", start:6.8, end:6.95},
|
||||
{text:"becomes", start:6.95, end:7.3},
|
||||
{text:"cinema.", start:7.3, end:7.7}
|
||||
];
|
||||
var WORDS = [
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
var GROUPS = [
|
||||
{wordStart:0, wordEnd:3, start:0.0, end:1.1},
|
||||
{wordStart:4, wordEnd:7, start:1.1, end:2.05},
|
||||
{wordStart:8, wordEnd:8, start:2.1, end:2.6},
|
||||
{wordStart:9, wordEnd:12, start:2.65, end:3.5},
|
||||
{wordStart:13, wordEnd:15, start:3.55, end:4.4},
|
||||
{wordStart:16, wordEnd:16, start:3.95, end:4.75},
|
||||
{wordStart:17, wordEnd:19, start:4.9, end:5.4},
|
||||
{wordStart:20, wordEnd:22, start:5.65, end:6.2},
|
||||
{wordStart:23, wordEnd:24, start:6.35, end:6.75},
|
||||
{wordStart:25, wordEnd:27, start:6.8, end:7.8},
|
||||
];
|
||||
var GROUPS = [
|
||||
{ wordStart: 0, wordEnd: 3, start: 0.0, end: 1.1 },
|
||||
{ wordStart: 4, wordEnd: 7, start: 1.1, end: 2.05 },
|
||||
{ wordStart: 8, wordEnd: 8, start: 2.1, end: 2.6 },
|
||||
{ wordStart: 9, wordEnd: 12, start: 2.65, end: 3.5 },
|
||||
{ wordStart: 13, wordEnd: 15, start: 3.55, end: 4.4 },
|
||||
{ wordStart: 16, wordEnd: 16, start: 3.95, end: 4.75 },
|
||||
{ wordStart: 17, wordEnd: 19, start: 4.9, end: 5.4 },
|
||||
{ wordStart: 20, wordEnd: 22, start: 5.65, end: 6.2 },
|
||||
{ wordStart: 23, wordEnd: 24, start: 6.35, end: 6.75 },
|
||||
{ wordStart: 25, wordEnd: 27, start: 6.8, end: 7.8 },
|
||||
];
|
||||
|
||||
var container = document.getElementById('tw-container');
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
var container = document.getElementById("tw-container");
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
|
||||
GROUPS.forEach(function(g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var fontSize = 76;
|
||||
var grp = document.createElement('div');
|
||||
grp.className = 'tw-group';
|
||||
grp.id = 'tw-grp-' + gi;
|
||||
GROUPS.forEach(function (g, gi) {
|
||||
var groupWords = WORDS.slice(g.wordStart, g.wordEnd + 1);
|
||||
var fontSize = 76;
|
||||
var grp = document.createElement("div");
|
||||
grp.className = "tw-group";
|
||||
grp.id = "tw-grp-" + gi;
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordWrap = document.createElement('span');
|
||||
wordWrap.className = 'tw-word';
|
||||
wordWrap.id = 'tw-w-' + wi;
|
||||
wordWrap.style.fontSize = fontSize + 'px';
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var wordWrap = document.createElement("span");
|
||||
wordWrap.className = "tw-word";
|
||||
wordWrap.id = "tw-w-" + wi;
|
||||
wordWrap.style.fontSize = fontSize + "px";
|
||||
|
||||
w.text.split('').forEach(function(c, ci) {
|
||||
var charEl = document.createElement('span');
|
||||
charEl.className = 'tw-char';
|
||||
charEl.id = 'tw-c-' + wi + '-' + ci;
|
||||
charEl.textContent = c;
|
||||
wordWrap.appendChild(charEl);
|
||||
w.text.split("").forEach(function (c, ci) {
|
||||
var charEl = document.createElement("span");
|
||||
charEl.className = "tw-char";
|
||||
charEl.id = "tw-c-" + wi + "-" + ci;
|
||||
charEl.textContent = c;
|
||||
wordWrap.appendChild(charEl);
|
||||
});
|
||||
|
||||
var cursor = document.createElement("span");
|
||||
cursor.className = "tw-cursor";
|
||||
cursor.id = "tw-cur-" + wi;
|
||||
cursor.textContent = "_";
|
||||
cursor.style.fontSize = fontSize + "px";
|
||||
wordWrap.appendChild(cursor);
|
||||
grp.appendChild(wordWrap);
|
||||
});
|
||||
|
||||
var cursor = document.createElement('span');
|
||||
cursor.className = 'tw-cursor';
|
||||
cursor.id = 'tw-cur-' + wi;
|
||||
cursor.textContent = '_';
|
||||
cursor.style.fontSize = fontSize + 'px';
|
||||
wordWrap.appendChild(cursor);
|
||||
grp.appendChild(wordWrap);
|
||||
});
|
||||
container.appendChild(grp);
|
||||
|
||||
container.appendChild(grp);
|
||||
tl.set(grp, { visibility: "visible", opacity: 1 }, g.start);
|
||||
|
||||
tl.set(grp, { visibility: 'visible', opacity: 1 }, g.start);
|
||||
groupWords.forEach(function (w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var chars = w.text.split("");
|
||||
var wordDuration = Math.max(w.end - w.start, 0.1);
|
||||
var charCount = chars.length;
|
||||
var cursorEl = document.getElementById("tw-cur-" + wi);
|
||||
|
||||
groupWords.forEach(function(w, i) {
|
||||
var wi = g.wordStart + i;
|
||||
var chars = w.text.split('');
|
||||
var wordDuration = Math.max(w.end - w.start, 0.1);
|
||||
var charCount = chars.length;
|
||||
var cursorEl = document.getElementById('tw-cur-' + wi);
|
||||
|
||||
tl.set(cursorEl, { display: 'inline' }, w.start);
|
||||
chars.forEach(function(c, ci) {
|
||||
var charEl = document.getElementById('tw-c-' + wi + '-' + ci);
|
||||
tl.set(charEl, { display: 'inline' }, w.start + ci * (wordDuration / charCount));
|
||||
tl.set(cursorEl, { display: "inline" }, w.start);
|
||||
chars.forEach(function (c, ci) {
|
||||
var charEl = document.getElementById("tw-c-" + wi + "-" + ci);
|
||||
tl.set(charEl, { display: "inline" }, w.start + ci * (wordDuration / charCount));
|
||||
});
|
||||
tl.set(cursorEl, { display: "none" }, w.end);
|
||||
});
|
||||
tl.set(cursorEl, { display: 'none' }, w.end);
|
||||
|
||||
tl.to(grp, { opacity: 0, duration: 0.2 }, g.end - 0.2);
|
||||
tl.set(grp, { opacity: 0, visibility: "hidden" }, g.end);
|
||||
});
|
||||
|
||||
tl.to(grp, { opacity: 0, duration: 0.2 }, g.end - 0.2);
|
||||
tl.set(grp, { opacity: 0, visibility: 'hidden' }, g.end);
|
||||
});
|
||||
|
||||
window.__timelines['typewriter'] = tl;
|
||||
})();
|
||||
window.__timelines["typewriter"] = tl;
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
<title>Weight Shift</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;700&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*,
|
||||
@@ -145,44 +148,48 @@
|
||||
var FONT_WEIGHT_BOLD = 700;
|
||||
|
||||
var TRANSCRIPT = [
|
||||
{"text": "Every", "start": 0.0, "end": 0.3},
|
||||
{"text": "great", "start": 0.3, "end": 0.55},
|
||||
{"text": "video", "start": 0.55, "end": 0.85},
|
||||
{"text": "starts", "start": 0.85, "end": 1.1},
|
||||
{"text": "with", "start": 1.1, "end": 1.25},
|
||||
{"text": "a", "start": 1.25, "end": 1.35},
|
||||
{"text": "single", "start": 1.35, "end": 1.65},
|
||||
{"text": "frame.", "start": 1.65, "end": 2.0},
|
||||
{"text": "HyperFrames", "start": 2.1, "end": 2.65},
|
||||
{"text": "lets", "start": 2.65, "end": 2.85},
|
||||
{"text": "you", "start": 2.85, "end": 2.95},
|
||||
{"text": "write", "start": 2.95, "end": 3.15},
|
||||
{"text": "HTML", "start": 3.15, "end": 3.55},
|
||||
{"text": "and", "start": 3.55, "end": 3.65},
|
||||
{"text": "render", "start": 3.65, "end": 3.95},
|
||||
{"text": "professional", "start": 3.95, "end": 4.45},
|
||||
{"text": "video.", "start": 4.45, "end": 4.8},
|
||||
{"text": "No", "start": 4.9, "end": 5.05},
|
||||
{"text": "timeline.", "start": 5.05, "end": 5.45},
|
||||
{"text": "No", "start": 5.5, "end": 5.65},
|
||||
{"text": "drag", "start": 5.65, "end": 5.85},
|
||||
{"text": "and", "start": 5.85, "end": 5.95},
|
||||
{"text": "drop.", "start": 5.95, "end": 6.25},
|
||||
{"text": "Just", "start": 6.35, "end": 6.55},
|
||||
{"text": "code", "start": 6.55, "end": 6.8},
|
||||
{"text": "that", "start": 6.8, "end": 6.95},
|
||||
{"text": "becomes", "start": 6.95, "end": 7.3},
|
||||
{"text": "cinema.", "start": 7.3, "end": 7.7}
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
function normalizeWords(rawWords) {
|
||||
return rawWords.map(function (item) {
|
||||
return {
|
||||
text: String(item.word || item.text || "").trim(),
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
};
|
||||
}).filter(function (word) { return word.text.length > 0; });
|
||||
return rawWords
|
||||
.map(function (item) {
|
||||
return {
|
||||
text: String(item.word || item.text || "").trim(),
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
};
|
||||
})
|
||||
.filter(function (word) {
|
||||
return word.text.length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
var measureCanvas = document.createElement("canvas");
|
||||
@@ -214,7 +221,10 @@
|
||||
var w2 = measureLineWidth(words.slice(s));
|
||||
if (w1 <= MAX_LINE_WIDTH && w2 <= MAX_LINE_WIDTH) {
|
||||
var diff = Math.abs(w1 - w2);
|
||||
if (diff < bestDiff) { bestDiff = diff; bestSplit = s; }
|
||||
if (diff < bestDiff) {
|
||||
bestDiff = diff;
|
||||
bestSplit = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
var result = [];
|
||||
@@ -239,7 +249,12 @@
|
||||
current.push(word);
|
||||
var punctuation = /[,.:!?]$/.test(word.text);
|
||||
var pause = nextWord ? nextWord.start - word.end : 0;
|
||||
if (!nextWord || punctuation || pause >= PAUSE_THRESHOLD || current.length >= MAX_WORDS_PER_GROUP) {
|
||||
if (
|
||||
!nextWord ||
|
||||
punctuation ||
|
||||
pause >= PAUSE_THRESHOLD ||
|
||||
current.length >= MAX_WORDS_PER_GROUP
|
||||
) {
|
||||
groups.push(makeGroup(current));
|
||||
current = [];
|
||||
}
|
||||
@@ -249,7 +264,12 @@
|
||||
}
|
||||
|
||||
function makeGroup(words) {
|
||||
return { words: words.slice(), lines: splitLines(words), start: words[0].start, end: words[words.length - 1].end };
|
||||
return {
|
||||
words: words.slice(),
|
||||
lines: splitLines(words),
|
||||
start: words[0].start,
|
||||
end: words[words.length - 1].end,
|
||||
};
|
||||
}
|
||||
|
||||
function buildCaptions(groups) {
|
||||
@@ -291,7 +311,9 @@
|
||||
return Math.max(0, group.start - entryLead);
|
||||
});
|
||||
|
||||
var allGroupEls = GROUPS.map(function (_, i) { return document.getElementById("caption-group-" + i); });
|
||||
var allGroupEls = GROUPS.map(function (_, i) {
|
||||
return document.getElementById("caption-group-" + i);
|
||||
});
|
||||
|
||||
GROUPS.forEach(function (group, groupIndex) {
|
||||
var groupEl = allGroupEls[groupIndex];
|
||||
@@ -303,15 +325,27 @@
|
||||
});
|
||||
|
||||
tl.set(groupEl, { opacity: 0, scale: 0.85 }, visibleStart);
|
||||
tl.to(groupEl, { opacity: 1, scale: 1, duration: ENTRY_DURATION, ease: "power3.out", force3D: true }, visibleStart);
|
||||
tl.to(
|
||||
groupEl,
|
||||
{ opacity: 1, scale: 1, duration: ENTRY_DURATION, ease: "power3.out", force3D: true },
|
||||
visibleStart,
|
||||
);
|
||||
|
||||
if (group.lines.length === 2) {
|
||||
var line1El = document.getElementById("caption-group-" + groupIndex + "-line-0");
|
||||
var line2El = document.getElementById("caption-group-" + groupIndex + "-line-1");
|
||||
var line2FirstWord = group.lines[1].words[0];
|
||||
var switchTime = line2FirstWord.start;
|
||||
tl.to(line1El, { fontWeight: FONT_WEIGHT_LIGHT, duration: WEIGHT_TRANSITION, ease: "power2.out" }, switchTime);
|
||||
tl.to(line2El, { fontWeight: FONT_WEIGHT_BOLD, duration: WEIGHT_TRANSITION, ease: "power2.out" }, switchTime);
|
||||
tl.to(
|
||||
line1El,
|
||||
{ fontWeight: FONT_WEIGHT_LIGHT, duration: WEIGHT_TRANSITION, ease: "power2.out" },
|
||||
switchTime,
|
||||
);
|
||||
tl.to(
|
||||
line2El,
|
||||
{ fontWeight: FONT_WEIGHT_BOLD, duration: WEIGHT_TRANSITION, ease: "power2.out" },
|
||||
switchTime,
|
||||
);
|
||||
}
|
||||
|
||||
tl.set(groupEl, { opacity: 0 }, visibleEnd);
|
||||
|
||||
+77
-43
@@ -6,7 +6,10 @@
|
||||
<title>Weight Shift</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;700&display=swap" rel="stylesheet" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;700&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
*,
|
||||
@@ -145,44 +148,48 @@
|
||||
var FONT_WEIGHT_BOLD = 700;
|
||||
|
||||
var TRANSCRIPT = [
|
||||
{"text": "Every", "start": 0.0, "end": 0.3},
|
||||
{"text": "great", "start": 0.3, "end": 0.55},
|
||||
{"text": "video", "start": 0.55, "end": 0.85},
|
||||
{"text": "starts", "start": 0.85, "end": 1.1},
|
||||
{"text": "with", "start": 1.1, "end": 1.25},
|
||||
{"text": "a", "start": 1.25, "end": 1.35},
|
||||
{"text": "single", "start": 1.35, "end": 1.65},
|
||||
{"text": "frame.", "start": 1.65, "end": 2.0},
|
||||
{"text": "HyperFrames", "start": 2.1, "end": 2.65},
|
||||
{"text": "lets", "start": 2.65, "end": 2.85},
|
||||
{"text": "you", "start": 2.85, "end": 2.95},
|
||||
{"text": "write", "start": 2.95, "end": 3.15},
|
||||
{"text": "HTML", "start": 3.15, "end": 3.55},
|
||||
{"text": "and", "start": 3.55, "end": 3.65},
|
||||
{"text": "render", "start": 3.65, "end": 3.95},
|
||||
{"text": "professional", "start": 3.95, "end": 4.45},
|
||||
{"text": "video.", "start": 4.45, "end": 4.8},
|
||||
{"text": "No", "start": 4.9, "end": 5.05},
|
||||
{"text": "timeline.", "start": 5.05, "end": 5.45},
|
||||
{"text": "No", "start": 5.5, "end": 5.65},
|
||||
{"text": "drag", "start": 5.65, "end": 5.85},
|
||||
{"text": "and", "start": 5.85, "end": 5.95},
|
||||
{"text": "drop.", "start": 5.95, "end": 6.25},
|
||||
{"text": "Just", "start": 6.35, "end": 6.55},
|
||||
{"text": "code", "start": 6.55, "end": 6.8},
|
||||
{"text": "that", "start": 6.8, "end": 6.95},
|
||||
{"text": "becomes", "start": 6.95, "end": 7.3},
|
||||
{"text": "cinema.", "start": 7.3, "end": 7.7}
|
||||
{ text: "Every", start: 0.0, end: 0.3 },
|
||||
{ text: "great", start: 0.3, end: 0.55 },
|
||||
{ text: "video", start: 0.55, end: 0.85 },
|
||||
{ text: "starts", start: 0.85, end: 1.1 },
|
||||
{ text: "with", start: 1.1, end: 1.25 },
|
||||
{ text: "a", start: 1.25, end: 1.35 },
|
||||
{ text: "single", start: 1.35, end: 1.65 },
|
||||
{ text: "frame.", start: 1.65, end: 2.0 },
|
||||
{ text: "HyperFrames", start: 2.1, end: 2.65 },
|
||||
{ text: "lets", start: 2.65, end: 2.85 },
|
||||
{ text: "you", start: 2.85, end: 2.95 },
|
||||
{ text: "write", start: 2.95, end: 3.15 },
|
||||
{ text: "HTML", start: 3.15, end: 3.55 },
|
||||
{ text: "and", start: 3.55, end: 3.65 },
|
||||
{ text: "render", start: 3.65, end: 3.95 },
|
||||
{ text: "professional", start: 3.95, end: 4.45 },
|
||||
{ text: "video.", start: 4.45, end: 4.8 },
|
||||
{ text: "No", start: 4.9, end: 5.05 },
|
||||
{ text: "timeline.", start: 5.05, end: 5.45 },
|
||||
{ text: "No", start: 5.5, end: 5.65 },
|
||||
{ text: "drag", start: 5.65, end: 5.85 },
|
||||
{ text: "and", start: 5.85, end: 5.95 },
|
||||
{ text: "drop.", start: 5.95, end: 6.25 },
|
||||
{ text: "Just", start: 6.35, end: 6.55 },
|
||||
{ text: "code", start: 6.55, end: 6.8 },
|
||||
{ text: "that", start: 6.8, end: 6.95 },
|
||||
{ text: "becomes", start: 6.95, end: 7.3 },
|
||||
{ text: "cinema.", start: 7.3, end: 7.7 },
|
||||
];
|
||||
|
||||
function normalizeWords(rawWords) {
|
||||
return rawWords.map(function (item) {
|
||||
return {
|
||||
text: String(item.word || item.text || "").trim(),
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
};
|
||||
}).filter(function (word) { return word.text.length > 0; });
|
||||
return rawWords
|
||||
.map(function (item) {
|
||||
return {
|
||||
text: String(item.word || item.text || "").trim(),
|
||||
start: Math.max(0, Number(item.start) || 0),
|
||||
end: Math.min(DURATION, Math.max(Number(item.start) || 0, Number(item.end) || 0)),
|
||||
};
|
||||
})
|
||||
.filter(function (word) {
|
||||
return word.text.length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
var measureCanvas = document.createElement("canvas");
|
||||
@@ -214,7 +221,10 @@
|
||||
var w2 = measureLineWidth(words.slice(s));
|
||||
if (w1 <= MAX_LINE_WIDTH && w2 <= MAX_LINE_WIDTH) {
|
||||
var diff = Math.abs(w1 - w2);
|
||||
if (diff < bestDiff) { bestDiff = diff; bestSplit = s; }
|
||||
if (diff < bestDiff) {
|
||||
bestDiff = diff;
|
||||
bestSplit = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
var result = [];
|
||||
@@ -239,7 +249,12 @@
|
||||
current.push(word);
|
||||
var punctuation = /[,.:!?]$/.test(word.text);
|
||||
var pause = nextWord ? nextWord.start - word.end : 0;
|
||||
if (!nextWord || punctuation || pause >= PAUSE_THRESHOLD || current.length >= MAX_WORDS_PER_GROUP) {
|
||||
if (
|
||||
!nextWord ||
|
||||
punctuation ||
|
||||
pause >= PAUSE_THRESHOLD ||
|
||||
current.length >= MAX_WORDS_PER_GROUP
|
||||
) {
|
||||
groups.push(makeGroup(current));
|
||||
current = [];
|
||||
}
|
||||
@@ -249,7 +264,12 @@
|
||||
}
|
||||
|
||||
function makeGroup(words) {
|
||||
return { words: words.slice(), lines: splitLines(words), start: words[0].start, end: words[words.length - 1].end };
|
||||
return {
|
||||
words: words.slice(),
|
||||
lines: splitLines(words),
|
||||
start: words[0].start,
|
||||
end: words[words.length - 1].end,
|
||||
};
|
||||
}
|
||||
|
||||
function buildCaptions(groups) {
|
||||
@@ -291,7 +311,9 @@
|
||||
return Math.max(0, group.start - entryLead);
|
||||
});
|
||||
|
||||
var allGroupEls = GROUPS.map(function (_, i) { return document.getElementById("caption-group-" + i); });
|
||||
var allGroupEls = GROUPS.map(function (_, i) {
|
||||
return document.getElementById("caption-group-" + i);
|
||||
});
|
||||
|
||||
GROUPS.forEach(function (group, groupIndex) {
|
||||
var groupEl = allGroupEls[groupIndex];
|
||||
@@ -303,15 +325,27 @@
|
||||
});
|
||||
|
||||
tl.set(groupEl, { opacity: 0, scale: 0.85 }, visibleStart);
|
||||
tl.to(groupEl, { opacity: 1, scale: 1, duration: ENTRY_DURATION, ease: "power3.out", force3D: true }, visibleStart);
|
||||
tl.to(
|
||||
groupEl,
|
||||
{ opacity: 1, scale: 1, duration: ENTRY_DURATION, ease: "power3.out", force3D: true },
|
||||
visibleStart,
|
||||
);
|
||||
|
||||
if (group.lines.length === 2) {
|
||||
var line1El = document.getElementById("caption-group-" + groupIndex + "-line-0");
|
||||
var line2El = document.getElementById("caption-group-" + groupIndex + "-line-1");
|
||||
var line2FirstWord = group.lines[1].words[0];
|
||||
var switchTime = line2FirstWord.start;
|
||||
tl.to(line1El, { fontWeight: FONT_WEIGHT_LIGHT, duration: WEIGHT_TRANSITION, ease: "power2.out" }, switchTime);
|
||||
tl.to(line2El, { fontWeight: FONT_WEIGHT_BOLD, duration: WEIGHT_TRANSITION, ease: "power2.out" }, switchTime);
|
||||
tl.to(
|
||||
line1El,
|
||||
{ fontWeight: FONT_WEIGHT_LIGHT, duration: WEIGHT_TRANSITION, ease: "power2.out" },
|
||||
switchTime,
|
||||
);
|
||||
tl.to(
|
||||
line2El,
|
||||
{ fontWeight: FONT_WEIGHT_BOLD, duration: WEIGHT_TRANSITION, ease: "power2.out" },
|
||||
switchTime,
|
||||
);
|
||||
}
|
||||
|
||||
tl.set(groupEl, { opacity: 0 }, visibleEnd);
|
||||
|
||||
Reference in New Issue
Block a user