{"id":1191,"date":"2023-04-06T13:24:01","date_gmt":"2023-04-06T10:24:01","guid":{"rendered":"https:\/\/notes.profidev.online\/?p=1191"},"modified":"2023-04-06T13:24:06","modified_gmt":"2023-04-06T10:24:06","slug":"magnetic-hover-icon","status":"publish","type":"post","link":"https:\/\/notes.profidev.online\/ru\/elements\/1191\/","title":{"rendered":"Magnetic hover icon"},"content":{"rendered":"<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe title=\"Magnetic hover icon\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/IdFO5wBHQpI?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text\/html&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:false,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;HTML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;html&quot;}\">  &lt;main&gt;\n\t\n    &lt;button&gt;\n      &lt;ion-icon name=&quot;logo-facebook&quot;&gt;&lt;\/ion-icon&gt;\n    &lt;\/button&gt;\n    &lt;button&gt;\n      &lt;ion-icon name=&quot;logo-twitter&quot;&gt;&lt;\/ion-icon&gt;\n    &lt;\/button&gt;\n    &lt;button&gt;\n      &lt;ion-icon name=&quot;logo-instagram&quot;&gt;&lt;\/ion-icon&gt;\n    &lt;\/button&gt;\n    &lt;button&gt;\n      &lt;ion-icon name=&quot;logo-youtube&quot;&gt;&lt;\/ion-icon&gt;\n    &lt;\/button&gt;\n    &lt;button&gt;\n      &lt;ion-icon name=&quot;logo-dribbble&quot;&gt;&lt;\/ion-icon&gt;\n    &lt;\/button&gt;\n  \n  &lt;\/main&gt;\n\n  &lt;div class=&quot;cursor cursor--large&quot;&gt;&lt;\/div&gt;\n  &lt;div class=&quot;cursor cursor--small&quot;&gt;&lt;\/div&gt;\n\n  &lt;div class=&quot;support&quot;&gt;\n    &lt;a href=&quot;#&quot; target=&quot;_blank&quot;&gt;&lt;i class=&quot;fab fa-twitter-square&quot;&gt;&lt;\/i&gt;&lt;\/a&gt;\n    &lt;a href=&quot;#&quot; target=&quot;_blank&quot;&gt;&lt;i class=&quot;fab fa-dribbble&quot;&gt;&lt;\/i&gt;&lt;\/a&gt;\n  &lt;\/div&gt;\n\n  &lt;script src=&quot;https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/gsap\/3.1.1\/gsap.min.js&quot;&gt;&lt;\/script&gt;\n  &lt;script src=&quot;https:\/\/unpkg.com\/ionicons@5.0.0\/dist\/ionicons.js&quot;&gt;&lt;\/script&gt;<\/pre><\/div>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;css&quot;,&quot;mime&quot;:&quot;text\/css&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:false,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;CSS&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;css&quot;}\">* {\n  box-sizing: border-box;\n  margin: 0;\n  padding: 0;\n}\n\nbody {\n  width: 100%;\n  height: 100vh;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  overflow: hidden;\n  background: #2c3881;\n  cursor: none;\n}\n\n.cursor {\n  width: var(--size);\n  height: var(--size);\n  border-radius: 50%;\n  position: absolute;\n  left: 0;\n  top: 0;\n  pointer-events: none;\n  z-index: 100;\n}\n.cursor--large {\n  --size: 40px;\n  border: 1px solid #ff3c3c;\n}\n.cursor--small {\n  --size: 10px;\n  background: #ff3c3c;\n  transform: translate(-50%, -50%);\n}\n\nmain {\n  display: flex;\n  flex-wrap: wrap;\n  justify-content: center;\n}\nmain button {\n  --size: 60px;\n  border: none;\n  min-width: var(--size);\n  min-height: var(--size);\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  font-size: 1.2rem;\n  background: rgba(255, 255, 255, 0.08);\n  color: #fff;\n  transition: background 200ms ease, color 200ms ease;\n  cursor: none;\n}\nmain:hover button {\n  background: rgba(255, 255, 255, 0.04);\n  color: rgba(255, 255, 255, 0.04);\n}\nmain:hover button:hover {\n  color: #fff;\n}\n\n.support {\n  position: absolute;\n  right: 10px;\n  bottom: 10px;\n  padding: 10px;\n  display: flex;\n}\n.support a {\n  margin: 0 10px;\n  color: #fff;\n  font-size: 1.8rem;\n  backface-visibility: hidden;\n  transition: all 150ms ease;\n}\n.support a:hover {\n  transform: scale(1.1);\n}<\/pre><\/div>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;text\/javascript&quot;,&quot;theme&quot;:&quot;cobalt&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:false,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;JavaScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;js&quot;}\">console.clear();\n\nconst { gsap } = window;\n\nconst cursorOuter = document.querySelector(&quot;.cursor--large&quot;);\nconst cursorInner = document.querySelector(&quot;.cursor--small&quot;);\nlet isStuck = false;\nlet mouse = {\n\tx: -100,\n\ty: -100,\n};\n\n\/\/ Just in case you need to scroll\nlet scrollHeight = 0;\nwindow.addEventListener('scroll', function(e) {\n\tscrollHeight = window.scrollY\n})\n\nlet cursorOuterOriginalState = {\n\twidth: cursorOuter.getBoundingClientRect().width,\n\theight: cursorOuter.getBoundingClientRect().height,\n};\nconst buttons = document.querySelectorAll(&quot;main button&quot;);\n\nbuttons.forEach((button) =&gt; {\n\tbutton.addEventListener(&quot;pointerenter&quot;, handleMouseEnter);\n\tbutton.addEventListener(&quot;pointerleave&quot;, handleMouseLeave);\n});\n\ndocument.body.addEventListener(&quot;pointermove&quot;, updateCursorPosition);\ndocument.body.addEventListener(&quot;pointerdown&quot;, () =&gt; {\n\tgsap.to(cursorInner, 0.15, {\n\t\tscale: 2,\n\t});\n});\ndocument.body.addEventListener(&quot;pointerup&quot;, () =&gt; {\n\tgsap.to(cursorInner, 0.15, {\n\t\tscale: 1,\n\t});\n});\n\nfunction updateCursorPosition(e) {\n\tmouse.x = e.pageX;\n\tmouse.y = e.pageY;\n}\n\nfunction updateCursor() {\n\tgsap.set(cursorInner, {\n\t\tx: mouse.x,\n\t\ty: mouse.y,\n\t});\n\n\tif (!isStuck) {\n\t\tgsap.to(cursorOuter, {\n\t\t\tduration: 0.15,\n\t\t\tx: mouse.x - cursorOuterOriginalState.width\/2,\n\t\t\ty: mouse.y - cursorOuterOriginalState.height\/2,\n\t\t});\n\t}\n\n\trequestAnimationFrame(updateCursor);\n}\n\nupdateCursor();\n\nfunction handleMouseEnter(e) {\n\tisStuck = true;\n\tconst targetBox = e.currentTarget.getBoundingClientRect();\n\tgsap.to(cursorOuter, 0.2, {\n\t\tx: targetBox.left, \n\t\ty: targetBox.top + scrollHeight,\n\t\twidth: targetBox.width,\n\t\theight: targetBox.width,\n\t\tborderRadius: 0,\n\t\tbackgroundColor: &quot;rgba(255, 255, 255, 0.1)&quot;,\n\t});\n}\n\nfunction handleMouseLeave(e) {\n\tisStuck = false;\n\tgsap.to(cursorOuter, 0.2, {\n\t\twidth: cursorOuterOriginalState.width,\n\t\theight: cursorOuterOriginalState.width,\n\t\tborderRadius: &quot;50%&quot;,\n\t\tbackgroundColor: &quot;transparent&quot;,\n\t});\n}\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":1192,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19],"tags":[27,33],"class_list":["post-1191","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-elements","tag-gsap","tag-icons"],"_links":{"self":[{"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/posts\/1191","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/comments?post=1191"}],"version-history":[{"count":1,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/posts\/1191\/revisions"}],"predecessor-version":[{"id":1193,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/posts\/1191\/revisions\/1193"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/media\/1192"}],"wp:attachment":[{"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/media?parent=1191"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/categories?post=1191"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/notes.profidev.online\/ru\/wp-json\/wp\/v2\/tags?post=1191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}