Personal Site
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Respect reduced motion preferences

+72 -43
+72 -43
src/components/home/playing/NowPlaying.astro
··· 237 237 238 238 animation: 30s linear forwards infinite spin; 239 239 240 + @media (prefers-reduced-motion: reduce) { 241 + animation-delay: -20s; 242 + animation-play-state: paused; 243 + } 244 + 240 245 [data-playing="false"] & { 241 246 animation-play-state: paused; 242 247 } ··· 265 270 height: calc((60 / 3) * 1cqw); 266 271 267 272 animation: 60s linear 2.5s infinite forwards head-move; 273 + 274 + @media (prefers-reduced-motion: reduce) { 275 + animation-delay: -20s; 276 + animation-play-state: paused; 277 + } 268 278 269 279 [data-playing="false"] & { 270 280 animation-play-state: paused; ··· 564 574 * ANIMATIONS * 565 575 **************/ 566 576 567 - // delete css animations since we r going to use our own 568 - elements.spinner.forEach((el) => 569 - el.getAnimations().forEach((anim) => anim.cancel()), 570 - ); 577 + const reducedMotion = window.matchMedia("(prefers-reduced-motion:reduce)"); 571 578 572 579 const playHeadAnimation = [ 573 580 { ··· 594 601 // start state is infered 595 602 const goToStartAnimation = [{ rotate: "0deg" }]; 596 603 597 - const animations = elements.spinner.map((el) => 598 - el.animate(playHeadAnimation, { 599 - duration: 30 * 1000, 600 - fill: "forwards", 601 - iterations: Infinity, 602 - }), 603 - ); 604 + let animations: Animation[] = []; 605 + 606 + // we only do js animations if reduced motion is disabled 607 + // if reduce motion is reduced, the static css animations are fine 608 + if (!reducedMotion.matches) { 609 + // delete css animations since we r going to use our own 610 + elements.spinner.forEach((el) => 611 + el.getAnimations().forEach((anim) => anim.cancel()), 612 + ); 613 + 614 + animations = elements.spinner.map((el) => 615 + el.animate(playHeadAnimation, { 616 + duration: 30 * 1000, 617 + fill: "forwards", 618 + iterations: Infinity, 619 + }), 620 + ); 604 621 605 - if (elements.player.dataset.playing === "false") { 606 - // dont play animations 607 - animations.forEach((anim) => anim.pause()); 622 + // pause the animations if nothing is playing or reduced motion is enabled 623 + if (elements.player.dataset.playing === "false") { 624 + // dont play animations 625 + animations.forEach((anim) => anim.pause()); 626 + } 608 627 } 609 628 610 629 /************ ··· 648 667 // there is now a difference between the previous setting and the new setting 649 668 // so it is worth updating the UI 650 669 651 - // spinner head animation: 652 - // 1. pause current animation. 653 - animations.forEach((anim) => anim.pause()); 654 - elements.spinner.forEach((el) => 655 - // 2. send the playback head to the start 656 - el 657 - .animate(goToStartAnimation, { 658 - duration: 2.5 * 1000, 659 - easing: "ease-in-out", 660 - }) 661 - // 3. when the playback head is at the start 662 - .finished.then(async () => { 663 - // 4. update the record art 664 - elements.recordArt.src = data ? data?.art : "https://undefined"; 670 + if (!reducedMotion) { 671 + // spinner head animation: 672 + // 1. pause current animation. 673 + animations.forEach((anim) => anim.pause()); 674 + elements.spinner.forEach((el) => 675 + // 2. send the playback head to the start 676 + el 677 + .animate(goToStartAnimation, { 678 + duration: 2.5 * 1000, 679 + easing: "ease-in-out", 680 + }) 681 + // 3. when the playback head is at the start 682 + .finished.then(async () => { 683 + // 4. update the record art 684 + elements.recordArt.src = data ? data?.art : "https://undefined"; 685 + 686 + // 5. update popup 687 + if (data) elements.nowPlaying.updateMetadata(data); 688 + else elements.nowPlaying.nothingPlaying(); 665 689 666 - // 5. update popup 667 - if (data) elements.nowPlaying.updateMetadata(data); 668 - else elements.nowPlaying.nothingPlaying(); 690 + // 6. reset the position of the infinite animation 691 + animations.forEach((anim) => (anim.currentTime = 0)); 669 692 670 - // 6. reset the position of the infinite animation 671 - animations.forEach((anim) => (anim.currentTime = 0)); 693 + // 7. if new track is not null then, after 2s 694 + if (data) 695 + setTimeout(() => { 696 + // 8. resume the infinite animation 697 + animations.forEach((anim) => anim.play()); 698 + }, 2000); 672 699 673 - // 7. if new track is not null then, after 2s 674 - if (data) 675 - setTimeout(() => { 676 - // 8. resume the infinite animation 677 - animations.forEach((anim) => anim.play()); 678 - }, 2000); 700 + // 9. make sure the record is in the right state (playing or paused) 701 + elements.player.dataset.playing = data ? "true" : "false"; 702 + }), 703 + ); 704 + // the user requested reduced motion, so instantly update state 705 + } else { 706 + elements.recordArt.src = data ? data?.art : "https://undefined"; 707 + 708 + if (data) elements.nowPlaying.updateMetadata(data); 709 + else elements.nowPlaying.nothingPlaying(); 679 710 680 - // 9. make sure the record is in the right state (playing or paused) 681 - elements.player.dataset.playing = data ? "true" : "false"; 682 - }), 683 - ); 711 + elements.player.dataset.playing = data ? "true" : "false"; 712 + } 684 713 } 685 714 } finally { 686 715 prev = data;