hyperframes 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +7159 -6411
- package/dist/docs/{templates.md → examples.md} +2 -2
- package/dist/skills/gsap/SKILL.md +5 -16
- package/dist/skills/gsap/references/effects.md +7 -14
- package/dist/skills/hyperframes/SKILL.md +124 -43
- package/dist/skills/hyperframes/house-style.md +34 -93
- package/dist/skills/hyperframes/references/captions.md +2 -2
- package/dist/skills/hyperframes/references/css-patterns.md +36 -34
- package/dist/skills/hyperframes/references/transitions/catalog.md +4 -19
- package/dist/skills/hyperframes/references/transitions/css-other.md +0 -11
- package/dist/skills/hyperframes/references/transitions.md +53 -37
- package/dist/skills/hyperframes/references/{fonts.md → typography.md} +73 -32
- package/dist/skills/hyperframes/scripts/animation-map.mjs +596 -0
- package/dist/skills/hyperframes/scripts/contrast-report.mjs +335 -0
- package/dist/skills/hyperframes-cli/SKILL.md +1 -1
- package/dist/studio/assets/hyperframes-player-C6QOH12J.js +198 -0
- package/dist/studio/assets/{index-QlToZFln.js → index-BLIJTYAJ.js} +21 -21
- package/dist/studio/assets/index-DZEa45DQ.css +1 -0
- package/dist/studio/index.html +2 -2
- package/dist/templates/_shared/AGENTS.md +58 -0
- package/dist/templates/_shared/CLAUDE.md +8 -9
- package/package.json +1 -1
- package/dist/skills/gsap/references/frameworks.md +0 -56
- package/dist/skills/gsap/references/plugins.md +0 -194
- package/dist/skills/gsap/references/react.md +0 -80
- package/dist/skills/gsap/references/scrolltrigger.md +0 -147
- package/dist/skills/gsap/references/utils.md +0 -91
- package/dist/skills/hyperframes/references/examples.md +0 -146
- package/dist/skills/hyperframes/references/marker-highlight.md +0 -158
- package/dist/skills/hyperframes/references/transitions/shader-setup.md +0 -463
- package/dist/skills/hyperframes/references/transitions/shader-transitions.md +0 -329
- package/dist/studio/assets/hyperframes-player-Ba4c3ztZ.js +0 -198
- package/dist/studio/assets/index-DHr9yo58.css +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.\!visible{visibility:visible!important}.visible{visibility:visible}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.bottom-0{bottom:0}.bottom-1{bottom:.25rem}.bottom-2{bottom:.5rem}.bottom-6{bottom:1.5rem}.bottom-full{bottom:100%}.left-0{left:0}.left-1\/2{left:50%}.right-0{right:0}.right-3{right:.75rem}.top-0{top:0}.top-1{top:.25rem}.top-1\/2{top:50%}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.z-\[100\]{z-index:100}.z-\[1\]{z-index:1}.z-\[200\]{z-index:200}.z-\[2\]{z-index:2}.z-\[90\]{z-index:90}.z-\[91\]{z-index:91}.mx-1{margin-left:.25rem;margin-right:.25rem}.my-0\.5{margin-top:.125rem;margin-bottom:.125rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.ml-1\.5{margin-left:.375rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[1080px\]{height:1080px}.h-\[3px\]{height:3px}.h-\[45px\]{height:45px}.h-\[5px\]{height:5px}.h-full{height:100%}.h-screen{height:100vh}.max-h-24{max-height:6rem}.max-h-\[70\%\]{max-height:70%}.max-h-\[80vh\]{max-height:80vh}.max-h-full{max-height:100%}.min-h-0{min-height:0px}.min-h-7{min-height:1.75rem}.min-h-8{min-height:2rem}.min-h-9{min-height:2.25rem}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-2{width:.5rem}.w-20{width:5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-52{width:13rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-80{width:20rem}.w-\[160px\]{width:160px}.w-\[1920px\]{width:1920px}.w-full{width:100%}.w-px{width:1px}.w-screen{width:100vw}.min-w-0{min-width:0px}.min-w-7{min-width:1.75rem}.min-w-8{min-width:2rem}.min-w-9{min-width:2.25rem}.min-w-\[140px\]{min-width:140px}.min-w-\[160px\]{min-width:160px}.min-w-\[56px\]{min-width:56px}.min-w-\[72px\]{min-width:72px}.max-w-\[280px\]{max-width:280px}.max-w-full{max-width:100%}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.grow{flex-grow:1}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-col-resize{cursor:col-resize}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-help{cursor:help}.cursor-pointer{cursor:pointer}.cursor-row-resize{cursor:row-resize}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.resize-y{resize:vertical}.resize{resize:both}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.overflow-x-hidden{overflow-x:hidden}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded{border-radius:.25rem}.rounded-\[4px\]{border-radius:4px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-none{border-style:none}.border-green-500\/30{border-color:#22c55e4d}.border-neutral-600{--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity, 1))}.border-neutral-700{--tw-border-opacity: 1;border-color:rgb(64 64 64 / var(--tw-border-opacity, 1))}.border-neutral-700\/20{border-color:#40404033}.border-neutral-700\/40{border-color:#40404066}.border-neutral-700\/50{border-color:#40404080}.border-neutral-700\/60{border-color:#40404099}.border-neutral-800{--tw-border-opacity: 1;border-color:rgb(38 38 38 / var(--tw-border-opacity, 1))}.border-neutral-800\/30{border-color:#2626264d}.border-neutral-800\/40{border-color:#26262666}.border-neutral-800\/50{border-color:#26262680}.border-neutral-800\/60{border-color:#26262699}.border-red-500{--tw-border-opacity: 1;border-color:rgb(239 68 68 / var(--tw-border-opacity, 1))}.border-red-700\/50{border-color:#b91c1c80}.border-studio-accent{--tw-border-opacity: 1;border-color:rgb(60 230 172 / var(--tw-border-opacity, 1))}.border-studio-accent\/25{border-color:#3ce6ac40}.border-studio-accent\/30{border-color:#3ce6ac4d}.border-studio-accent\/50{border-color:#3ce6ac80}.border-studio-accent\/60{border-color:#3ce6ac99}.border-transparent{border-color:transparent}.bg-\[\#0a0a0b\]{--tw-bg-opacity: 1;background-color:rgb(10 10 11 / var(--tw-bg-opacity, 1))}.bg-\[\#3CE6AC\]\/10{background-color:#3ce6ac1a}.bg-\[\#3CE6AC\]\/5{background-color:#3ce6ac0d}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/50{background-color:#00000080}.bg-black\/60{background-color:#0009}.bg-green-500\/20{background-color:#22c55e33}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity, 1))}.bg-neutral-600{--tw-bg-opacity: 1;background-color:rgb(82 82 82 / var(--tw-bg-opacity, 1))}.bg-neutral-600\/60{background-color:#52525299}.bg-neutral-700{--tw-bg-opacity: 1;background-color:rgb(64 64 64 / var(--tw-bg-opacity, 1))}.bg-neutral-700\/40{background-color:#40404066}.bg-neutral-800{--tw-bg-opacity: 1;background-color:rgb(38 38 38 / var(--tw-bg-opacity, 1))}.bg-neutral-800\/50{background-color:#26262680}.bg-neutral-800\/60{background-color:#26262699}.bg-neutral-900{--tw-bg-opacity: 1;background-color:rgb(23 23 23 / var(--tw-bg-opacity, 1))}.bg-neutral-900\/50{background-color:#17171780}.bg-neutral-950{--tw-bg-opacity: 1;background-color:rgb(10 10 10 / var(--tw-bg-opacity, 1))}.bg-red-400{--tw-bg-opacity: 1;background-color:rgb(248 113 113 / var(--tw-bg-opacity, 1))}.bg-red-500\/10{background-color:#ef44441a}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-red-900\/60{background-color:#7f1d1d99}.bg-red-900\/90{background-color:#7f1d1de6}.bg-red-950\/30{background-color:#450a0a4d}.bg-studio-accent{--tw-bg-opacity: 1;background-color:rgb(60 230 172 / var(--tw-bg-opacity, 1))}.bg-studio-accent\/10{background-color:#3ce6ac1a}.bg-studio-accent\/15{background-color:#3ce6ac26}.bg-studio-accent\/20{background-color:#3ce6ac33}.bg-studio-accent\/\[0\.03\]{background-color:#3ce6ac08}.bg-studio-accent\/\[0\.05\]{background-color:#3ce6ac0d}.bg-studio-accent\/\[0\.06\]{background-color:#3ce6ac0f}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-0\.5{padding-bottom:.125rem}.pb-3{padding-bottom:.75rem}.pr-1\.5{padding-right:.375rem}.pt-1\.5{padding-top:.375rem}.pt-3{padding-top:.75rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[9px\]{font-size:9px}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-wider{letter-spacing:.05em}.text-\[\#09090B\]{--tw-text-opacity: 1;color:rgb(9 9 11 / var(--tw-text-opacity, 1))}.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-neutral-100{--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity, 1))}.text-neutral-200{--tw-text-opacity: 1;color:rgb(229 229 229 / var(--tw-text-opacity, 1))}.text-neutral-300{--tw-text-opacity: 1;color:rgb(212 212 212 / var(--tw-text-opacity, 1))}.text-neutral-400{--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.text-neutral-500{--tw-text-opacity: 1;color:rgb(115 115 115 / var(--tw-text-opacity, 1))}.text-neutral-600{--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.text-neutral-700{--tw-text-opacity: 1;color:rgb(64 64 64 / var(--tw-text-opacity, 1))}.text-neutral-950{--tw-text-opacity: 1;color:rgb(10 10 10 / var(--tw-text-opacity, 1))}.text-purple-400{--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.text-red-200{--tw-text-opacity: 1;color:rgb(254 202 202 / var(--tw-text-opacity, 1))}.text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-studio-accent{--tw-text-opacity: 1;color:rgb(60 230 172 / var(--tw-text-opacity, 1))}.text-studio-accent\/50{color:#3ce6ac80}.text-studio-accent\/60{color:#3ce6ac99}.text-studio-accent\/80{color:#3ce6accc}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.line-through{text-decoration-line:line-through}.accent-studio-accent{accent-color:#3CE6AC}.opacity-25{opacity:.25}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-black\/40{--tw-shadow-color: rgb(0 0 0 / .4);--tw-shadow: var(--tw-shadow-colored)}.outline-none{outline:2px solid transparent;outline-offset:2px}.outline{outline-style:solid}.outline-1{outline-width:1px}.-outline-offset-1{outline-offset:-1px}.outline-\[\#3CE6AC\]\/30{outline-color:#3ce6ac4d}.outline-\[\#3CE6AC\]\/40{outline-color:#3ce6ac66}.ring{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-studio-accent{--tw-ring-opacity: 1;--tw-ring-color: rgb(60 230 172 / var(--tw-ring-opacity, 1))}.ring-white\/50{--tw-ring-color: rgb(255 255 255 / .5)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow{--tw-drop-shadow: drop-shadow(0 1px 2px rgb(0 0 0 / .1)) drop-shadow(0 1px 1px rgb(0 0 0 / .06));filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert: invert(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-150{transition-duration:.15s}.duration-300{transition-duration:.3s}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}body{margin:0;padding:0;background:#0a0a0a;color:#e5e5e5;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;overflow:hidden}#root{width:100vw;height:100vh}.cm-editor{height:100%;font-size:13px}.cm-editor .cm-scroller{font-family:JetBrains Mono,Fira Code,SF Mono,monospace}.cm-editor.cm-focused{outline:none}.placeholder\:text-neutral-600::-moz-placeholder{--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.placeholder\:text-neutral-600::placeholder{--tw-text-opacity: 1;color:rgb(82 82 82 / var(--tw-text-opacity, 1))}.last\:border-0:last-child{border-width:0px}.hover\:border-neutral-600:hover{--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity, 1))}.hover\:border-studio-accent\/50:hover{border-color:#3ce6ac80}.hover\:bg-neutral-200:hover{--tw-bg-opacity: 1;background-color:rgb(229 229 229 / var(--tw-bg-opacity, 1))}.hover\:bg-neutral-600:hover{--tw-bg-opacity: 1;background-color:rgb(82 82 82 / var(--tw-bg-opacity, 1))}.hover\:bg-neutral-800:hover{--tw-bg-opacity: 1;background-color:rgb(38 38 38 / var(--tw-bg-opacity, 1))}.hover\:bg-neutral-800\/30:hover{background-color:#2626264d}.hover\:bg-neutral-800\/50:hover{background-color:#26262680}.hover\:bg-red-500:hover{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.hover\:bg-red-600:hover{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.hover\:bg-red-800\/60:hover{background-color:#991b1b99}.hover\:bg-red-900\/30:hover{background-color:#7f1d1d4d}.hover\:bg-studio-accent:hover{--tw-bg-opacity: 1;background-color:rgb(60 230 172 / var(--tw-bg-opacity, 1))}.hover\:bg-studio-accent\/25:hover{background-color:#3ce6ac40}.hover\:bg-studio-accent\/80:hover{background-color:#3ce6accc}.hover\:text-amber-300:hover{--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.hover\:text-green-400:hover{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.hover\:text-neutral-200:hover{--tw-text-opacity: 1;color:rgb(229 229 229 / var(--tw-text-opacity, 1))}.hover\:text-neutral-300:hover{--tw-text-opacity: 1;color:rgb(212 212 212 / var(--tw-text-opacity, 1))}.hover\:text-neutral-400:hover{--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity, 1))}.hover\:text-red-400:hover{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.hover\:text-studio-accent:hover{--tw-text-opacity: 1;color:rgb(60 230 172 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:ring-1:hover{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.hover\:ring-white\/30:hover{--tw-ring-color: rgb(255 255 255 / .3)}.hover\:brightness-110:hover{--tw-brightness: brightness(1.1);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.focus\:border-\[\#3CE6AC\]:focus{--tw-border-opacity: 1;border-color:rgb(60 230 172 / var(--tw-border-opacity, 1))}.focus\:border-neutral-600:focus{--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity, 1))}.focus\:border-studio-accent:focus{--tw-border-opacity: 1;border-color:rgb(60 230 172 / var(--tw-border-opacity, 1))}.focus\:border-studio-accent\/40:focus{border-color:#3ce6ac66}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.active\:scale-\[0\.97\]:active{--tw-scale-x: .97;--tw-scale-y: .97;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:scale-\[0\.98\]:active{--tw-scale-x: .98;--tw-scale-y: .98;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:bg-studio-accent\/80:active{background-color:#3ce6accc}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:scale-125{--tw-scale-x: 1.25;--tw-scale-y: 1.25;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}
|
package/dist/studio/index.html
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>HyperFrames Studio</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-BLIJTYAJ.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DZEa45DQ.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# HyperFrames Composition Project
|
|
2
|
+
|
|
3
|
+
## Skills
|
|
4
|
+
|
|
5
|
+
This project uses AI agent skills for framework-specific patterns. Install them if not already present:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx skills add heygen-com/hyperframes
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Skills encode patterns like `window.__timelines` registration, `data-*` attribute semantics, and shader-compatible CSS rules that are not in generic web docs. Using them produces correct compositions from the start.
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx hyperframes preview # preview in browser (studio editor)
|
|
17
|
+
npx hyperframes render # render to MP4
|
|
18
|
+
npx hyperframes lint # validate compositions (errors + warnings)
|
|
19
|
+
npx hyperframes lint --json # machine-readable output for CI
|
|
20
|
+
npx hyperframes docs <topic> # reference docs in terminal
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Project Structure
|
|
24
|
+
|
|
25
|
+
- `index.html` — main composition (root timeline)
|
|
26
|
+
- `compositions/` — sub-compositions referenced via `data-composition-src`
|
|
27
|
+
- `assets/` — media files (video, audio, images)
|
|
28
|
+
- `meta.json` — project metadata (id, name)
|
|
29
|
+
- `transcript.json` — whisper word-level transcript (if generated)
|
|
30
|
+
|
|
31
|
+
## Linting — Always Run After Changes
|
|
32
|
+
|
|
33
|
+
After creating or editing any `.html` composition, run the linter before considering the task complete:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx hyperframes lint
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Fix all errors before presenting the result.
|
|
40
|
+
|
|
41
|
+
## Key Rules
|
|
42
|
+
|
|
43
|
+
1. Every timed element needs `data-start`, `data-duration`, and `data-track-index`
|
|
44
|
+
2. Visible timed elements **must** have `class="clip"` — the framework uses this for visibility control
|
|
45
|
+
3. GSAP timelines must be paused and registered on `window.__timelines`:
|
|
46
|
+
```js
|
|
47
|
+
window.__timelines = window.__timelines || {};
|
|
48
|
+
window.__timelines["composition-id"] = gsap.timeline({ paused: true });
|
|
49
|
+
```
|
|
50
|
+
4. Videos use `muted` with a separate `<audio>` element for the audio track
|
|
51
|
+
5. Sub-compositions use `data-composition-src="compositions/file.html"`
|
|
52
|
+
6. Only deterministic logic — no `Date.now()`, no `Math.random()`, no network fetches
|
|
53
|
+
|
|
54
|
+
## Documentation
|
|
55
|
+
|
|
56
|
+
Full docs: https://hyperframes.heygen.com/introduction
|
|
57
|
+
|
|
58
|
+
Machine-readable index for AI tools: https://hyperframes.heygen.com/llms.txt
|
|
@@ -2,17 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Skills — USE THESE FIRST
|
|
4
4
|
|
|
5
|
-
**Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `
|
|
5
|
+
**Always invoke the relevant skill before writing or modifying compositions.** Skills encode framework-specific patterns (e.g., `window.__timelines` registration, `data-*` attribute semantics, shader-compatible CSS rules) that are NOT in generic web docs. Skipping them produces broken compositions.
|
|
6
6
|
|
|
7
|
-
| Skill | Command | When to use
|
|
8
|
-
| ------------------- | ------------------ |
|
|
9
|
-
| **hyperframes** | `/hyperframes` | Creating or editing HTML compositions, captions, TTS, audio-reactive animation, marker highlights
|
|
10
|
-
| **hyperframes-cli** | `/hyperframes-cli` | CLI commands: init, lint, preview, render, transcribe, tts
|
|
11
|
-
| **gsap** | `/gsap` | GSAP animations — tweens, timelines, easing,
|
|
7
|
+
| Skill | Command | When to use |
|
|
8
|
+
| ------------------- | ------------------ | ------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| **hyperframes** | `/hyperframes` | Creating or editing HTML compositions, captions, TTS, audio-reactive animation, marker highlights |
|
|
10
|
+
| **hyperframes-cli** | `/hyperframes-cli` | CLI commands: init, lint, preview, render, transcribe, tts |
|
|
11
|
+
| **gsap** | `/gsap` | GSAP animations for HyperFrames — tweens, timelines, easing, performance |
|
|
12
12
|
|
|
13
13
|
> **Skills not available?** Ask the user to run `npx hyperframes skills` and restart their
|
|
14
|
-
> agent session, or install manually: `npx skills add heygen-com/hyperframes
|
|
15
|
-
> `npx skills add greensock/gsap-skills`.
|
|
14
|
+
> agent session, or install manually: `npx skills add heygen-com/hyperframes`.
|
|
16
15
|
|
|
17
16
|
## Commands
|
|
18
17
|
|
|
@@ -33,7 +32,7 @@ npx hyperframes docs <topic> # reference docs in terminal
|
|
|
33
32
|
npx hyperframes docs <topic>
|
|
34
33
|
```
|
|
35
34
|
|
|
36
|
-
Topics: `data-attributes`, `gsap`, `compositions`, `rendering`, `
|
|
35
|
+
Topics: `data-attributes`, `gsap`, `compositions`, `rendering`, `examples`, `troubleshooting`
|
|
37
36
|
|
|
38
37
|
**For full documentation**, discover pages via the machine-readable index — do NOT guess URLs:
|
|
39
38
|
|
package/package.json
CHANGED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# GSAP with Vue, Svelte, and Other Frameworks
|
|
2
|
-
|
|
3
|
-
For **React**, see [react.md](react.md).
|
|
4
|
-
|
|
5
|
-
## Principles (All Frameworks)
|
|
6
|
-
|
|
7
|
-
- **Create** tweens/ScrollTriggers **after** DOM is available (onMounted/onMount).
|
|
8
|
-
- **Kill or revert** in unmount cleanup.
|
|
9
|
-
- **Scope selectors** to component root via `gsap.context(callback, scope)`.
|
|
10
|
-
|
|
11
|
-
## Vue 3 (Composition API / script setup)
|
|
12
|
-
|
|
13
|
-
```javascript
|
|
14
|
-
import { onMounted, onUnmounted, ref } from "vue";
|
|
15
|
-
import { gsap } from "gsap";
|
|
16
|
-
|
|
17
|
-
const container = ref(null);
|
|
18
|
-
let ctx;
|
|
19
|
-
|
|
20
|
-
onMounted(() => {
|
|
21
|
-
ctx = gsap.context(() => {
|
|
22
|
-
gsap.to(".box", { x: 100 });
|
|
23
|
-
gsap.from(".item", { autoAlpha: 0, stagger: 0.1 });
|
|
24
|
-
}, container.value);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
onUnmounted(() => ctx?.revert());
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Svelte
|
|
31
|
-
|
|
32
|
-
```javascript
|
|
33
|
-
import { onMount } from "svelte";
|
|
34
|
-
import { gsap } from "gsap";
|
|
35
|
-
|
|
36
|
-
let container;
|
|
37
|
-
onMount(() => {
|
|
38
|
-
const ctx = gsap.context(() => {
|
|
39
|
-
gsap.to(".box", { x: 100 });
|
|
40
|
-
}, container);
|
|
41
|
-
return () => ctx.revert();
|
|
42
|
-
});
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Use `bind:this={container}` for the root element ref.
|
|
46
|
-
|
|
47
|
-
## ScrollTrigger Cleanup
|
|
48
|
-
|
|
49
|
-
ScrollTriggers inside `gsap.context()` are reverted by `ctx.revert()`. Call `ScrollTrigger.refresh()` after layout changes (nextTick in Vue, tick in Svelte).
|
|
50
|
-
|
|
51
|
-
## Do Not
|
|
52
|
-
|
|
53
|
-
- Create tweens before the component is mounted.
|
|
54
|
-
- Use selector strings without a scope.
|
|
55
|
-
- Skip cleanup — always revert context on unmount.
|
|
56
|
-
- Register plugins inside re-rendering component bodies.
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
# GSAP Plugins
|
|
2
|
-
|
|
3
|
-
Register each plugin once before use:
|
|
4
|
-
|
|
5
|
-
```javascript
|
|
6
|
-
import gsap from "gsap";
|
|
7
|
-
import { ScrollToPlugin } from "gsap/ScrollToPlugin";
|
|
8
|
-
import { Flip } from "gsap/Flip";
|
|
9
|
-
gsap.registerPlugin(ScrollToPlugin, Flip);
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
## Table of Contents
|
|
13
|
-
|
|
14
|
-
- [ScrollToPlugin](#scrolltoplugin)
|
|
15
|
-
- [ScrollSmoother](#scrollsmoother)
|
|
16
|
-
- [Flip](#flip)
|
|
17
|
-
- [Draggable + Inertia](#draggable)
|
|
18
|
-
- [Observer](#observer)
|
|
19
|
-
- [SplitText](#splittext)
|
|
20
|
-
- [ScrambleText](#scrambletext)
|
|
21
|
-
- [DrawSVG](#drawsvg)
|
|
22
|
-
- [MorphSVG](#morphsvg)
|
|
23
|
-
- [MotionPath](#motionpath)
|
|
24
|
-
- [CustomEase / EasePack](#customeaseeasepak)
|
|
25
|
-
- [Physics2D / PhysicsProps](#physics)
|
|
26
|
-
- [GSDevTools](#gsdevtools)
|
|
27
|
-
- [PixiPlugin](#pixiplugin)
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## ScrollToPlugin
|
|
32
|
-
|
|
33
|
-
Animate scroll position (window or scrollable element).
|
|
34
|
-
|
|
35
|
-
```javascript
|
|
36
|
-
gsap.to(window, { scrollTo: { y: "#section", offsetY: 50 }, duration: 1 });
|
|
37
|
-
gsap.to(scrollContainer, { scrollTo: { x: "max" }, duration: 1 });
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## ScrollSmoother
|
|
41
|
-
|
|
42
|
-
Smooth scroll wrapper. Requires ScrollTrigger + specific DOM structure (`#smooth-wrapper` > `#smooth-content`).
|
|
43
|
-
|
|
44
|
-
## Flip
|
|
45
|
-
|
|
46
|
-
FLIP layout transitions: capture state, change DOM, animate from old to new.
|
|
47
|
-
|
|
48
|
-
```javascript
|
|
49
|
-
const state = Flip.getState(".item");
|
|
50
|
-
// change DOM (reorder, add/remove, change classes)
|
|
51
|
-
Flip.from(state, { duration: 0.5, ease: "power2.inOut" });
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Options: `absolute`, `nested`, `scale`, `simple`, `duration`, `ease`.
|
|
55
|
-
|
|
56
|
-
## Draggable
|
|
57
|
-
|
|
58
|
-
Makes elements draggable/spinnable/throwable.
|
|
59
|
-
|
|
60
|
-
```javascript
|
|
61
|
-
gsap.registerPlugin(Draggable, InertiaPlugin);
|
|
62
|
-
Draggable.create(".box", { type: "x,y", bounds: "#container", inertia: true });
|
|
63
|
-
Draggable.create(".knob", { type: "rotation" });
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
Types: `"x"`, `"y"`, `"x,y"`, `"rotation"`, `"scroll"`. Options: `bounds`, `inertia`, `edgeResistance`, `cursor`, drag callbacks.
|
|
67
|
-
|
|
68
|
-
### Inertia (InertiaPlugin)
|
|
69
|
-
|
|
70
|
-
Momentum after release with Draggable, or track velocity of any property:
|
|
71
|
-
|
|
72
|
-
```javascript
|
|
73
|
-
InertiaPlugin.track(".box", "x");
|
|
74
|
-
gsap.to(obj, { inertia: { x: "auto" } });
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
## Observer
|
|
78
|
-
|
|
79
|
-
Normalized pointer/scroll input across devices. Use for swipe/gesture detection.
|
|
80
|
-
|
|
81
|
-
```javascript
|
|
82
|
-
Observer.create({
|
|
83
|
-
target: "#area",
|
|
84
|
-
onUp: () => {},
|
|
85
|
-
onDown: () => {},
|
|
86
|
-
tolerance: 10,
|
|
87
|
-
});
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## SplitText
|
|
91
|
-
|
|
92
|
-
Split text into chars, words, lines for per-unit animation.
|
|
93
|
-
|
|
94
|
-
```javascript
|
|
95
|
-
const split = SplitText.create(".heading", { type: "words, chars" });
|
|
96
|
-
gsap.from(split.chars, { opacity: 0, y: 20, stagger: 0.03 });
|
|
97
|
-
// later: split.revert()
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Key options: `type` (comma-separated: chars/words/lines), `charsClass`/`wordsClass`/`linesClass`, `aria` ("auto"/"hidden"/"none"), `autoSplit` + `onSplit(self)` for font-safe re-splitting, `mask` (lines/words/chars for reveal effects), `tag`, `ignore`, `smartWrap`, `propIndex`.
|
|
101
|
-
|
|
102
|
-
Tips: Split only what's animated. For custom fonts, use `autoSplit: true` with `onSplit()`. Avoid `text-wrap: balance`.
|
|
103
|
-
|
|
104
|
-
## ScrambleText
|
|
105
|
-
|
|
106
|
-
Scramble/glitch text effect.
|
|
107
|
-
|
|
108
|
-
```javascript
|
|
109
|
-
gsap.to(".text", { scrambleText: { text: "New message", chars: "01", revealDelay: 0.5 } });
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
## DrawSVG
|
|
113
|
-
|
|
114
|
-
Animate SVG stroke reveal (stroke-dashoffset/dasharray). Element must have `stroke` and `stroke-width`.
|
|
115
|
-
|
|
116
|
-
```javascript
|
|
117
|
-
gsap.from("#path", { drawSVG: 0, duration: 1 }); // nothing to full stroke
|
|
118
|
-
gsap.to("#path", { drawSVG: "20% 80%", duration: 1 }); // partial segment
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
`drawSVG` value = visible segment: `"start end"` in % or length. Single value (e.g. `0`) means start is 0.
|
|
122
|
-
|
|
123
|
-
## MorphSVG
|
|
124
|
-
|
|
125
|
-
Morph one SVG shape into another. Handles different point counts.
|
|
126
|
-
|
|
127
|
-
```javascript
|
|
128
|
-
MorphSVGPlugin.convertToPath("circle, rect, ellipse, line");
|
|
129
|
-
gsap.to("#diamond", { morphSVG: "#lightning", duration: 1 });
|
|
130
|
-
// object form: { shape, type: "rotational", shapeIndex, smooth, curveMode }
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
Use `shapeIndex: "log"` to find optimal value. `type: "rotational"` avoids kinks.
|
|
134
|
-
|
|
135
|
-
## MotionPath
|
|
136
|
-
|
|
137
|
-
Animate along an SVG path.
|
|
138
|
-
|
|
139
|
-
```javascript
|
|
140
|
-
gsap.to(".dot", {
|
|
141
|
-
motionPath: { path: "#path", align: "#path", alignOrigin: [0.5, 0.5], autoRotate: true },
|
|
142
|
-
});
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## CustomEase/EasePack
|
|
146
|
-
|
|
147
|
-
Custom curves beyond built-in eases:
|
|
148
|
-
|
|
149
|
-
```javascript
|
|
150
|
-
const ease = CustomEase.create("name", ".17,.67,.83,.67");
|
|
151
|
-
// or SVG path data for complex curves
|
|
152
|
-
const hop = CustomEase.create("hop", "M0,0 C0,0 0.056,0.442 ...");
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
EasePack adds SlowMo, RoughEase, ExpoScaleEase. CustomWiggle for oscillation. CustomBounce for configurable bounces.
|
|
156
|
-
|
|
157
|
-
## Physics
|
|
158
|
-
|
|
159
|
-
### Physics2D
|
|
160
|
-
|
|
161
|
-
```javascript
|
|
162
|
-
gsap.to(".ball", { physics2D: { velocity: 250, angle: 80, gravity: 500 }, duration: 2 });
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### PhysicsProps
|
|
166
|
-
|
|
167
|
-
```javascript
|
|
168
|
-
gsap.to(".obj", {
|
|
169
|
-
physicsProps: { x: { velocity: 100, end: 300 }, y: { velocity: -50, acceleration: 200 } },
|
|
170
|
-
duration: 2,
|
|
171
|
-
});
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
## GSDevTools
|
|
175
|
-
|
|
176
|
-
Timeline scrubbing UI for development. **Do not ship to production.**
|
|
177
|
-
|
|
178
|
-
```javascript
|
|
179
|
-
GSDevTools.create({ animation: tl });
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
## PixiPlugin
|
|
183
|
-
|
|
184
|
-
Integrates GSAP with PixiJS display objects.
|
|
185
|
-
|
|
186
|
-
```javascript
|
|
187
|
-
gsap.to(sprite, { pixi: { x: 200, scale: 1.5 }, duration: 1 });
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
## Do Not
|
|
191
|
-
|
|
192
|
-
- Use a plugin without registering it first.
|
|
193
|
-
- Ship GSDevTools to production.
|
|
194
|
-
- Forget to revert SplitText instances on unmount.
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# GSAP with React
|
|
2
|
-
|
|
3
|
-
## Installation
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
npm install gsap @gsap/react
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
## useGSAP() Hook (Preferred)
|
|
10
|
-
|
|
11
|
-
```javascript
|
|
12
|
-
import { useGSAP } from "@gsap/react";
|
|
13
|
-
gsap.registerPlugin(useGSAP);
|
|
14
|
-
|
|
15
|
-
const containerRef = useRef(null);
|
|
16
|
-
useGSAP(
|
|
17
|
-
() => {
|
|
18
|
-
gsap.to(".box", { x: 100 });
|
|
19
|
-
},
|
|
20
|
-
{ scope: containerRef },
|
|
21
|
-
);
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
- Pass **scope** (ref) so selectors are scoped to the component.
|
|
25
|
-
- Cleanup runs automatically on unmount.
|
|
26
|
-
- Use **contextSafe** for callbacks created after useGSAP executes:
|
|
27
|
-
|
|
28
|
-
```javascript
|
|
29
|
-
useGSAP(
|
|
30
|
-
(context, contextSafe) => {
|
|
31
|
-
const onClick = contextSafe(() => {
|
|
32
|
-
gsap.to(ref.current, { rotation: 180 });
|
|
33
|
-
});
|
|
34
|
-
ref.current.addEventListener("click", onClick);
|
|
35
|
-
return () => ref.current.removeEventListener("click", onClick);
|
|
36
|
-
},
|
|
37
|
-
{ scope: container },
|
|
38
|
-
);
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Dependency Array and revertOnUpdate
|
|
42
|
-
|
|
43
|
-
```javascript
|
|
44
|
-
useGSAP(
|
|
45
|
-
() => {
|
|
46
|
-
/* gsap code */
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
dependencies: [endX],
|
|
50
|
-
scope: container,
|
|
51
|
-
revertOnUpdate: true, // reverts + re-runs on dependency change
|
|
52
|
-
},
|
|
53
|
-
);
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## gsap.context() in useEffect (Fallback)
|
|
57
|
-
|
|
58
|
-
When @gsap/react isn't available:
|
|
59
|
-
|
|
60
|
-
```javascript
|
|
61
|
-
useEffect(() => {
|
|
62
|
-
const ctx = gsap.context(() => {
|
|
63
|
-
gsap.to(".box", { x: 100 });
|
|
64
|
-
}, containerRef);
|
|
65
|
-
return () => ctx.revert();
|
|
66
|
-
}, []);
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Always return `ctx.revert()` in cleanup.
|
|
70
|
-
|
|
71
|
-
## SSR (Next.js)
|
|
72
|
-
|
|
73
|
-
GSAP runs in the browser. Keep all GSAP code inside useGSAP or useEffect.
|
|
74
|
-
|
|
75
|
-
## Do Not
|
|
76
|
-
|
|
77
|
-
- Target by selector without a scope — always pass scope.
|
|
78
|
-
- Skip cleanup — always revert context or kill tweens on unmount.
|
|
79
|
-
- Run GSAP during SSR.
|
|
80
|
-
- Register plugins inside components that re-render — register once at app level.
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
# ScrollTrigger
|
|
2
|
-
|
|
3
|
-
## Registering
|
|
4
|
-
|
|
5
|
-
```javascript
|
|
6
|
-
gsap.registerPlugin(ScrollTrigger);
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
## Basic Trigger
|
|
10
|
-
|
|
11
|
-
```javascript
|
|
12
|
-
gsap.to(".box", {
|
|
13
|
-
x: 500,
|
|
14
|
-
scrollTrigger: {
|
|
15
|
-
trigger: ".box",
|
|
16
|
-
start: "top center",
|
|
17
|
-
end: "bottom center",
|
|
18
|
-
toggleActions: "play reverse play reverse",
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
**start/end** format: `"triggerPosition viewportPosition"`. Examples: `"top top"`, `"center center"`, `"bottom 80%"`, numeric px `500`, relative `"+=300"`, `"+=100%"` (scroller height), `"max"`. Wrap in `clamp()` (v3.12+): `"clamp(top bottom)"`. Can be a function returning string/number.
|
|
24
|
-
|
|
25
|
-
## Key Config Options
|
|
26
|
-
|
|
27
|
-
| Property | Type | Description |
|
|
28
|
-
| ----------------------------------------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
29
|
-
| **trigger** | String/Element | Element whose position defines start. Required. |
|
|
30
|
-
| **start** | String/Number/Function | When active. Default `"top bottom"` (or `"top top"` if pinned). |
|
|
31
|
-
| **end** | String/Number/Function | When ends. Default `"bottom top"`. |
|
|
32
|
-
| **endTrigger** | String/Element | Different element for end calculation. |
|
|
33
|
-
| **scrub** | Boolean/Number | Link progress to scroll. `true` = direct; number = catch-up seconds. |
|
|
34
|
-
| **toggleActions** | String | Four actions: onEnter, onLeave, onEnterBack, onLeaveBack. Values: play/pause/resume/reset/restart/complete/reverse/none. Default `"play none none none"`. |
|
|
35
|
-
| **pin** | Boolean/String/Element | Pin element while active. `true` = pin trigger. Animate children, not the pinned element. |
|
|
36
|
-
| **pinSpacing** | Boolean/String | Default `true` (adds spacer). `false` or `"margin"`. |
|
|
37
|
-
| **horizontal** | Boolean | For horizontal scrolling. |
|
|
38
|
-
| **scroller** | String/Element | Scroll container (default: viewport). |
|
|
39
|
-
| **markers** | Boolean/Object | Dev markers. Remove in production. |
|
|
40
|
-
| **once** | Boolean | Kill after end reached once. |
|
|
41
|
-
| **snap** | Number/Array/Function/"labels"/Object | Snap to progress values. |
|
|
42
|
-
| **containerAnimation** | Tween/Timeline | For fake horizontal scroll (see below). |
|
|
43
|
-
| **toggleClass** | String/Object | Add/remove class when active. |
|
|
44
|
-
| **onEnter/onLeave/onEnterBack/onLeaveBack** | Function | Callbacks; receive ScrollTrigger instance. |
|
|
45
|
-
| **onUpdate/onToggle/onRefresh/onScrubComplete** | Function | Progress/state callbacks. |
|
|
46
|
-
|
|
47
|
-
**Standalone** (no linked tween): `ScrollTrigger.create({...})` with callbacks.
|
|
48
|
-
|
|
49
|
-
## Scrub
|
|
50
|
-
|
|
51
|
-
```javascript
|
|
52
|
-
scrollTrigger: { trigger: ".box", start: "top center", end: "bottom center", scrub: true }
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
`scrub: true` = direct link; number (e.g. `1`) = smooth lag.
|
|
56
|
-
|
|
57
|
-
## Pinning
|
|
58
|
-
|
|
59
|
-
```javascript
|
|
60
|
-
scrollTrigger: {
|
|
61
|
-
trigger: ".section", start: "top top", end: "+=1000", pin: true, scrub: 1
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## Timeline + ScrollTrigger
|
|
66
|
-
|
|
67
|
-
```javascript
|
|
68
|
-
const tl = gsap.timeline({
|
|
69
|
-
scrollTrigger: { trigger: ".container", start: "top top", end: "+=2000", scrub: 1, pin: true },
|
|
70
|
-
});
|
|
71
|
-
tl.to(".a", { x: 100 }).to(".b", { y: 50 });
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## ScrollTrigger.batch()
|
|
75
|
-
|
|
76
|
-
Creates one ScrollTrigger per target, batches callbacks within a short interval. Good for staggered reveal of many elements.
|
|
77
|
-
|
|
78
|
-
```javascript
|
|
79
|
-
ScrollTrigger.batch(".box", {
|
|
80
|
-
onEnter: (elements) => gsap.to(elements, { opacity: 1, y: 0, stagger: 0.15 }),
|
|
81
|
-
start: "top 80%",
|
|
82
|
-
});
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
Options: `interval` (batch window), `batchMax` (max per batch). Callbacks receive `(targets, scrollTriggers)`.
|
|
86
|
-
|
|
87
|
-
## Horizontal Scroll (containerAnimation)
|
|
88
|
-
|
|
89
|
-
Pin a section, animate inner content's `x`/`xPercent` horizontally on vertical scroll:
|
|
90
|
-
|
|
91
|
-
1. Pin the section
|
|
92
|
-
2. Animate inner content with **ease: "none"** (required)
|
|
93
|
-
3. Attach ScrollTrigger with pin + scrub
|
|
94
|
-
4. Use `containerAnimation` on nested triggers
|
|
95
|
-
|
|
96
|
-
```javascript
|
|
97
|
-
const scrollTween = gsap.to(scrollingEl, {
|
|
98
|
-
xPercent: () => Math.max(0, window.innerWidth - scrollingEl.offsetWidth),
|
|
99
|
-
ease: "none",
|
|
100
|
-
scrollTrigger: {
|
|
101
|
-
trigger: scrollingEl,
|
|
102
|
-
pin: scrollingEl.parentNode,
|
|
103
|
-
start: "top top",
|
|
104
|
-
end: "+=1000",
|
|
105
|
-
},
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
gsap.to(".nested", {
|
|
109
|
-
y: 100,
|
|
110
|
-
scrollTrigger: { containerAnimation: scrollTween, trigger: ".wrapper", start: "left center" },
|
|
111
|
-
});
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Pinning and snapping unavailable on containerAnimation-based ScrollTriggers.
|
|
115
|
-
|
|
116
|
-
## ScrollTrigger.scrollerProxy()
|
|
117
|
-
|
|
118
|
-
Override scroll position reading for third-party smooth-scroll libraries. Call `ScrollTrigger.update` when the scroller updates.
|
|
119
|
-
|
|
120
|
-
```javascript
|
|
121
|
-
ScrollTrigger.scrollerProxy(document.body, {
|
|
122
|
-
scrollTop(value) {
|
|
123
|
-
if (arguments.length) scrollbar.scrollTop = value;
|
|
124
|
-
return scrollbar.scrollTop;
|
|
125
|
-
},
|
|
126
|
-
getBoundingClientRect() {
|
|
127
|
-
return { top: 0, left: 0, width: window.innerWidth, height: window.innerHeight };
|
|
128
|
-
},
|
|
129
|
-
});
|
|
130
|
-
scrollbar.addListener(ScrollTrigger.update);
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## Refresh and Cleanup
|
|
134
|
-
|
|
135
|
-
- `ScrollTrigger.refresh()` — recalculate after DOM/layout changes. Auto on resize (200ms debounce).
|
|
136
|
-
- Create ScrollTriggers top-to-bottom or set `refreshPriority`.
|
|
137
|
-
- Kill instances when removing elements: `ScrollTrigger.getAll().forEach(t => t.kill())` or `ScrollTrigger.getById("id")?.kill()`.
|
|
138
|
-
|
|
139
|
-
## Do Not
|
|
140
|
-
|
|
141
|
-
- Put ScrollTrigger on child tweens inside a timeline — put on the timeline.
|
|
142
|
-
- Nest ScrollTriggered animations inside a parent timeline.
|
|
143
|
-
- Use scrub and toggleActions together (scrub wins).
|
|
144
|
-
- Use an ease other than "none" on the horizontal animation with containerAnimation.
|
|
145
|
-
- Leave markers in production.
|
|
146
|
-
- Create triggers in random order without refreshPriority.
|
|
147
|
-
- Forget refresh() after layout changes.
|