controls.html 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Controls (chain / seek / scroll) - Animal.js</title>
  7. <link rel="stylesheet" href="../demo.css">
  8. <style>
  9. .demo-visual {
  10. gap: 18px;
  11. }
  12. .row {
  13. width: 100%;
  14. display: flex;
  15. align-items: center;
  16. justify-content: space-between;
  17. gap: 14px;
  18. }
  19. .box {
  20. width: 48px;
  21. height: 48px;
  22. border-radius: 10px;
  23. background: var(--highlight-color);
  24. transform: translateX(0px);
  25. }
  26. .bar-wrap {
  27. width: 100%;
  28. background: rgba(255,255,255,0.05);
  29. border: 1px solid rgba(255,255,255,0.08);
  30. border-radius: 999px;
  31. overflow: hidden;
  32. height: 10px;
  33. }
  34. .bar {
  35. height: 100%;
  36. width: 0%;
  37. background: var(--orange);
  38. }
  39. .hint {
  40. font-size: 12px;
  41. color: #888;
  42. }
  43. .spacer {
  44. height: 80vh; /* enough to scroll inside the iframe */
  45. }
  46. </style>
  47. </head>
  48. <body>
  49. <div class="container">
  50. <div class="page-top">
  51. <div class="crumb">ANIMATION &gt; EXAMPLES</div>
  52. <div class="since">CONTROLS</div>
  53. </div>
  54. <h1>Controls</h1>
  55. <p class="description">
  56. <code class="inline">animate()</code> returns a <strong>thenable controls object</strong>.
  57. You can <code class="inline">play/pause</code>, <code class="inline">seek()</code> (0..1),
  58. and wire it to <code class="inline">scroll()</code>.
  59. </p>
  60. <div class="box-container">
  61. <div class="box-header">
  62. <div class="box-title">Controls example</div>
  63. <div class="tabs">
  64. <div class="tab active" onclick="switchTab('js')">JavaScript</div>
  65. <div class="tab" onclick="switchTab('html')">HTML</div>
  66. </div>
  67. </div>
  68. <pre id="js-code" class="code-view active">const ctl = xjs('.ex-box').animate({
  69. x: 220,
  70. rotate: 180,
  71. opacity: 0.6,
  72. duration: 800,
  73. autoplay: false
  74. });
  75. // chainable controls
  76. ctl.seek(0.25).play();
  77. // still awaitable / thenable
  78. ctl.then(() =&gt; console.log('done'));
  79. // scroll-linked (works with WAAPI + JS fallback)
  80. const progress = xjs('.ex-bar').animate({
  81. width: ['0%', '100%'],
  82. autoplay: false,
  83. duration: 1000
  84. });
  85. xjs.scroll(progress);</pre>
  86. <pre id="html-code" class="html-view">&lt;div class="ex-box"&gt;&lt;/div&gt;
  87. &lt;div class="bar-wrap"&gt;
  88. &lt;div class="ex-bar"&gt;&lt;/div&gt;
  89. &lt;/div&gt;</pre>
  90. <div class="demo-visual">
  91. <div class="row">
  92. <div class="box ex-box" aria-label="demo box"></div>
  93. <div class="hint">Click REPLAY, then scroll inside this panel.</div>
  94. </div>
  95. <div class="bar-wrap">
  96. <div class="bar ex-bar" aria-label="progress bar"></div>
  97. </div>
  98. <div class="spacer"></div>
  99. <div class="hint">Scroll target area (spacer)</div>
  100. </div>
  101. <div class="action-bar">
  102. <button class="play-btn" onclick="runDemo()">REPLAY</button>
  103. </div>
  104. </div>
  105. </div>
  106. <script src="../../xjs.js"></script>
  107. <script>
  108. function switchTab(tab) {
  109. document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
  110. document.querySelectorAll('.code-view, .html-view').forEach(v => v.classList.remove('active'));
  111. if (tab === 'js') {
  112. document.querySelector('.tabs .tab:nth-child(1)').classList.add('active');
  113. document.getElementById('js-code').classList.add('active');
  114. } else {
  115. document.querySelector('.tabs .tab:nth-child(2)').classList.add('active');
  116. document.getElementById('html-code').classList.add('active');
  117. }
  118. }
  119. let cleanup = null;
  120. function runDemo() {
  121. // reset
  122. const box = document.querySelector('.ex-box');
  123. const bar = document.querySelector('.ex-bar');
  124. box.style.transform = 'none';
  125. box.style.opacity = '1';
  126. bar.style.width = '0%';
  127. // Remove previous scroll listener if any
  128. if (cleanup) cleanup();
  129. cleanup = null;
  130. const ctl = xjs('.ex-box').animate({
  131. x: 220,
  132. rotate: 180,
  133. opacity: 0.6,
  134. duration: 800,
  135. autoplay: false
  136. });
  137. ctl.seek(0.25).play();
  138. const progress = xjs('.ex-bar').animate({
  139. width: ['0%', '100%'],
  140. autoplay: false,
  141. duration: 1000
  142. });
  143. cleanup = xjs.scroll(progress);
  144. }
  145. setTimeout(runDemo, 300);
  146. </script>
  147. </body>
  148. </html>