Animación de Hover 3D con orientación a la dirección con JavaScript y CSS3
| Autor: | noeldelgado |
|---|---|
| Views Total: | 1,819 |
| Sitio oficial: | Ir a la web |
| Actualizado: | February 17, 2017 |
| Licencia: | MIT |
Vista prévia
Descripción
Una solución CSS3 Pure JavaScript & para aplicar un efecto de rotación 3D consciente de la dirección a los cubos al pasar el cursor sobre él.
Funcionamiento
Agregue cubos a la Página Web de la siguiente manera:
<ul class='-center'> <li> <div class='w'> <div class='f'> <svg viewBox='0 0 180 180'> <image height='100%' preserveAspectRatio='xMidYMid slice' width='100%' xlink:href='https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-angus.png'></image> </svg> </div> <div class='b'> <h3> Angus Young </h3> </div> </div> </li> <li> <div class='w'> <div class='f'> <svg viewBox='0 0 180 180'> <image height='100%' preserveAspectRatio='xMidYMid slice' width='100%' xlink:href='https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-aurora.png'></image> </svg> </div> <div class='b'> <h3> Aurora </h3> </div> </div> </li> <li> <div class='w'> <div class='f'> <svg viewBox='0 0 180 180'> <image height='100%' preserveAspectRatio='xMidYMid slice' width='100%' xlink:href='https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-bride.png'></image> </svg> </div> <div class='b'> <h3> Bride of Frankenstein </h3> </div> </div> </li> <li> <div class='w'> <div class='f'> <svg viewBox='0 0 180 180'> <image height='100%' preserveAspectRatio='xMidYMid slice' width='100%' xlink:href='https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-d.png'></image> </svg> </div> <div class='b'> <h3> Dracula </h3> </div> </div> </li> </ul>
Las principales reglas CSS/CSS3.
li {
margin: 5px;
position: relative;
width: 180px;
height: 180px;
display: inline-block;
vertical-align: top;
-webkit-perspective: 300px;
perspective: 300px;
-webkit-transform-origin: 50% 50% 90px;
transform-origin: 50% 50% 90px;
}
.w {
font-size: medium;
font-size: initial;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
pointer-events: none;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-transform-origin: 50% 50% -90px;
transform-origin: 50% 50% -90px;
will-change: transform;
-webkit-animation: 200ms ease-out 0ms 1 normal forwards paused;
animation: 200ms ease-out 0ms 1 normal forwards paused;
}
.f,
.b {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
color: white;
-webkit-transition: none;
transition: none;
}
.f {
background-color: #00BCD4;
background: -webkit-linear-gradient(#00BCD4, #673AB7);
background: linear-gradient(#00BCD4, #673AB7);
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0)
}
.f > svg{
mix-blend-mode: luminosity;
}
.b {
padding: 16px;
padding: 1rem;
background-image: -webkit-radial-gradient(circle, #333, #000 160%);
background-image: radial-gradient(circle, #333, #000 160%);
-webkit-transform: translate3d(0,0,-1px);
transform: translate3d(0,0,-1px);
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
text-shadow: 0 20px 20px black;
text-align: center;
}
.in-top .b,
.out-top .b {
-webkit-transform-origin: 0% 100%;
transform-origin: 0% 100%;
-webkit-transform: translate3d(0, -100%, 0) rotate3d(1,0,0,90deg);
transform: translate3d(0, -100%, 0) rotate3d(1,0,0,90deg);
}
.in-right .b,
.out-right .b {
-webkit-transform-origin: 0% 0%;
transform-origin: 0% 0%;
-webkit-transform: translate3d(100%, 0, 0) rotate3d(0,1,0,90deg);
transform: translate3d(100%, 0, 0) rotate3d(0,1,0,90deg);
}
.in-bottom .b,
.out-bottom .b {
-webkit-transform-origin: 0% 0%;
transform-origin: 0% 0%;
-webkit-transform: translate3d(0, 100%, 0) rotate3d(-1,0,0,90deg);
transform: translate3d(0, 100%, 0) rotate3d(-1,0,0,90deg);
}
.in-left .b,
.out-left .b {
-webkit-transform-origin: 100% 0;
transform-origin: 100% 0;
-webkit-transform: translate3d(-100%,0,0) rotate3d(0,-1,0,90deg);
transform: translate3d(-100%,0,0) rotate3d(0,-1,0,90deg);
}
.in {
}
.in-top .w{
-webkit-animation-name: in-top;
animation-name: in-top;
-webkit-animation-play-state: running;
animation-play-state: running;
}
.in-right .w{
-webkit-animation-name: in-right;
animation-name: in-right;
-webkit-animation-play-state: running;
animation-play-state: running;
}
.in-bottom .w{
-webkit-animation-name: in-bottom;
animation-name: in-bottom;
-webkit-animation-play-state: running;
animation-play-state: running;
}
.in-left .w{
-webkit-animation-name: in-left;
animation-name: in-left;
-webkit-animation-play-state: running;
animation-play-state: running;
}
.out {
}
.out-top .w{
-webkit-animation-name: out-top;
animation-name: out-top;
-webkit-animation-play-state: running;
animation-play-state: running;
}
.out-right .w{
-webkit-animation-name: out-right;
animation-name: out-right;
-webkit-animation-play-state: running;
animation-play-state: running;
}
.out-bottom .w{
-webkit-animation-name: out-bottom;
animation-name: out-bottom;
-webkit-animation-play-state: running;
animation-play-state: running;
}
.out-left .w{
-webkit-animation-name: out-left;
animation-name: out-left;
-webkit-animation-play-state: running;
animation-play-state: running;
} Las principales animaciones de CSS3 Powered:
@-webkit-keyframes in-top {
from
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
to
{-webkit-transform: rotate3d(-1,0,0,90deg);transform: rotate3d(-1,0,0,90deg)}
}
@keyframes in-top {
from
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
to
{-webkit-transform: rotate3d(-1,0,0,90deg);transform: rotate3d(-1,0,0,90deg)}
}
@-webkit-keyframes out-top {
from {-webkit-transform: rotate3d(-1,0,0,90deg);transform: rotate3d(-1,0,0,90deg)}
to
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
}
@keyframes out-top {
from {-webkit-transform: rotate3d(-1,0,0,90deg);transform: rotate3d(-1,0,0,90deg)}
to
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
}
@-webkit-keyframes in-right {
from
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
to
{-webkit-transform: rotate3d(0,-1,0,90deg);transform: rotate3d(0,-1,0,90deg)}
}
@keyframes in-right {
from
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
to
{-webkit-transform: rotate3d(0,-1,0,90deg);transform: rotate3d(0,-1,0,90deg)}
}
@-webkit-keyframes out-right {
from
{-webkit-transform: rotate3d(0,-1,0,90deg);transform: rotate3d(0,-1,0,90deg)}
to
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
}
@keyframes out-right {
from
{-webkit-transform: rotate3d(0,-1,0,90deg);transform: rotate3d(0,-1,0,90deg)}
to
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
}
@-webkit-keyframes in-bottom {
from
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
to
{-webkit-transform: rotate3d(1,0,0,90deg);transform: rotate3d(1,0,0,90deg)}
}
@keyframes in-bottom {
from
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
to
{-webkit-transform: rotate3d(1,0,0,90deg);transform: rotate3d(1,0,0,90deg)}
}
@-webkit-keyframes out-bottom {
from
{-webkit-transform: rotate3d(1,0,0,90deg);transform: rotate3d(1,0,0,90deg)}
to
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
}
@keyframes out-bottom {
from
{-webkit-transform: rotate3d(1,0,0,90deg);transform: rotate3d(1,0,0,90deg)}
to
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
}
@-webkit-keyframes in-left {
from
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
to
{-webkit-transform: rotate3d(0,1,0,90deg);transform: rotate3d(0,1,0,90deg)}
}
@keyframes in-left {
from
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
to
{-webkit-transform: rotate3d(0,1,0,90deg);transform: rotate3d(0,1,0,90deg)}
}
@-webkit-keyframes out-left {
from
{-webkit-transform: rotate3d(0,1,0,90deg);transform: rotate3d(0,1,0,90deg)}
to
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
}
@keyframes out-left {
from
{-webkit-transform: rotate3d(0,1,0,90deg);transform: rotate3d(0,1,0,90deg)}
to
{-webkit-transform: rotate3d(0,0,0,0deg);transform: rotate3d(0,0,0,0deg)}
} El núcleo JavaScript para activar el efecto.
class DAH {
constructor(nodes) {
this.nodes = [];
Array.prototype.slice.call(nodes, 0).forEach(node => {
this.nodes.push(new Node(node));
});
this._bindEvents();
}
_bindEvents() {
['_resizeHandler'].forEach(fn => this[fn] = this[fn].bind(this));
window.addEventListener('resize', this._resizeHandler, false);
}
_resizeHandler() {
this.nodes.forEach(node => node.update());
}
}
class Node {
constructor(node) {
this.element = node;
this._bindEvents().update();
}
update() {
// const bcr = this.element.getBoundingClientRect();
// this.l = bcr.left;
// this.t = bcr.top;
this.w = this.element.offsetWidth;
this.h = this.element.offsetHeight;
this.l = this.element.offsetLeft;
this.t = this.element.offsetTop;
}
_bindEvents() {
['_mouseEnterHandler', '_mouseOutHandler'].forEach(fn => this[fn] = this[fn].bind(this));
this.element.addEventListener('mouseenter', this._mouseEnterHandler, false);
this.element.addEventListener('mouseout', this._mouseOutHandler, false);
return this;
}
_mouseEnterHandler(ev) {
this._addClass(ev, 'in');
}
_mouseOutHandler(ev) {
this._addClass(ev, 'out');
}
_addClass(ev, state) {
const direction = this._getDirection(ev);
let class_suffix = '';
switch (direction) {
case 0: class_suffix = '-top'; break;
case 1: class_suffix = '-right'; break;
case 2: class_suffix = '-bottom'; break;
case 3: class_suffix = '-left'; break;
}
this.element.className = '';
this.element.classList.add(state + class_suffix);
}
_getDirection(ev) {
const w = this.w,
h = this.h,
x = (ev.pageX - this.l - (w / 2) * (w > h ? (h / w) : 1)),
y = (ev.pageY - this.t - (h / 2) * (h > w ? (w / h) : 1)),
d = Math.round(Math.atan2(y, x) / 1.57079633 + 5) % 4;
return d;
}
}
new DAH(document.querySelectorAll('li'));





