You want to go next level ???
Let’s go…
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Premium Rotating Text Hero Effect</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700;800;900&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--primary-gradient: linear-gradient(135deg, #0f0f23 0%, #1a1a2e 30%, #16213e 70%, #0f3460 100%);
--accent-color: #00d4ff;
--accent-gradient: linear-gradient(45deg, #00d4ff, #7c3aed, #ec4899);
--secondary-gradient: linear-gradient(45deg, #f59e0b, #ef4444, #8b5cf6);
--text-shadow: 0 4px 20px rgba(0, 212, 255, 0.3);
--glow-color: rgba(0, 212, 255, 0.6);
--background-text-color: rgba(0, 212, 255, 0.08);
}
body {
font-family: 'Inter', sans-serif;
background: var(--primary-gradient);
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
position: relative;
}
/* Animated background mesh */
.background-mesh {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background:
radial-gradient(circle at 25% 25%, rgba(0, 212, 255, 0.1) 0%, transparent 50%),
radial-gradient(circle at 75% 75%, rgba(124, 58, 237, 0.1) 0%, transparent 50%),
radial-gradient(circle at 75% 25%, rgba(236, 72, 153, 0.1) 0%, transparent 50%),
radial-gradient(circle at 25% 75%, rgba(245, 158, 11, 0.1) 0%, transparent 50%);
animation: mesh-move 20s ease-in-out infinite;
}
@keyframes mesh-move {
0%, 100% { transform: translateX(0) translateY(0) rotate(0deg); }
25% { transform: translateX(-20px) translateY(-10px) rotate(1deg); }
50% { transform: translateX(20px) translateY(10px) rotate(-1deg); }
75% { transform: translateX(-10px) translateY(20px) rotate(0.5deg); }
}
/* Background text animations */
.background-text-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: 2;
}
.background-word {
position: absolute;
font-size: 8rem;
font-weight: 900;
color: var(--background-text-color);
pointer-events: none;
user-select: none;
opacity: 0;
transform: scale(0.5) rotate(45deg);
animation: float-background 15s infinite linear;
}
@keyframes float-background {
0% {
transform: translateY(120vh) translateX(-50px) scale(0.3) rotate(45deg);
opacity: 0;
}
5% {
opacity: 1;
}
50% {
opacity: 0.6;
transform: translateY(50vh) translateX(50px) scale(0.8) rotate(-15deg);
}
95% {
opacity: 0.2;
}
100% {
transform: translateY(-20vh) translateX(-100px) scale(1.2) rotate(-45deg);
opacity: 0;
}
}
/* Animated particles with new colors */
.particles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: 3;
}
.particle {
position: absolute;
border-radius: 50%;
animation: float-particle 15s infinite linear;
}
.particle.type-1 {
background: radial-gradient(circle, rgba(0, 212, 255, 0.4) 0%, transparent 70%);
}
.particle.type-2 {
background: radial-gradient(circle, rgba(124, 58, 237, 0.3) 0%, transparent 70%);
}
.particle.type-3 {
background: radial-gradient(circle, rgba(236, 72, 153, 0.3) 0%, transparent 70%);
}
@keyframes float-particle {
0% {
transform: translateY(100vh) rotate(0deg) scale(0);
opacity: 0;
}
10% {
opacity: 1;
transform: translateY(90vh) rotate(36deg) scale(1);
}
90% {
opacity: 0.8;
transform: translateY(10vh) rotate(324deg) scale(1);
}
100% {
transform: translateY(-10vh) rotate(360deg) scale(0);
opacity: 0;
}
}
/* Modern glassmorphism container */
.hero-container {
text-align: center;
color: white;
max-width: 900px;
padding: 3rem;
position: relative;
z-index: 10;
background: rgba(15, 15, 35, 0.3);
backdrop-filter: blur(25px);
border-radius: 25px;
border: 1px solid rgba(0, 212, 255, 0.2);
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.1),
0 0 60px rgba(0, 212, 255, 0.1);
animation: fadeInScale 1s ease-out;
}
@keyframes fadeInScale {
from {
opacity: 0;
transform: scale(0.9) translateY(30px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
.hero-text {
font-size: 4.5rem;
font-weight: 800;
line-height: 1.1;
margin-bottom: 1.5rem;
text-shadow: var(--text-shadow);
letter-spacing: -0.02em;
}
.static-text {
background: linear-gradient(45deg, #ffffff, #00d4ff);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
display: inline-block;
filter: drop-shadow(0 0 20px rgba(0, 212, 255, 0.3));
}
.rotating-text-container {
display: inline-block;
position: relative;
min-width: 400px;
height: 1.2em;
vertical-align: top;
margin-left: 20px;
perspective: 1000px;
}
.rotating-word {
position: absolute;
top: 0;
left: 0;
width: 100%;
opacity: 0;
transform: translateY(60px) rotateX(90deg) scale(0.8);
transition: all 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
background: var(--accent-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-weight: 900;
text-shadow: none;
filter: drop-shadow(0 0 30px var(--glow-color));
}
.rotating-word.active {
opacity: 1;
transform: translateY(0) rotateX(0deg) scale(1);
animation: glow-pulse 3s ease-in-out infinite;
}
.rotating-word.fade-out {
opacity: 0;
transform: translateY(-60px) rotateX(-90deg) scale(0.8);
}
.rotating-word.slide-in-right {
transform: translateX(100px) translateY(0) rotateY(90deg) scale(0.8);
}
.rotating-word.slide-in-left {
transform: translateX(-100px) translateY(0) rotateY(-90deg) scale(0.8);
}
.rotating-word.zoom-in {
transform: translateY(0) scale(0.3) rotateZ(180deg);
}
.rotating-word.flip-in {
transform: translateY(0) rotateY(180deg) scale(0.8);
}
.rotating-word.bounce-in {
transform: translateY(-100px) scale(1.3);
animation-timing-function: cubic-bezier(0.68, -0.55, 0.265, 1.55);
}
@keyframes glow-pulse {
0%, 100% {
filter: drop-shadow(0 0 30px var(--glow-color));
}
50% {
filter:
drop-shadow(0 0 50px var(--glow-color))
drop-shadow(0 0 80px rgba(124, 58, 237, 0.4))
drop-shadow(0 0 100px rgba(236, 72, 153, 0.3));
}
}
.subtitle {
font-size: 1.3rem;
font-weight: 400;
opacity: 0;
margin-top: 2rem;
animation: fadeInUp 1.2s ease-out 0.8s forwards;
background: linear-gradient(45deg, rgba(255, 255, 255, 0.9), rgba(0, 212, 255, 0.7));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(40px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Enhanced control panel */
.control-panel {
position: absolute;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 10px;
z-index: 20;
background: rgba(15, 15, 35, 0.4);
padding: 15px 25px;
border-radius: 50px;
backdrop-filter: blur(15px);
border: 1px solid rgba(0, 212, 255, 0.3);
animation: slideInUp 1s ease-out 1.5s backwards;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
}
@keyframes slideInUp {
from {
opacity: 0;
transform: translateX(-50%) translateY(50px);
}
to {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
}
.control-btn {
background: rgba(0, 212, 255, 0.1);
border: 1px solid rgba(0, 212, 255, 0.3);
color: #00d4ff;
padding: 10px 15px;
border-radius: 25px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 0.9rem;
font-weight: 500;
}
.control-btn:hover {
background: rgba(0, 212, 255, 0.2);
border-color: rgba(0, 212, 255, 0.6);
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0, 212, 255, 0.3);
}
.control-btn.active {
background: var(--accent-gradient);
border-color: transparent;
color: #000;
font-weight: 600;
}
/* Progress indicator with new colors */
.progress-bar {
position: absolute;
bottom: 0;
left: 0;
height: 3px;
background: var(--accent-gradient);
border-radius: 2px;
transform-origin: left;
transform: scaleX(0);
animation: progress-fill var(--duration, 3000ms) linear infinite;
box-shadow: 0 0 10px rgba(0, 212, 255, 0.5);
}
@keyframes progress-fill {
0% { transform: scaleX(0); }
95% { transform: scaleX(1); }
100% { transform: scaleX(0); }
}
/* Word indicators with new styling */
.word-indicators {
position: absolute;
top: -60px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 8px;
}
.word-indicator {
width: 8px;
height: 8px;
border-radius: 50%;
background: rgba(0, 212, 255, 0.3);
transition: all 0.3s ease;
cursor: pointer;
}
.word-indicator.active {
background: var(--accent-color);
transform: scale(1.3);
box-shadow: 0 0 15px var(--glow-color);
}
/* Enhanced mobile responsiveness */
@media (max-width: 768px) {
.hero-text {
font-size: 3rem;
}
.rotating-text-container {
min-width: 280px;
margin-left: 10px;
}
.subtitle {
font-size: 1.1rem;
}
.hero-container {
padding: 2rem;
margin: 1rem;
}
.control-panel {
bottom: 20px;
padding: 10px 15px;
}
.control-btn {
padding: 8px 12px;
font-size: 0.8rem;
}
.background-word {
font-size: 4rem;
}
}
@media (max-width: 480px) {
.hero-text {
font-size: 2.2rem;
}
.rotating-text-container {
min-width: 200px;
display: block;
margin: 20px auto 0;
}
.control-panel {
flex-wrap: wrap;
justify-content: center;
}
.background-word {
font-size: 3rem;
}
}
/* New theme variants */
.theme-cyber {
--primary-gradient: linear-gradient(135deg, #0a0a0a 0%, #1a0033 30%, #330066 70%, #004d99 100%);
--accent-gradient: linear-gradient(45deg, #00ffff, #ff00ff, #ffff00);
--glow-color: rgba(255, 0, 255, 0.6);
--background-text-color: rgba(255, 0, 255, 0.08);
}
.theme-sunset {
--primary-gradient: linear-gradient(135deg, #2d1b69 0%, #11998e 50%, #38ef7d 100%);
--accent-gradient: linear-gradient(45deg, #ff6b6b, #feca57, #48dbfb);
--glow-color: rgba(255, 107, 107, 0.6);
--background-text-color: rgba(255, 107, 107, 0.08);
}
.theme-neon {
--primary-gradient: linear-gradient(135deg, #000000 0%, #0d1421 30%, #1e3c72 70%, #2a5298 100%);
--accent-gradient: linear-gradient(45deg, #39ff14, #ff073a, #bf00ff);
--glow-color: rgba(57, 255, 20, 0.6);
--background-text-color: rgba(57, 255, 20, 0.08);
}
/* Accessibility */
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
</style>
</head>
<body>
<div class="background-mesh"></div>
<div class="background-text-layer" id="backgroundText"></div>
<div class="particles" id="particles"></div>
<div class="hero-container">
<div class="word-indicators" id="wordIndicators"></div>
<h1 class="hero-text">
<span class="static-text">WE FIX</span>
<span class="rotating-text-container">
<span class="rotating-word active" data-animation="default">WASHERS</span>
<span class="rotating-word" data-animation="slide-right">DRYERS</span>
<span class="rotating-word" data-animation="slide-left">DISHWASHERS</span>
<span class="rotating-word" data-animation="zoom">REFRIGERATORS</span>
<span class="rotating-word" data-animation="flip">OVENS</span>
<span class="rotating-word" data-animation="bounce">MICROWAVES</span>
<span class="rotating-word" data-animation="slide-left">FREEZERS</span>
<span class="rotating-word" data-animation="zoom">STOVES</span>
</span>
</h1>
<p class="subtitle">Professional appliance repair services with premium quality and unmatched expertise</p>
<div class="progress-bar"></div>
</div>
<div class="control-panel">
<button class="control-btn active" data-action="play">⏸️ Pause</button>
<button class="control-btn" data-action="speed-up">⚡ Fast</button>
<button class="control-btn" data-action="slow-down">🐌 Slow</button>
<button class="control-btn" data-action="theme">🎨 Theme</button>
<button class="control-btn" data-action="random">🎲 Random</button>
</div>
<script>
class PremiumRotatingText {
constructor(container, options = {}) {
this.container = container;
this.words = container.querySelectorAll('.rotating-word');
this.currentIndex = 0;
this.baseInterval = options.interval || 3000;
this.interval = this.baseInterval;
this.isRunning = false;
this.isPaused = false;
this.animations = ['default', 'slide-right', 'slide-left', 'zoom', 'flip', 'bounce'];
this.themes = ['default', 'theme-cyber', 'theme-sunset', 'theme-neon'];
this.currentTheme = 0;
this.backgroundWords = [];
this.init();
this.createParticles();
this.createBackgroundText();
this.updateProgressBar();
}
init() {
if (this.words.length === 0) return;
this.words[0].classList.add('active');
this.createWordIndicators();
this.updateIndicators();
this.start();
this.bindControls();
}
createParticles() {
const particlesContainer = document.getElementById('particles');
const particleTypes = ['type-1', 'type-2', 'type-3'];
for (let i = 0; i < 25; i++) {
const particle = document.createElement('div');
const randomType = particleTypes[Math.floor(Math.random() * particleTypes.length)];
particle.className = `particle ${randomType}`;
particle.style.left = Math.random() * 100 + '%';
particle.style.width = particle.style.height = (Math.random() * 6 + 3) + 'px';
particle.style.animationDelay = Math.random() * 15 + 's';
particle.style.animationDuration = (Math.random() * 10 + 12) + 's';
particlesContainer.appendChild(particle);
}
}
createBackgroundText() {
const backgroundContainer = document.getElementById('backgroundText');
const wordTexts = Array.from(this.words).map(word => word.textContent);
// Create multiple instances of each word for background animation
wordTexts.forEach((word, index) => {
for (let i = 0; i < 3; i++) { // Create 3 instances of each word
const bgWord = document.createElement('div');
bgWord.className = 'background-word';
bgWord.textContent = word;
bgWord.style.left = Math.random() * 80 + 10 + '%';
bgWord.style.animationDelay = (index * 2 + i * 5) + 's';
bgWord.style.animationDuration = (Math.random() * 5 + 15) + 's';
backgroundContainer.appendChild(bgWord);
this.backgroundWords.push(bgWord);
}
});
}
createWordIndicators() {
const indicatorsContainer = document.getElementById('wordIndicators');
this.words.forEach((word, index) => {
const indicator = document.createElement('div');
indicator.className = 'word-indicator' + (index === 0 ? ' active' : '');
indicator.addEventListener('click', () => this.goToWord(index));
indicatorsContainer.appendChild(indicator);
});
this.indicators = indicatorsContainer.querySelectorAll('.word-indicator');
}
updateProgressBar() {
const progressBar = document.querySelector('.progress-bar');
progressBar.style.setProperty('--duration', this.interval + 'ms');
// Restart animation to apply new duration immediately
progressBar.style.animation = 'none';
void progressBar.offsetWidth; // Trigger reflow
progressBar.style.animation = null;
}
updateIndicators() {
if (this.indicators) {
this.indicators.forEach((indicator, index) => {
indicator.classList.toggle('active', index === this.currentIndex);
});
}
}
start() {
if (this.isRunning && !this.isPaused) return; // If already running and not paused, do nothing
this.isRunning = true;
this.isPaused = false;
// Clear any existing timer before starting a new one
if (this.timer) {
clearInterval(this.timer);
}
this.timer = setInterval(() => {
this.rotate();
}, this.interval);
this.updatePlayButton();
this.updateProgressBar(); // Ensure progress bar restarts with current interval
}
pause() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
this.isRunning = false;
this.isPaused = true;
this.updatePlayButton();
// Pause progress bar animation
document.querySelector('.progress-bar').style.animationPlayState = 'paused';
}
rotate() {
const currentWord = this.words[this.currentIndex];
const nextIndex = (this.currentIndex + 1) % this.words.length;
const nextWord = this.words[nextIndex];
// Get animation type for next word
const animationType = nextWord.dataset.animation || 'default';
// Apply exit animation to current word
currentWord.classList.add('fade-out');
currentWord.classList.remove('active');
// Highlight background text of current word
this.highlightBackgroundWord(nextWord.textContent);
setTimeout(() => {
currentWord.classList.remove('fade-out');
// Apply entrance animation based on type
if (animationType !== 'default') {
nextWord.classList.add(
animationType === 'slide-right' ? 'slide-in-right' :
animationType === 'slide-left' ? 'slide-in-left' :
animationType === 'zoom' ? 'zoom-in' :
animationType === 'flip' ? 'flip-in' :
animationType === 'bounce' ? 'bounce-in' : ''
);
}
nextWord.classList.add('active');
// Remove entrance animation class after animation completes
// The duration of this timeout should match the CSS transition duration
setTimeout(() => {
nextWord.classList.remove('slide-in-right', 'slide-in-left', 'zoom-in', 'flip-in', 'bounce-in');
}, 800); // Matches the transition duration of .rotating-word
this.currentIndex = nextIndex;
this.updateIndicators();
this.updateProgressBar(); // Restart progress bar for the new word
}, 400); // This timeout controls when the next word starts appearing
}
highlightBackgroundWord(wordText) {
// Remove highlight from all background words first
this.backgroundWords.forEach(bgWord => {
bgWord.style.opacity = '';
bgWord.style.color = '';
bgWord.style.transform = bgWord.style.transform.replace(' scale(1.1)', '');
});
// Temporarily enhance the opacity and color of background words that match current word
this.backgroundWords.forEach(bgWord => {
if (bgWord.textContent === wordText) {
bgWord.style.opacity = '0.3';
bgWord.style.color = 'rgba(0, 212, 255, 0.2)'; // Use a more visible highlight color
bgWord.style.transform = bgWord.style.transform.split(' ').filter(t => !t.startsWith('scale')).join(' ') + ' scale(1.1)'; // Ensure scale is applied only once
// Reset after 2 seconds
setTimeout(() => {
bgWord.style.opacity = '';
bgWord.style.color = '';
bgWord.style.transform = bgWord.style.transform.replace(' scale(1.1)', '');
}, 2000);
}
});
}
goToWord(index) {
if (index >= 0 && index < this.words.length && index !== this.currentIndex) {
const currentWord = this.words[this.currentIndex];
const targetWord = this.words[index];
// Pause the rotation, go to word, then resume if it was running
const wasRunning = this.isRunning && !this.isPaused;
this.pause();
currentWord.classList.add('fade-out');
currentWord.classList.remove('active');
this.highlightBackgroundWord(targetWord.textContent);
setTimeout(() => {
currentWord.classList.remove('fade-out');
// Apply animation for direct jump
const animationType = targetWord.dataset.animation || 'default';
if (animationType !== 'default') {
targetWord.classList.add(
animationType === 'slide-right' ? 'slide-in-right' :
animationType === 'slide-left' ? 'slide-in-left' :
animationType === 'zoom' ? 'zoom-in' :
animationType === 'flip' ? 'flip-in' :
animationType === 'bounce' ? 'bounce-in' : ''
);
}
targetWord.classList.add('active');
setTimeout(() => {
targetWord.classList.remove('slide-in-right', 'slide-in-left', 'zoom-in', 'flip-in', 'bounce-in');
}, 800); // Matches the transition duration
this.currentIndex = index;
this.updateIndicators();
this.updateProgressBar(); // Reset progress bar for the new word
if (wasRunning) {
this.start();
}
}, 400);
}
}
randomizeAnimation() {
this.words.forEach(word => {
const randomAnimation = this.animations[Math.floor(Math.random() * this.animations.length)];
word.dataset.animation = randomAnimation;
});
// Also randomize background word positions and timing
this.backgroundWords.forEach(bgWord => {
bgWord.style.left = Math.random() * 80 + 10 + '%';
bgWord.style.animationDelay = Math.random() * 20 + 's';
bgWord.style.animationDuration = (Math.random() * 5 + 15) + 's'; // Ensure duration is also randomized
});
}
changeSpeed(multiplier) {
const wasRunning = this.isRunning && !this.isPaused;
this.pause(); // Pause before changing interval to prevent odd behavior
// Adjust base interval for "Fast" and "Slow" to ensure noticeable changes
if (multiplier === 0.5) { // Faster
this.baseInterval = Math.max(1000, this.baseInterval * 0.75); // Make it faster, but not too fast
} else if (multiplier === 2) { // Slower
this.baseInterval = Math.min(6000, this.baseInterval * 1.25); // Make it slower, but not too slow
} else { // Reset or specific value
this.baseInterval = 3000; // Default speed
}
this.interval = this.baseInterval;
this.updateProgressBar();
if (wasRunning) {
this.start(); // Resume with new interval
}
}
cycleTheme() {
// Remove all theme classes from body
document.body.classList.remove(...this.themes.filter(theme => theme !== 'default'));
this.currentTheme = (this.currentTheme + 1) % this.themes.length;
// Apply the new theme
if (this.themes[this.currentTheme] !== 'default') {
document.body.classList.add(this.themes[this.currentTheme]);
}
// When switching theme, re-create particles and background text to pick up new colors
this.clearParticles();
this.clearBackgroundText();
this.createParticles();
this.createBackgroundText();
}
clearParticles() {
const particlesContainer = document.getElementById('particles');
while (particlesContainer.firstChild) {
particlesContainer.removeChild(particlesContainer.firstChild);
}
}
clearBackgroundText() {
const backgroundContainer = document.getElementById('backgroundText');
while (backgroundContainer.firstChild) {
backgroundContainer.removeChild(backgroundContainer.firstChild);
}
this.backgroundWords = []; // Clear array as well
}
updatePlayButton() {
const playBtn = document.querySelector('[data-action="play"]');
if (this.isPaused || !this.isRunning) {
playBtn.innerHTML = '▶️ Play';
playBtn.classList.remove('active');
} else {
playBtn.innerHTML = '⏸️ Pause';
playBtn.classList.add('active');
}
}
bindControls() {
const controls = document.querySelectorAll('.control-btn');
controls.forEach(btn => {
btn.addEventListener('click', (e) => {
const action = e.target.dataset.action;
// Remove active class from all buttons except play (which toggles)
controls.forEach(b => {
if (b.dataset.action !== 'play') b.classList.remove('active');
});
// Add active class to clicked button, unless it's the play/pause button
if (action !== 'play') {
e.target.classList.add('active');
}
switch (action) {
case 'play':
if (this.isRunning && !this.isPaused) {
this.pause();
} else {
this.start();
}
break;
case 'speed-up':
this.changeSpeed(0.5);
break;
case 'slow-down':
this.changeSpeed(2);
break;
case 'theme':
this.cycleTheme();
break;
case 'random':
this.randomizeAnimation();
break;
}
});
});
}
}
// Initialize when page loads
document.addEventListener('DOMContentLoaded', function() {
const rotatingContainer = document.querySelector('.rotating-text-container');
if (rotatingContainer) {
window.rotatingText = new PremiumRotatingText(rotatingContainer, {
interval: 3000
});
// Add keyboard shortcuts
document.addEventListener('keydown', function(e) {
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
switch (e.key) {
case ' ':
e.preventDefault();
document.querySelector('[data-action="play"]').click();
break;
case 'ArrowLeft':
e.preventDefault();
const prevIndex = window.rotatingText.currentIndex > 0 ?
window.rotatingText.currentIndex - 1 :
window.rotatingText.words.length - 1;
window.rotatingText.goToWord(prevIndex);
break;
case 'ArrowRight':
e.preventDefault();
const nextIndex = (window.rotatingText.currentIndex + 1) % window.rotatingText.words.length;
window.rotatingText.goToWord(nextIndex);
break;
case 't': // 't' for theme
e.preventDefault();
document.querySelector('[data-action="theme"]').click();
break;
case 'r': // 'r' for random
e.preventDefault();
document.querySelector('[data-action="random"]').click();
break;
case '+': // '+' for speed up
e.preventDefault();
document.querySelector('[data-action="speed-up"]').click();
break;
case '-': // '-' for slow down
e.preventDefault();
document.querySelector('[data-action="slow-down"]').click();
break;
}
});
}
});
</script>
</body>
</html>