chromium/ash/webui/camera_app_ui/resources/css/mode/video.css

/* Copyright 2021 The Chromium Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

body:is(:not(.video), .taking, .camera-configuring, .should-handle-intent-result) #record-types-group {
  display: none;
}

body:is(:not(.video), :not(.taking), :not(.enable-gif-recording)) #shutter-progress-bar {
  display: none;
}

@keyframes ring-countdown {
  0% {
    /* Set 999999 distance to next strip so that only first strip is visible. */
    stroke-dasharray: 0 999999;
  }
  100% {
    stroke-dasharray: var(--inner-perimeter) 999999;
  }
}

body.video.taking.enable-gif-recording #shutter-progress-bar>circle {
  animation: ring-countdown 5s linear;
  animation-fill-mode: forwards;
}

body.video.taking.enable-gif-recording:not(.recording) #shutter-progress-bar>circle {
  animation-play-state: paused;
}

#shutter-progress-bar {
  --bar-width: 4px;
  --inner-perimeter: calc((var(--outer-radius) - var(--bar-width)) * 2 * 3.1416);
  --outer-radius: 40px;
  --stroke-width: 4px;
  --svg-size: calc(var(--outer-radius) * 2 - var(--bar-width));

  fill: transparent;
  height: var(--svg-size);
  left: 50%;
  pointer-events: none;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  width: var(--svg-size);
}

#shutter-progress-bar>circle {
  cx: 50%;
  cy: 50%;
  r: calc(var(--outer-radius) - var(--bar-width));
  stroke: var(--cros-sys-white);
  stroke-width: var(--bar-width);
  /* The dash strip will appear from 3 o'clock direction while we want to start
   * from 12 o'clock. Rotate 90deg counterclockwise accordingly. */
  transform: rotate(-90deg);
  transform-origin: center;
}

body.video.record-type-time-lapse.recording #time-lapse-progress {
  display: block;
}

body.video.record-type-time-lapse.recording-ui-paused {
  #loop-mask {
    animation-play-state: paused;
  }
  #time-lapse-progress {
    visibility: hidden;
  }
}

#time-lapse-progress {
  --PI: 3.14159;
  --mask-circle-radius: 20px;
  --mask-perimeter: calc(2 * var(--PI) * var(--mask-circle-radius));
  --ticks-circle-radius: 36px;
  --ticks-perimeter: calc(2 * var(--PI) * var(--ticks-circle-radius));
  --svg-size: 76px;

  --no-of-ticks: 40;
  --tick-length: 2px;
  --tick-gap-length: calc((var(--ticks-perimeter) - 2px * var(--no-of-ticks)) / var(--no-of-ticks));

  display: none;
  height: var(--svg-size);
  left: calc((100% - var(--svg-size)) / 2);
  pointer-events: none;
  position: absolute;
  top: calc((100% - var(--svg-size)) / 2);
  width: var(--svg-size);
}

#time-lapse-progress circle {
  cx: 50%;
  cy: 50%;
  fill: transparent;
}

#loop-mask circle {
  r: var(--mask-circle-radius);
  /* Mask needs to be white to be visible. */
  /* color-token-disable-next-line */
  stroke: white;
  stroke-width: 36px;
}

#time-lapse-progress .ticks {
  mask: url(#loop-mask);
  r: var(--ticks-circle-radius);
  stroke: var(--cros-sys-white);
  stroke-dasharray: var(--tick-length) var(--tick-gap-length);
  stroke-linejoin: round;
  stroke-width: 4px;
  transform: rotate(-90deg);
  transform-origin: center;
}

#loop-mask {
  animation-name: shutter-loop;
  animation-duration: 5s;
  animation-iteration-count: infinite;
  animation-timing-function: steps(calc(var(--no-of-ticks) + 1));
}

@keyframes shutter-loop {
  0% {
    stroke-dasharray: 0 var(--mask-perimeter);
  }
  100% {
    stroke-dasharray: var(--mask-perimeter) var(--mask-perimeter);
  }
}