CSSのみでは実装できない、気持ちいい動きのちょっと面白いホバーエフェクト -Attract hover effect
Post on:2017年7月12日
周りがうねうねしたサークル状のアイコン、ホバー時にどんなインタラクションを想像しますか?
カラーが変化したり、裏返しになったり、サイズが大きくなったり、いろいろなエフェクトが考えられると思います。
あまり見たことがない、ホバー時のちょっと面白いインタラクションを紹介します。
上記ページでの操作をアニメーションgifにしてみました。
ホバーすると、サークル状のアイコンが拡大され、マウスに引きつけられるように小気味よくアニメーションします。
このサイトにインスパイアされたデモも紹介します。
See the Pen Attract hover effect by Louis Hoebregts (@Mamboleoo) on CodePen.
HTML
各アイコンはbutton要素で実装されています。
1 2 3 4 5 6 7 8 9 10 11 |
<ul> <li> <button></button> </li> <li> <button></button> </li> <li> <button></button> </li> </ul> |
CSS
CSSは見た目のスタイルのみで、動きはJavaScriptで実装されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
ul { padding: 0; } li { display: inline-block; list-style-type: none; margin: 0 20px; } li:nth-child(1) button { background: #F3FFBD; } li:nth-child(2) button { background: #247BA0; } li:nth-child(3) button { background: #FF1654; } button { position: relative; background: rebeccapurple; width: 200px; height: 200px; border-radius: 50%; border: 5px solid white; color: white; font-family: Verdana; font-weight: bold; font-size: 50px; cursor: pointer; padding: 0; } |
JavaScript
ホバー時の気持ちいい動きは、スクリプトで制御されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
'use strict'; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var HoverButton = function () { function HoverButton(el) { _classCallCheck(this, HoverButton); this.el = el; this.hover = false; this.calculatePosition(); this.attachEventsListener(); } HoverButton.prototype.attachEventsListener = function attachEventsListener() { var _this = this; window.addEventListener('mousemove', function (e) { return _this.onMouseMove(e); }); window.addEventListener('resize', function (e) { return _this.calculatePosition(e); }); }; HoverButton.prototype.calculatePosition = function calculatePosition() { TweenMax.set(this.el, { x: 0, y: 0, scale: 1 }); var box = this.el.getBoundingClientRect(); this.x = box.left + box.width * 0.5; this.y = box.top + box.height * 0.5; this.width = box.width; this.height = box.height; }; HoverButton.prototype.onMouseMove = function onMouseMove(e) { var hover = false; var hoverArea = this.hover ? 0.7 : 0.5; var x = e.clientX - this.x; var y = e.clientY - this.y; var distance = Math.sqrt(x * x + y * y); if (distance < this.width * hoverArea) { hover = true; if (!this.hover) { this.hover = true; } this.onHover(e.clientX, e.clientY); } if (!hover && this.hover) { this.onLeave(); this.hover = false; } }; HoverButton.prototype.onHover = function onHover(x, y) { TweenMax.to(this.el, 0.4, { x: (x - this.x) * 0.4, y: (y - this.y) * 0.4, scale: 1.15, ease: Power2.easeOut }); this.el.style.zIndex = 10; }; HoverButton.prototype.onLeave = function onLeave() { TweenMax.to(this.el, 0.7, { x: 0, y: 0, scale: 1, ease: Elastic.easeOut.config(1.2, 0.4) }); this.el.style.zIndex = 1; }; return HoverButton; }(); var btn1 = document.querySelector('li:nth-child(1) button'); new HoverButton(btn1); var btn2 = document.querySelector('li:nth-child(2) button'); new HoverButton(btn2); var btn3 = document.querySelector('li:nth-child(3) button'); new HoverButton(btn3); |
sponsors