cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              <div></div>
<input type="range" value="0" min="0" max="8000" step="1" id="scrub" />
<label for="scrub">Timeline</label>
<p class="support">Requires native Web Animation Support (latest Firefox, Chrome, Opera)</p>
            
          
!
            
              div {
  width: var(--side);
  height: var(--side);
  background: hsl(var(--hue, 323), 70%, 55%);
  margin: calc(var(--side) / 5) 0;
  clip-path: var(--path, polygon(48% 0%, 52% 0%, 52% 100%, 48% 100%));
  
  --side: 12.5vmin;
}

input[type="range"] {
  width: 100%;
  padding: 0;
  margin: 0;
}

p, label {
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 14px;
  padding: .5rem;
  text-align: center;
  display: block;
}

body {
  background: radial-gradient(circle, hsl(223, 90%, 16%), hsl(263, 90%, 6%));
  color: #fafcff;
}
* {
  box-sizing: border-box;
}

html:not(.unsupported) .support {
  display: none;
}
            
          
!
            
              var div = document.querySelector('div');
var animation;
var isPlaying = true;
const DURATION = 8000;
var scrub = document.getElementById('scrub');

//Check for support... I'm including the polyfill at the moment so this won't actually be triggered
if (!document.body.animate) {
  document.documentElement.classList.add('unsupported')
}

//Animate each div... for simplicity, using delays and endDelays to make all animations have same start and end times (end time will be duration + delay + endDelay)
animation = div.animate({
  transform: ['translateX(0) rotate(0deg)', 'translateX(80vw) rotate(2700deg)']
}, {
  duration: DURATION,
  easing: 'ease-in-out',
  fill: 'both',
});

//Also start moving the "scrubber" control
adjustScrubber();

//Stop moving the "scrubber" when the animations finish
animation.onfinish = function() {
  isPlaying = false;
  console.log('finished');
}

//when the input range ("scrubber") is adjusted, pause the animations and change the `currentTime` property
scrub.addEventListener('input', e => {
  var time = e.currentTarget.value;
  animation.currentTime = time;
  pauseAll();
});

//When the user finalizes the value for input range ("scrubber")... such as by letting go with the pointer, start playing the animations again. Unless the range is at the end (so the animation should finish). This set up does not work well with Right/Left arrows because of how often it fires the "change" event compared to with a mouse/touch. Plan to investigate a better approach to support keyboard and other inputs.
scrub.addEventListener('change', e => {
  console.log('change', e.currentTarget.value);
  if (animation.currentTime >= e.currentTarget.getAttribute('max')) {
    finishAll();
    return false;
  }
  requestAnimationFrame(adjustScrubber);
  playAll();
});



function adjustScrubber() {
  if (isPlaying) {
    scrub.value = animation.currentTime;
    requestAnimationFrame(adjustScrubber);
  }
}

function pauseAll() {
  isPlaying = false;
  animation.pause();
}
function finishAll() {
  isPlaying = false;
  animation.finish();
}
function playAll() {
  isPlaying = true;
  animation.play();
}

            
          
!
999px
Loading ..................

Console