<div class="container">
<div class="icon-container">
<svg class="progress-icon" viewBox="0 0 50 50">
<path
fill="none"
stroke-width="2"
d="M 0, 20 a 20, 20 0 1,0 40,0 a 20, 20 0 1,0 -40,0"
transform="translate(5 5)"
/>
<path
class="tick"
fill="none"
stroke-width="2"
d="M14,26 L 22,33 L 35,16"
/>
<path
class="cross-a"
fill="none"
stroke-width="2"
d="M17,17 L33,33"
/>
<path
class="cross-b"
fill="none"
stroke-width="2"
d="M33,17 L17,33"
/>
</svg>
</div>
</div>
<script type="module">
import { drag, mapValue, motionValue, styleEffect, svgEffect } from "motion"
const container = document.querySelector(".container")
const box = document.querySelector(".icon-container")
/**
* Bind x to the box before calling drag(), so the drag gesture
* moves this motion value.
*/
const x = motionValue(0)
styleEffect(box, { x })
drag(box, {
axis: "x",
constraints: { left: 0, right: 0 },
elastic: 0.5,
})
const xInput = [-100, 0, 100]
styleEffect(container, {
backgroundColor: mapValue(x, xInput, ["#ff4945", "#141210", "#52cd86"]),
})
svgEffect("path", {
stroke: mapValue(x, xInput, ["#ff4945", "#0a0a0b", "#52cd86"]),
})
svgEffect(".tick", { pathLength: mapValue(x, [10, 100], [0, 1]) })
svgEffect(".cross-a", { pathLength: mapValue(x, [-10, -55], [0, 1]) })
svgEffect(".cross-b", { pathLength: mapValue(x, [-50, -100], [0, 1]) })
</script>
<style>
.container {
display: flex;
justify-content: center;
align-items: center;
flex: 1;
width: 480px;
height: 300px;
max-width: calc(100vw - 32px);
border: 1px solid var(--border);
}
.icon-container {
width: 100px;
height: 100px;
background-color: var(--foreground);
padding: 20px;
cursor: grab;
}
.icon-container:active {
cursor: grabbing;
}
</style>