<div class="app">
<h2>Bouncing toggles</h2>
<!-- prototyping, This is not semantic HTML -->
<div class="toggle" id="toggle-1">
<div class="knot">
<div></div>
<div></div>
</div>
</div>
<div class="toggle toggle--1" id="toggle-2">
<div class="knot">
<div></div>
<div></div>
</div>
</div>
<div class="toggle toggle--2" id="toggle-3">
<div class="knot">
<div></div>
<div></div>
</div>
</div>
</div>
$size: 40px;
$width: 100px;
* {
box-sizing: border-box;
}
body {
font-family: Verdana, sans-serif;
margin: 0;
display: grid;
place-items: center;
min-height: 100vh;
overflow: hidden;
}
.app {
display: grid;
place-items: center;
}
.toggle {
width: $width;
height: $size;
box-shadow: 0 0 0 2px #333;
border-radius: $size;
overflow: hidden;
transform: rotateZ(-5deg);
margin-bottom: 2rem;
cursor: pointer;
outline: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
&--1 {
.knot {
> :nth-child(1) {
background: lightblue;
}
> :nth-child(2) {
background: dodgerblue;
box-shadow: inset 0 0 0 2px royalblue;
}
}
}
&--2 {
.knot {
> :nth-child(1) {
background: pink;
}
> :nth-child(2) {
background: hotpink;
box-shadow: inset 0 0 0 2px deeppink;
}
}
}
}
.knot {
height: $size;
width: $width;
position: relative;
> * {
position: absolute;
top: 0;
height: inherit;
}
> :nth-child(1) {
background: lightgreen;
width: $width;
left: calc(-100% + #{$size/2});
}
> :nth-child(2) {
width: $size;
background: #333;
border-radius: 50%;
left: 0;
}
}
View Compiled
const eases = window.eases;
const FuzzyToggle = window.FuzzyToggle;
const width = 100;
const size = 40;
let onUpdate = (params, toggle) => {
let isExpanding = params.motion === "expanding";
let ease = isExpanding ? eases.expoOut : eases.expoIn;
let bounce = isExpanding ? eases.bounceOut : eases.bounceIn;
toggle.style.transform = `rotateZ(${-5 + ease(params.value) * 10}deg)`;
let knot = toggle.querySelector(".knot");
knot.style.transform = `translateX(${bounce(params.value) *
(width - size)}px)`;
};
let onDone = params => {};
let onToggle = params => {};
let toggle1 = document.querySelector("#toggle-1");
let toggle2 = document.querySelector("#toggle-2");
let toggle3 = document.querySelector("#toggle-3");
let fuzzy1 = FuzzyToggle({
onUpdate: params => onUpdate(params, toggle1),
onDone,
onToggle,
duration: 1000,
});
let fuzzy2 = FuzzyToggle({
onUpdate: params => onUpdate(params, toggle2),
onDone,
onToggle,
duration: 700
});
let fuzzy3 = FuzzyToggle({
onUpdate: params => onUpdate(params, toggle3),
onDone,
onToggle,
duration: 2000
});
toggle1.addEventListener("click", fuzzy1.toggle);
toggle2.addEventListener("click", fuzzy2.toggle);
toggle3.addEventListener("click", fuzzy3.toggle);
setTimeout(fuzzy3.toggle, 500);
View Compiled
This Pen doesn't use any external CSS resources.