<section class="demo">
<div class="demo__frame" id="frame">
<div class="demo__layer demo__layer--a"></div>
<div class="demo__layer demo__layer--b" id="after"></div>
<div class="demo__handle" id="handle"><span></span></div>
</div>
</section>.demo {
min-height: 100dvh;
display: grid;
place-items: center;
padding: 24px;
background: #08080a;
}
.demo__frame {
position: relative;
width: min(420px, 88vw);
height: 260px;
border-radius: 16px;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.08);
}
.demo__layer { position: absolute; inset: 0; }
.demo__layer--a { background: linear-gradient(135deg, #3a3123, #d8b26f 70%); }
.demo__layer--b {
background: linear-gradient(135deg, #0e1a25, #4f9bd8 70%);
clip-path: inset(0 0 0 52%);
}
.demo__handle {
position: absolute;
top: 0;
bottom: 0;
left: 52%;
width: 18px;
margin-left: -9px;
cursor: ew-resize;
}
.demo__handle span {
position: absolute;
top: 50%;
left: 50%;
width: 18px;
height: 18px;
margin: -9px 0 0 -9px;
border-radius: 50%;
background: #f4f4f2;
box-shadow: 0 0 0 1px #08080a;
}
.demo__handle::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 50%;
width: 1px;
background: #f4f4f2;
}const frame = document.querySelector("#frame");
const after = document.querySelector("#after");
const handle = document.querySelector("#handle");
let pct = 52;
function render() {
const clamped = gsap.utils.clamp(8, 92, pct);
after.style.clipPath = "inset(0 0 0 " + clamped + "%)";
handle.style.left = clamped + "%";
}
render();
if (window.Draggable) {
Draggable.create(handle, {
type: "x",
onPress: function () {
this.startPct = pct;
this.frameW = frame.clientWidth || 1;
gsap.set(handle, { x: 0 });
},
onDrag: function () {
pct = gsap.utils.clamp(8, 92, this.startPct + (this.x / this.frameW) * 100);
after.style.clipPath = "inset(0 0 0 " + pct + "%)";
},
onRelease: function () {
gsap.set(handle, { x: 0 });
render();
},
});
} else {
frame.addEventListener("pointerdown", function (event) {
frame.setPointerCapture(event.pointerId);
pct = ((event.clientX - frame.getBoundingClientRect().left) / frame.clientWidth) * 100;
render();
});
frame.addEventListener("pointermove", function (event) {
if (!event.buttons) return;
pct = ((event.clientX - frame.getBoundingClientRect().left) / frame.clientWidth) * 100;
render();
});
}