Skip to content

Instantly share code, notes, and snippets.

@CodeMyUI
Created November 6, 2017 04:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CodeMyUI/14435111fa4e980b3a8a11b7531f9487 to your computer and use it in GitHub Desktop.
Save CodeMyUI/14435111fa4e980b3a8a11b7531f9487 to your computer and use it in GitHub Desktop.
Web Animation API, Hover animation
<div class="grid">
<div class="box-cont"><div class="box"></div></div>
<div class="box-cont multiple-col"><div class="box"></div> </div>
<div class="box-cont multiple-row"><div class="box"></div> </div>
<div class="box-cont"><div class="box"></div></div>
<div class="box-cont"><div class="box"></div></div>
<div class="box-cont"><div class="box"></div></div>
</div>
<!--Polyfill for safari and Edge, normally I would use feature detection in js and add the script dynamically-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/web-animations/2.2.5/web-animations-next-lite.min.js"></script>
const container = document.querySelectorAll(".box-cont");
container.forEach((element) => {
element.addEventListener("mouseenter", function(event) {
const element = event.target.querySelector(".box");
const coords = getCoords(event.target.getBoundingClientRect());
const radius = circleSize(event.target.getBoundingClientRect(), coords)
circleConstraints(element, coords, radius)
animation(element)
});
element.addEventListener("mouseleave", function(event) {
const element = event.target.querySelector(".box");
animationLeave(element);
});
});
function animation(element) {
const transform = [
"scale(0)",
"scale(1)"
];
const options = {
duration: 600,
fill: "forwards",
easing: "cubic-bezier(.2, 1, .2, 1)",
iterations: 1
};
element.animate({transform}, options);
};
function animationLeave(element) {
const transform = [
"scale(1)",
"scale(0)"
];
const options = {
duration: 400,
fill: "forwards",
easing: "cubic-bezier(.2, 1, .2, 1)",
iterations: 1
};
element.animate({transform}, options);
};
function getCoords(rectangle) {
return {
x: rectangle.width * Math.random(),
y: rectangle.height * Math.random(),
}
};
function circleSize(rectangle, coords) {
const x1 = coords.x;
const y1 = coords.y;
const rectCoords = [
{ x: 0, y: 0 },
{ x: 0, y: rectangle.height },
{ x: rectangle.width, y: 0 },
{ x: rectangle.width, y: rectangle.height }
];
return Math.max(...rectCoords.map((el) => {
const x2 = el.x;
const y2 = el.y;
return Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2));
}));
}
function circleConstraints(element, coords, radius) {
element.style.height = radius * 2 + 'px';
element.style.width = radius * 2 + 'px';
element.style.top = coords.y - radius + 'px';
element.style.left = coords.x - radius + 'px';
}
:root {
--blue: #23278A;
}
.grid {
display: grid;
grid-auto-columns: auto;
grid-auto-rows: 300px;
grid-gap: 10px;
}
.grid .box-cont {
box-sizing: border-box;
position: relative;
background-color: tomato;
overflow: hidden;
}
.box {
transform: scale(0);
position: absolute;
background-color: var(--blue);
border-radius: 100%;
will-change: transform;
}
.multiple-col {
grid-column: 3 / 5;
}
.multiple-row {
grid-row: 1 / 3;
}

Web Animation API, Hover animation

Created a hover animation using the Web Animations API. The origin of the circle is a random set of coordinates inside the box. The circle will always be as small as possible to fully cover the box. I decided to use 2 different animations for the hover in/out for more control, but you could also use "animation.reverse()". (Chrome, Firefox)

If you see any improvements please let me know, I want to learn!

A Pen by Gennadi Debbaut on CodePen.

License.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment