Skip to content

Instantly share code, notes, and snippets.

@CodeMyUI
Created October 30, 2017 10:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CodeMyUI/e4f1d5b716502295ca592f6ca43f5b12 to your computer and use it in GitHub Desktop.
Save CodeMyUI/e4f1d5b716502295ca592f6ca43f5b12 to your computer and use it in GitHub Desktop.
Window to somewhere
.frame
.card
img.background-img(src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/544318/hills.jpeg")
"use strict";
const MAX_ROT = 30;
const ANIM_SPEED = 0.075;
let frame, card, img, mouse, userPos, hover, padding, center;
function lerp(n1, n2, speed) {
return (1 - speed) * n1 + speed * n2;
}
Array.prototype.lerp = function(target, speed) {
this.forEach((n, i) => this[i] = lerp(n, target[i], speed));
};
function resize() {
let rect = card.getBoundingClientRect();
center = [0.5 * card.clientWidth + rect.left, 0.5 * card.clientHeight + rect.top];
userPos = [
center[0],
center[1]
];
}
function loop() {
let xPosNorm, yPosNorm, mouseDistNorm, theta, xRot, yRot, imgX, imgY;
userPos.lerp(hover ? mouse : center, ANIM_SPEED);
xPosNorm = (center[0] - userPos[0]) / center[0];
yPosNorm = (center[1] - userPos[1]) / center[1];
imgX = xPosNorm * padding[0];
imgY = yPosNorm * padding[1];
mouseDistNorm = Math.sqrt(xPosNorm * xPosNorm + yPosNorm * yPosNorm);
theta = Math.atan2(userPos[1] - center[1], userPos[0] - center[0]);
xRot = Math.sin(-theta) * MAX_ROT * mouseDistNorm; //card x-axis rotation based on mouse y-axis position
yRot = Math.cos(theta) * MAX_ROT * mouseDistNorm;
card.style.transform = `rotateX(${xRot}deg) rotateY(${yRot}deg)`;
img.style.transform = `translateX(${imgX}px) translateY(${imgY}px)`;
window.requestAnimationFrame(loop);
}
function init() {
frame = document.querySelector(".frame");
card = document.querySelector(".card");
img = document.querySelector(".background-img");
mouse = [0, 0];
hover = false;
padding = [
0.5 * (img.clientWidth - card.clientWidth),
0.5 * (img.clientHeight - card.clientHeight)
];
resize();
frame.addEventListener("mousemove", e => {
mouse[0] = e.clientX;
mouse[1] = e.clientY;
hover = true;
});
frame.addEventListener("mouseleave", () => {
hover = false;
});
loop();
}
window.onresize = resize;
window.onload = init;
body
height: 100vh
background: linear-gradient(lightgray, darkgray)
.frame
position: absolute
top: 50%
left: 50%
width: 600px
height: 400px
perspective: 1000px
transform: translateX(-50%) translateY(-50%)
.card
display: flex
align-items: center
justify-content: center
width: 100%
height: 100%
border-radius: 5px
background: white
box-shadow: 0 0 2px rgba(30,30,20,0.5)
transform-origin: 50% 50%
overflow: hidden
img
display: block
position: relative
width: 150%
height: auto
transform-origin: 50% 50%

Window to somewhere

Using js to update css translation and rotation to create a nice hover effect

A Pen by Sean Free on CodePen.

License.

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