<svg width="" height="" viewBox="">
<defs>
<clipPath id="text-clip-path">
<rect x="0" y="0" width="500" height="250" />
</clipPath>
</defs>
<g id="circleHolder" transform="translate(250 250)">
<circle cx="0" cy="0" r="400" fill="black" stroke="none" />
</g>
<g id="lineHolder" transform="translate(250 250) scale(1 1)">
<path d="M-250,0 h500" stroke="white" stroke-width="2" />
</g>
<g id="textHolder" clip-path="url(#text-clip-path)">
<text x="90" y="230" text-anchor="middle" dominant-baseline="middle" class="letter">T</text>
<text x="115" y="230" text-anchor="middle" dominant-baseline="middle" class="letter">E</text>
<text x="140" y="230" text-anchor="middle" dominant-baseline="middle" class="letter">X</text>
<text x="165" y="230" text-anchor="middle" dominant-baseline="middle" class="letter">T</text>
<text x="215" y="230" text-anchor="middle" dominant-baseline="middle" class="letter">A</text>
<text x="240" y="230" text-anchor="middle" dominant-baseline="middle" class="letter">N</text>
<text x="265" y="230" text-anchor="middle" dominant-baseline="middle" class="letter">I</text>
<text x="290" y="230" text-anchor="middle" dominant-baseline="middle" class="letter">M</text>
<text x="315" y="230" text-anchor="middle" dominant-baseline="middle" class="letter">A</text>
<text x="340" y="230" text-anchor="middle" dominant-baseline="middle" class="letter">T</text>
<text x="365" y="230" text-anchor="middle" dominant-baseline="middle" class="letter">I</text>
<text x="390" y="230" text-anchor="middle" dominant-baseline="middle" class="letter">O</text>
<text x="415" y="230" text-anchor="middle" dominant-baseline="middle" class="letter">N</text>
</g>
</svg>
<div class="buttonHolder">
<button id="play" class="text-black bg-gray-200 py-2 px-2 my-5 hover:bg-gray-300 rounded">play</button>
<button id="pause" class="text-black bg-gray-200 py-2 px-2 my-5 hover:bg-gray-300 rounded">pause</button>
<button id="reverse" class="text-black bg-gray-200 py-2 px-2 my-5 hover:bg-gray-300 rounded">reverse</button>
<button id="restart" class="text-black bg-gray-200 py-2 px-2 my-5 hover:bg-gray-300 rounded">restart</button>
</div>
<label>
<span id="slider-label">animation scrubber</span>
<input id="scrubber" type="range" value="0" min="0" max="1" step="0.01" class="h-5 w-full cursor-ew-resize appearance-none rounded-full bg-gray-200 disabled:cursor-not-allowed">
</label>
// svg variables
const viewportWidth = 500;
const viewportHeight = 500;
const viewBoxWidth = 500;
const viewBoxHeight = 500;
const w = viewBoxWidth;
const h = viewBoxHeight;
const dur = 1;
// tween variables
let theTween = null;
let animationDuration = 0;
// ui
const playButton = document.querySelector("#play");
const pauseButton = document.querySelector("#pause");
const reverseButton = document.querySelector("#reverse");
const restartButton = document.querySelector("#restart");
const scrubber = document.querySelector("#scrubber");
initSVG();
initUI();
animate();
function initSVG() {
const svg = document.querySelector("svg");
svg.setAttribute("width", `${viewportWidth}`);
svg.setAttribute("height", `${viewportHeight}`);
svg.setAttribute("viewBox", `0 0 ${w} ${h}`);
}
function initUI() {
playButton.addEventListener("click", play);
pauseButton.addEventListener("click", pause);
reverseButton.addEventListener("click", reverse);
restartButton.addEventListener("click", restart);
// slider
scrubber.addEventListener("input", sliderInputHandler);
scrubber.addEventListener("mouseover",sliderOverHandler);
scrubber.addEventListener("mouseout", sliderOutHandler);
}
function sliderOverHandler(){
console.log("over");
theTween.pause();
}
function sliderOutHandler(){
console.log("out");
theTween.play();
}
function sliderInputHandler(){
const seekTime = scrubber.value * animationDuration;
console.log("seekTime:", seekTime);
theTween.seek(seekTime)
}
function updateScrubber(){
const val = theTween.time()/animationDuration;
scrubber.value = val;
}
function animate() {
theTween = gsap.timeline({ onUpdate:updateScrubber});
theTween
.fromTo(
"#circleHolder",
{ attr: { transform: "translate(250 -30) scale(.03)" } },
{
attr: { transform: "translate(250 250) scale(.03)" },
duration: dur,
ease: "back"
}
)
.fromTo(
"#circleHolder",
{ attr: { transform: "translate(250 250) scale(.03)" } },
{ attr: { transform: "translate(250 250) scale(1)" }, duration: dur }
)
.fromTo(
"#lineHolder",
{ attr: { transform: "translate(250 250) scale(0 1)" } },
{ attr: { transform: "translate(250 250) scale(1 1)" }, duration: dur }
)
.fromTo(
".letter",
{ attr: { y: 330 } },
{ attr: { y: 230 }, duration: dur, stagger: 0.1, ease: "back" }
);
animationDuration = theTween.duration();
}
function play() {
if (theTween == null) {
theTween.play();
return;
}
if (!theTween.isActive()) {
// if playhead is at end restart, else just play
if(theTween.progress()== 1){
theTween.restart();
} else {
theTween.play();
}
}
}
function pause() {
if (theTween != null) theTween.pause();
}
function reverse() {
if (theTween != null) theTween.reverse();
}
function restart() {
if (theTween != null) {
theTween.restart();
return;
}
theTween.play();
}