Author: | noeldelgado |
---|---|
Views Total: | 885 views |
Official Page: | Go to website |
Last Update: | February 17, 2017 |
License: | MIT |
Preview:

Description:
A Pure JavaScript & CSS3 solution to apply a direction-aware 3D rotation effect to cubes on hover over.
How to use it:
Add cubes to the webpage as follows:
<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>
The main CSS/CSS3 rules.
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; }
The main CSS3 powered animations:
@-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)} }
The core JavaScript to active the effect.
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'));
I am not able to use a hyperlink with these things.