<h3>offset-anchor: auto (类似transform-origin)</h3>
<div class="box">
  <svg viewBox="0 0 236 200">
    <g class="path" fill="none" stroke="#fff" stroke-miterlimit="10" stroke-width="1">
    <path d="M0,0 C40,240 200,240 240,0" fill="none" stroke="#ffffff" stroke-dasharray="5 3"/>
    </g>  
  </svg>
  <div class="offset-path"></div>
</div>

<aside>
  <div class="item">
    <input type="checkbox"  id="path-play-state"/>
    <label for="path-play-state">Animate offset-distance</label>
  </div>
  <div class="item">
    <label for="anchorX">anchorX:</label>
    <select name="anchorX" id="anchorX">
      <option value="center">center</option>
      <option value="top">top</option>
      <option value="right">right</option>
      <option value="bottom">bottom</option>
      <option value="left">left</option>
    </select>
  </div>
  <div class="item">
    <label for="anchorY">anchorY:</label>
    <select name="anchorY" id="anchorY">
      <option value="center">center</option>
      <option value="top">top</option>
      <option value="right">right</option>
      <option value="bottom">bottom</option>
      <option value="left">left</option>
    </select>
  </div>
</aside>
@import url('https://fonts.googleapis.com/css?family=Gochi+Hand');

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  --offset: 0%;
  --anchorX: center;
  --anchorY: center;
}

body {
  margin: 0;
  padding: 0;
  background-color: #291642;
  font-family: 'Gochi Hand', sans-serif;
  color: #fff;
  font-size: 130%;
  letter-spacing: 0.1rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100vw;
  min-height: 100vh;
}

.box {
  width: 240px;
  height: 240px;
  border: 1px dashed #f36;
  margin-bottom: 2vh;
  position: relative;
}

.offset-path {
  
  width: 5vh;
  height: 5vh;
  border: 1px solid hsla(343,100%,58%,.3);
  border-right: 5px solid hsl(343,100%,58%);
  background: hsla(343,100%,58%,.3);
  
  position: absolute;
  
  
  offset-path: path('M0,0 C40,240 200,240 240,0');
  offset-distance: var(--offset);
  offset-anchor: auto;
  transform-origin: var(--anchorX) var(--anchorY);
  
  &.play {
    animation: ani 4000ms linear alternate infinite;
  }
  
  &::after {
    content: '';
    position: absolute;
    background: radial-gradient(circle at var(--anchorX) var(--anchorY), #fff 6px, transparent 3px) no-repeat;
    width: 100%;
    left: 0;
    bottom: 0;
    top: 0;
  }
}

svg {
  position: absolute;
  opacity: .3;
}

@keyframes ani {
  from {
    offset-distance: 0%;
  }
  to {
    offset-distance: 100%;
  }
}

aside {
  display: flex;
  align-items: center;
  
  .item {
    margin: 0 2vh;
    display: flex;
    align-items: center;
  }
  
  label {
    display: flex;
    align-items: center;
  }
}

h3 {
  margin-bottom: 2em;
}
View Compiled
const toggle = document.querySelector('#path-play-state')
const aniEle = document.querySelector('.offset-path')
const anchorX = document.getElementById('anchorX')
const anchorY = document.getElementById('anchorY')

toggle.addEventListener('click', (e) => {
  console.log(e.target.checked)
  if (e.target.checked) {
    aniEle.classList.add('play')
  } else {
    aniEle.classList.remove('play')
  }
})
 

anchorX.addEventListener('change', (e) => {
  console.log(e.target.value)
  aniEle.style.setProperty('--anchorX', e.target.value)
})

anchorY.addEventListener('change', (e) => {
  console.log(e.target.value)
  aniEle.style.setProperty('--anchorY', e.target.value)
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.