Created
May 10, 2017 20:25
-
-
Save antenando/a239e7ed6cbd2565d240b0673c4ccd53 to your computer and use it in GitHub Desktop.
JS Bin // source http://jsbin.com/jinewul
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>JS Bin</title> | |
<style id="jsbin-css"> | |
html { | |
cursor: none; | |
} | |
.cursor { | |
will-change: transform; | |
transition: transform 0.1s linear; | |
transform: | |
translate3d( | |
calc(var(--posX) - 15px), | |
calc(var(--posY) - 20px), 0) | |
rotate(calc(90deg + var(--rotate, 90deg))); | |
background-size: cover; | |
width: 30px; | |
height: 40px; | |
background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+PHN2ZyB3aWR0aD0iNTk1LjI3NSIgaGVpZ2h0PSI4NDEuODkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiA8Zz4KICA8dGl0bGU+TGF5ZXIgMTwvdGl0bGU+CiAgPGcgaWQ9InN2Z18xIj4KICAgPHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z18yIiBwb2ludHM9IjEyMS4zNCA0MjcuODkgMTYwLjIgNDI3Ljg5IDE2MC4yIDQ2NS41MTUgMTk5LjA2IDQ2NS41MTUgMTk5LjA2IDE1NS4xMTkgMjM3LjY3OSAxNTUuMTE5IDIzNy43MzUgMTU1LjExOSAyNzYuNTQgMTU1LjExOSAyNzYuNTQgMjcxLjkyNSAyNzYuNTQgMzEwLjc0MSAyNzYuNTQgMzEwLjk5MyAyNzYuNTQgMzQ5LjgxIDI3Ni41NCAzODguODgyIDMxNS40IDM4OC44ODIgMzE1LjQgMzQ5LjgxIDMxNS40IDMxMC45OTMgMzE1LjQgMzEwLjg2NyAzOTIuOTQgMzEwLjg2NyAzOTIuOTQgMzQ5Ljg3NSAzOTIuOTQgMzQ5Ljk0IDM5Mi45NCAzODguOTQ3IDQzMS44IDM4OC45NDcgNDMxLjggMzQ5Ljk0IDQzMS44IDM0OS44NzUgNDMxLjggMzEwLjg2NyA0NjkuOTQ1IDMxMC44NjcgNDY5Ljk0NSAyNzEuNzk1IDMxNS40IDI3MS43OTUgMzE1LjQgMTU0LjgzNyAyNzYuNTQgMTU0LjgzNyAyNzYuNTQgMTE2LjA1MSAyMzcuNzM1IDExNi4wNTEgMjM3LjY3OSAxMTYuMDUxIDE5OC44NzUgMTE2LjA1MSAxOTguODc1IDE1NC44MzcgMTYwLjIgMTU0LjgzNyAxNjAuMiAzODguODE3IDEyMS40NiAzODguODE3IDEyMS40NiAzNDkuODc1IDQ0LjUyIDM0OS44NzUgNDQuNTIgMzg4Ljk0NyAxMjEuMzQgMzg4Ljk0NyIvPgogICA8cG9seWdvbiBmaWxsPSIjMDAwMDAwIiBpZD0ic3ZnXzMiIHBvaW50cz0iNTA5LjM0IDU4My44NTUgNTA5LjM0IDU4My45MiA1MDkuMzQgNjIyLjkyOCA0NzAuNiA2MjIuOTI4IDQ3MC42IDU4My44NTUgNDcwLjYgNTQ1LjAzOCA0NzAuNiA1NDQuNzg2IDQ3MC42IDUwNS45NyA0NzAuNiA0NjYuODk4IDQzMS43NCA0NjYuODk4IDQzMS43NCA1MDUuOTcgNDMxLjc0IDU0NC43ODYgNDMxLjc0IDU0NS4wMzggNDMxLjc0IDU4My44NTUgNDMxLjc0IDYyMi45MjggNDcwLjU0IDYyMi45MjggNDcwLjU0IDY2MS45MzUgNDcwLjU0IDY2MiA0NzAuNTQgNzAwLjk0MyA0MzEuOCA3MDAuOTQzIDQzMS44IDc0MC4wMTUgNDcwLjU0IDc0MC4wMTUgNDcwLjY2IDc0MC4wMTUgNTA5LjQgNzQwLjAxNSA1MDkuNCA3MDEuMDA4IDUwOS40IDcwMC45NDMgNTA5LjQgNjYyIDUwOS40IDY2MS45MzUgNTA5LjQgNjIyLjkyOCA1NDguMiA2MjIuOTI4IDU0OC4yIDU4My45MiA1NDguMiA1ODMuODU1IDU0OC4yIDU0NC44NDcgNTA5LjM0IDU0NC44NDciLz4KICAgPHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z180IiBwb2ludHM9IjU0OC4yIDM0OS44MSA1NDguMiAzMTAuODY3IDUwOS40IDMxMC44NjcgNTA5LjM0IDMxMC44NjcgNDcwLjU0IDMxMC44NjcgNDcwLjU0IDM0OS44NzUgNDcwLjU0IDM0OS45NCA0NzAuNTQgMzg4Ljk0NyA1MDkuNCAzODguOTQ3IDUwOS40IDM0OS45NCA1NDguMTQgMzQ5Ljk0IDU0OC4xNCA1NDQuMTg5IDU4NyA1NDQuMTg5IDU4NyAzNDkuODEiLz4KICAgPHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z181IiBwb2ludHM9IjgyLjYzMDIgNTA1Ljg3NSA4Mi42MzAyIDQ2Ni44MDcgNDMuODYwNCA0NjYuODA3IDQzLjg2MDQgNDI3Ljg5IDQzLjg2MDQgMzg4LjgxNyA1LjAwMDAyIDM4OC44MTcgNS4wMDAwMiA0MjcuODkgNS4wMDAwMiA0NjYuOTYzIDQzLjc2OTggNDY2Ljk2MyA0My43Njk4IDUwNS44NzUiLz4KICAgPHJlY3QgZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z182IiBoZWlnaHQ9IjM5LjA3MjUxMiIgd2lkdGg9IjM4Ljg2MDM1MyIgeT0iNjYxLjg2OTk1OSIgeD0iMzkyLjkzOTYzOCIvPgogICA8cG9seWdvbiBmaWxsPSIjMDAwMDAwIiBpZD0ic3ZnXzciIHBvaW50cz0iMjc2LjU0IDUwNS45NyAyNzYuNTQgNTQ0Ljc4NiAyNzYuNTQgNTQ1LjAzOCAyNzYuNTQgNTgzLjg1NSAyNzYuNTQgNjIyLjkyOCAzMTUuNCA2MjIuOTI4IDMxNS40IDU4My44NTUgMzE1LjQgNTQ1LjAzOCAzMTUuNCA1NDQuNzg2IDMxNS40IDUwNS45NyAzMTUuNCA0NjYuODk4IDI3Ni41NCA0NjYuODk4Ii8+CiAgIDxwb2x5Z29uIGZpbGw9IiMwMDAwMDAiIGlkPSJzdmdfOCIgcG9pbnRzPSIzNTQuMTQgNTA1Ljk3IDM1NC4xNCA1NDQuNzg2IDM1NC4xNCA1NDUuMDM4IDM1NC4xNCA1ODMuODU1IDM1NC4xNCA2MjIuOTI4IDM5MyA2MjIuOTI4IDM5MyA1ODMuODU1IDM5MyA1NDUuMDM4IDM5MyA1NDQuNzg2IDM5MyA1MDUuOTcgMzkzIDQ2Ni44OTggMzU0LjE0IDQ2Ni44OTgiLz4KICAgPHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z185IiBwb2ludHM9IjIzNy44IDcwMC44NzggMjM3LjggNjYxLjgwOSAxOTkgNjYxLjgwOSAxOTkgNjIyLjkyOCAxNjAuMiA2MjIuOTI4IDE2MC4yIDU4My45MiAxMjEuNDYgNTgzLjkyIDEyMS40NiA1NDQuOTc3IDEyMS40NiA1MDUuOTA1IDgyLjYgNTA1LjkwNSA4Mi42IDU0NC45NzcgODIuNiA1ODQuMDQ2IDEyMS4zNCA1ODQuMDQ2IDEyMS4zNCA2MjIuOTkyIDE2MC4xNCA2MjIuOTkyIDE2MC4xNCA2NjIgMTk4Ljk0IDY2MiAxOTguOTQgNzAwLjg3OCAxOTguOTQgNzM5Ljk1IDIzNy44IDczOS45NSAyMzcuOCA3NDAuMDE1IDM5Mi4zNDUgNzQwLjAxNSAzOTIuMzQ1IDcwMC45NDMgMjM3LjggNzAwLjk0MyIvPgogIDwvZz4KIDwvZz4KPC9zdmc+"); | |
} | |
</style> | |
</head> | |
<body> | |
<div class="cursor"></div> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.0/Rx.min.js"></script> | |
</div> | |
<script id="jsbin-javascript"> | |
class V { | |
constructor({clientX: clientX = 0, clientY: clientY = 0} = {}) { | |
this.x = clientX; | |
this.y = clientY; | |
} | |
magnitude() { | |
return Math.sqrt(this.x*this.x + this.y*this.y); | |
} | |
normalize() { | |
const mag = this.magnitude(); | |
return new V({ | |
clientX: this.x / mag, | |
clientY: this.y / mag | |
}); | |
} | |
subtract(v) { | |
return new V({ | |
clientX: this.x - v.x, | |
clientY: this.y - v.y | |
}); | |
} | |
degree() { | |
const norm = this.normalize(); | |
return Math.round(Math.atan2(norm.y, norm.x) * 180 / Math.PI); | |
} | |
} | |
const cursor = document.querySelector('.cursor'); | |
Rx.Observable | |
.fromEvent(window, 'mousemove') | |
.throttleTime(30) | |
.map((event) => new V(event)) | |
.do((position) => { | |
cursor.style.setProperty('--posX', `${position.x}px`); | |
cursor.style.setProperty('--posY', `${position.y}px`); | |
}) | |
.bufferCount(2) | |
.map(([previous, current]) => current.subtract(previous).normalize()) | |
.filter((direction) => direction.magnitude()) | |
.map((direction) => direction.degree()) | |
.subscribe((degree) => cursor.style.setProperty('--rotate', `${degree}deg`)); | |
</script> | |
<script id="jsbin-source-css" type="text/css">html { | |
cursor: none; | |
} | |
.cursor { | |
will-change: transform; | |
transition: transform 0.1s linear; | |
transform: | |
translate3d( | |
calc(var(--posX) - 15px), | |
calc(var(--posY) - 20px), 0) | |
rotate(calc(90deg + var(--rotate, 90deg))); | |
background-size: cover; | |
width: 30px; | |
height: 40px; | |
background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+PHN2ZyB3aWR0aD0iNTk1LjI3NSIgaGVpZ2h0PSI4NDEuODkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiA8Zz4KICA8dGl0bGU+TGF5ZXIgMTwvdGl0bGU+CiAgPGcgaWQ9InN2Z18xIj4KICAgPHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z18yIiBwb2ludHM9IjEyMS4zNCA0MjcuODkgMTYwLjIgNDI3Ljg5IDE2MC4yIDQ2NS41MTUgMTk5LjA2IDQ2NS41MTUgMTk5LjA2IDE1NS4xMTkgMjM3LjY3OSAxNTUuMTE5IDIzNy43MzUgMTU1LjExOSAyNzYuNTQgMTU1LjExOSAyNzYuNTQgMjcxLjkyNSAyNzYuNTQgMzEwLjc0MSAyNzYuNTQgMzEwLjk5MyAyNzYuNTQgMzQ5LjgxIDI3Ni41NCAzODguODgyIDMxNS40IDM4OC44ODIgMzE1LjQgMzQ5LjgxIDMxNS40IDMxMC45OTMgMzE1LjQgMzEwLjg2NyAzOTIuOTQgMzEwLjg2NyAzOTIuOTQgMzQ5Ljg3NSAzOTIuOTQgMzQ5Ljk0IDM5Mi45NCAzODguOTQ3IDQzMS44IDM4OC45NDcgNDMxLjggMzQ5Ljk0IDQzMS44IDM0OS44NzUgNDMxLjggMzEwLjg2NyA0NjkuOTQ1IDMxMC44NjcgNDY5Ljk0NSAyNzEuNzk1IDMxNS40IDI3MS43OTUgMzE1LjQgMTU0LjgzNyAyNzYuNTQgMTU0LjgzNyAyNzYuNTQgMTE2LjA1MSAyMzcuNzM1IDExNi4wNTEgMjM3LjY3OSAxMTYuMDUxIDE5OC44NzUgMTE2LjA1MSAxOTguODc1IDE1NC44MzcgMTYwLjIgMTU0LjgzNyAxNjAuMiAzODguODE3IDEyMS40NiAzODguODE3IDEyMS40NiAzNDkuODc1IDQ0LjUyIDM0OS44NzUgNDQuNTIgMzg4Ljk0NyAxMjEuMzQgMzg4Ljk0NyIvPgogICA8cG9seWdvbiBmaWxsPSIjMDAwMDAwIiBpZD0ic3ZnXzMiIHBvaW50cz0iNTA5LjM0IDU4My44NTUgNTA5LjM0IDU4My45MiA1MDkuMzQgNjIyLjkyOCA0NzAuNiA2MjIuOTI4IDQ3MC42IDU4My44NTUgNDcwLjYgNTQ1LjAzOCA0NzAuNiA1NDQuNzg2IDQ3MC42IDUwNS45NyA0NzAuNiA0NjYuODk4IDQzMS43NCA0NjYuODk4IDQzMS43NCA1MDUuOTcgNDMxLjc0IDU0NC43ODYgNDMxLjc0IDU0NS4wMzggNDMxLjc0IDU4My44NTUgNDMxLjc0IDYyMi45MjggNDcwLjU0IDYyMi45MjggNDcwLjU0IDY2MS45MzUgNDcwLjU0IDY2MiA0NzAuNTQgNzAwLjk0MyA0MzEuOCA3MDAuOTQzIDQzMS44IDc0MC4wMTUgNDcwLjU0IDc0MC4wMTUgNDcwLjY2IDc0MC4wMTUgNTA5LjQgNzQwLjAxNSA1MDkuNCA3MDEuMDA4IDUwOS40IDcwMC45NDMgNTA5LjQgNjYyIDUwOS40IDY2MS45MzUgNTA5LjQgNjIyLjkyOCA1NDguMiA2MjIuOTI4IDU0OC4yIDU4My45MiA1NDguMiA1ODMuODU1IDU0OC4yIDU0NC44NDcgNTA5LjM0IDU0NC44NDciLz4KICAgPHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z180IiBwb2ludHM9IjU0OC4yIDM0OS44MSA1NDguMiAzMTAuODY3IDUwOS40IDMxMC44NjcgNTA5LjM0IDMxMC44NjcgNDcwLjU0IDMxMC44NjcgNDcwLjU0IDM0OS44NzUgNDcwLjU0IDM0OS45NCA0NzAuNTQgMzg4Ljk0NyA1MDkuNCAzODguOTQ3IDUwOS40IDM0OS45NCA1NDguMTQgMzQ5Ljk0IDU0OC4xNCA1NDQuMTg5IDU4NyA1NDQuMTg5IDU4NyAzNDkuODEiLz4KICAgPHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z181IiBwb2ludHM9IjgyLjYzMDIgNTA1Ljg3NSA4Mi42MzAyIDQ2Ni44MDcgNDMuODYwNCA0NjYuODA3IDQzLjg2MDQgNDI3Ljg5IDQzLjg2MDQgMzg4LjgxNyA1LjAwMDAyIDM4OC44MTcgNS4wMDAwMiA0MjcuODkgNS4wMDAwMiA0NjYuOTYzIDQzLjc2OTggNDY2Ljk2MyA0My43Njk4IDUwNS44NzUiLz4KICAgPHJlY3QgZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z182IiBoZWlnaHQ9IjM5LjA3MjUxMiIgd2lkdGg9IjM4Ljg2MDM1MyIgeT0iNjYxLjg2OTk1OSIgeD0iMzkyLjkzOTYzOCIvPgogICA8cG9seWdvbiBmaWxsPSIjMDAwMDAwIiBpZD0ic3ZnXzciIHBvaW50cz0iMjc2LjU0IDUwNS45NyAyNzYuNTQgNTQ0Ljc4NiAyNzYuNTQgNTQ1LjAzOCAyNzYuNTQgNTgzLjg1NSAyNzYuNTQgNjIyLjkyOCAzMTUuNCA2MjIuOTI4IDMxNS40IDU4My44NTUgMzE1LjQgNTQ1LjAzOCAzMTUuNCA1NDQuNzg2IDMxNS40IDUwNS45NyAzMTUuNCA0NjYuODk4IDI3Ni41NCA0NjYuODk4Ii8+CiAgIDxwb2x5Z29uIGZpbGw9IiMwMDAwMDAiIGlkPSJzdmdfOCIgcG9pbnRzPSIzNTQuMTQgNTA1Ljk3IDM1NC4xNCA1NDQuNzg2IDM1NC4xNCA1NDUuMDM4IDM1NC4xNCA1ODMuODU1IDM1NC4xNCA2MjIuOTI4IDM5MyA2MjIuOTI4IDM5MyA1ODMuODU1IDM5MyA1NDUuMDM4IDM5MyA1NDQuNzg2IDM5MyA1MDUuOTcgMzkzIDQ2Ni44OTggMzU0LjE0IDQ2Ni44OTgiLz4KICAgPHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z185IiBwb2ludHM9IjIzNy44IDcwMC44NzggMjM3LjggNjYxLjgwOSAxOTkgNjYxLjgwOSAxOTkgNjIyLjkyOCAxNjAuMiA2MjIuOTI4IDE2MC4yIDU4My45MiAxMjEuNDYgNTgzLjkyIDEyMS40NiA1NDQuOTc3IDEyMS40NiA1MDUuOTA1IDgyLjYgNTA1LjkwNSA4Mi42IDU0NC45NzcgODIuNiA1ODQuMDQ2IDEyMS4zNCA1ODQuMDQ2IDEyMS4zNCA2MjIuOTkyIDE2MC4xNCA2MjIuOTkyIDE2MC4xNCA2NjIgMTk4Ljk0IDY2MiAxOTguOTQgNzAwLjg3OCAxOTguOTQgNzM5Ljk1IDIzNy44IDczOS45NSAyMzcuOCA3NDAuMDE1IDM5Mi4zNDUgNzQwLjAxNSAzOTIuMzQ1IDcwMC45NDMgMjM3LjggNzAwLjk0MyIvPgogIDwvZz4KIDwvZz4KPC9zdmc+"); | |
}</script> | |
<script id="jsbin-source-javascript" type="text/javascript">class V { | |
constructor({clientX: clientX = 0, clientY: clientY = 0} = {}) { | |
this.x = clientX; | |
this.y = clientY; | |
} | |
magnitude() { | |
return Math.sqrt(this.x*this.x + this.y*this.y); | |
} | |
normalize() { | |
const mag = this.magnitude(); | |
return new V({ | |
clientX: this.x / mag, | |
clientY: this.y / mag | |
}); | |
} | |
subtract(v) { | |
return new V({ | |
clientX: this.x - v.x, | |
clientY: this.y - v.y | |
}); | |
} | |
degree() { | |
const norm = this.normalize(); | |
return Math.round(Math.atan2(norm.y, norm.x) * 180 / Math.PI); | |
} | |
} | |
const cursor = document.querySelector('.cursor'); | |
Rx.Observable | |
.fromEvent(window, 'mousemove') | |
.throttleTime(30) | |
.map((event) => new V(event)) | |
.do((position) => { | |
cursor.style.setProperty('--posX', `${position.x}px`); | |
cursor.style.setProperty('--posY', `${position.y}px`); | |
}) | |
.bufferCount(2) | |
.map(([previous, current]) => current.subtract(previous).normalize()) | |
.filter((direction) => direction.magnitude()) | |
.map((direction) => direction.degree()) | |
.subscribe((degree) => cursor.style.setProperty('--rotate', `${degree}deg`));</script></body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html { | |
cursor: none; | |
} | |
.cursor { | |
will-change: transform; | |
transition: transform 0.1s linear; | |
transform: | |
translate3d( | |
calc(var(--posX) - 15px), | |
calc(var(--posY) - 20px), 0) | |
rotate(calc(90deg + var(--rotate, 90deg))); | |
background-size: cover; | |
width: 30px; | |
height: 40px; | |
background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+PHN2ZyB3aWR0aD0iNTk1LjI3NSIgaGVpZ2h0PSI4NDEuODkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiA8Zz4KICA8dGl0bGU+TGF5ZXIgMTwvdGl0bGU+CiAgPGcgaWQ9InN2Z18xIj4KICAgPHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z18yIiBwb2ludHM9IjEyMS4zNCA0MjcuODkgMTYwLjIgNDI3Ljg5IDE2MC4yIDQ2NS41MTUgMTk5LjA2IDQ2NS41MTUgMTk5LjA2IDE1NS4xMTkgMjM3LjY3OSAxNTUuMTE5IDIzNy43MzUgMTU1LjExOSAyNzYuNTQgMTU1LjExOSAyNzYuNTQgMjcxLjkyNSAyNzYuNTQgMzEwLjc0MSAyNzYuNTQgMzEwLjk5MyAyNzYuNTQgMzQ5LjgxIDI3Ni41NCAzODguODgyIDMxNS40IDM4OC44ODIgMzE1LjQgMzQ5LjgxIDMxNS40IDMxMC45OTMgMzE1LjQgMzEwLjg2NyAzOTIuOTQgMzEwLjg2NyAzOTIuOTQgMzQ5Ljg3NSAzOTIuOTQgMzQ5Ljk0IDM5Mi45NCAzODguOTQ3IDQzMS44IDM4OC45NDcgNDMxLjggMzQ5Ljk0IDQzMS44IDM0OS44NzUgNDMxLjggMzEwLjg2NyA0NjkuOTQ1IDMxMC44NjcgNDY5Ljk0NSAyNzEuNzk1IDMxNS40IDI3MS43OTUgMzE1LjQgMTU0LjgzNyAyNzYuNTQgMTU0LjgzNyAyNzYuNTQgMTE2LjA1MSAyMzcuNzM1IDExNi4wNTEgMjM3LjY3OSAxMTYuMDUxIDE5OC44NzUgMTE2LjA1MSAxOTguODc1IDE1NC44MzcgMTYwLjIgMTU0LjgzNyAxNjAuMiAzODguODE3IDEyMS40NiAzODguODE3IDEyMS40NiAzNDkuODc1IDQ0LjUyIDM0OS44NzUgNDQuNTIgMzg4Ljk0NyAxMjEuMzQgMzg4Ljk0NyIvPgogICA8cG9seWdvbiBmaWxsPSIjMDAwMDAwIiBpZD0ic3ZnXzMiIHBvaW50cz0iNTA5LjM0IDU4My44NTUgNTA5LjM0IDU4My45MiA1MDkuMzQgNjIyLjkyOCA0NzAuNiA2MjIuOTI4IDQ3MC42IDU4My44NTUgNDcwLjYgNTQ1LjAzOCA0NzAuNiA1NDQuNzg2IDQ3MC42IDUwNS45NyA0NzAuNiA0NjYuODk4IDQzMS43NCA0NjYuODk4IDQzMS43NCA1MDUuOTcgNDMxLjc0IDU0NC43ODYgNDMxLjc0IDU0NS4wMzggNDMxLjc0IDU4My44NTUgNDMxLjc0IDYyMi45MjggNDcwLjU0IDYyMi45MjggNDcwLjU0IDY2MS45MzUgNDcwLjU0IDY2MiA0NzAuNTQgNzAwLjk0MyA0MzEuOCA3MDAuOTQzIDQzMS44IDc0MC4wMTUgNDcwLjU0IDc0MC4wMTUgNDcwLjY2IDc0MC4wMTUgNTA5LjQgNzQwLjAxNSA1MDkuNCA3MDEuMDA4IDUwOS40IDcwMC45NDMgNTA5LjQgNjYyIDUwOS40IDY2MS45MzUgNTA5LjQgNjIyLjkyOCA1NDguMiA2MjIuOTI4IDU0OC4yIDU4My45MiA1NDguMiA1ODMuODU1IDU0OC4yIDU0NC44NDcgNTA5LjM0IDU0NC44NDciLz4KICAgPHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z180IiBwb2ludHM9IjU0OC4yIDM0OS44MSA1NDguMiAzMTAuODY3IDUwOS40IDMxMC44NjcgNTA5LjM0IDMxMC44NjcgNDcwLjU0IDMxMC44NjcgNDcwLjU0IDM0OS44NzUgNDcwLjU0IDM0OS45NCA0NzAuNTQgMzg4Ljk0NyA1MDkuNCAzODguOTQ3IDUwOS40IDM0OS45NCA1NDguMTQgMzQ5Ljk0IDU0OC4xNCA1NDQuMTg5IDU4NyA1NDQuMTg5IDU4NyAzNDkuODEiLz4KICAgPHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z181IiBwb2ludHM9IjgyLjYzMDIgNTA1Ljg3NSA4Mi42MzAyIDQ2Ni44MDcgNDMuODYwNCA0NjYuODA3IDQzLjg2MDQgNDI3Ljg5IDQzLjg2MDQgMzg4LjgxNyA1LjAwMDAyIDM4OC44MTcgNS4wMDAwMiA0MjcuODkgNS4wMDAwMiA0NjYuOTYzIDQzLjc2OTggNDY2Ljk2MyA0My43Njk4IDUwNS44NzUiLz4KICAgPHJlY3QgZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z182IiBoZWlnaHQ9IjM5LjA3MjUxMiIgd2lkdGg9IjM4Ljg2MDM1MyIgeT0iNjYxLjg2OTk1OSIgeD0iMzkyLjkzOTYzOCIvPgogICA8cG9seWdvbiBmaWxsPSIjMDAwMDAwIiBpZD0ic3ZnXzciIHBvaW50cz0iMjc2LjU0IDUwNS45NyAyNzYuNTQgNTQ0Ljc4NiAyNzYuNTQgNTQ1LjAzOCAyNzYuNTQgNTgzLjg1NSAyNzYuNTQgNjIyLjkyOCAzMTUuNCA2MjIuOTI4IDMxNS40IDU4My44NTUgMzE1LjQgNTQ1LjAzOCAzMTUuNCA1NDQuNzg2IDMxNS40IDUwNS45NyAzMTUuNCA0NjYuODk4IDI3Ni41NCA0NjYuODk4Ii8+CiAgIDxwb2x5Z29uIGZpbGw9IiMwMDAwMDAiIGlkPSJzdmdfOCIgcG9pbnRzPSIzNTQuMTQgNTA1Ljk3IDM1NC4xNCA1NDQuNzg2IDM1NC4xNCA1NDUuMDM4IDM1NC4xNCA1ODMuODU1IDM1NC4xNCA2MjIuOTI4IDM5MyA2MjIuOTI4IDM5MyA1ODMuODU1IDM5MyA1NDUuMDM4IDM5MyA1NDQuNzg2IDM5MyA1MDUuOTcgMzkzIDQ2Ni44OTggMzU0LjE0IDQ2Ni44OTgiLz4KICAgPHBvbHlnb24gZmlsbD0iIzAwMDAwMCIgaWQ9InN2Z185IiBwb2ludHM9IjIzNy44IDcwMC44NzggMjM3LjggNjYxLjgwOSAxOTkgNjYxLjgwOSAxOTkgNjIyLjkyOCAxNjAuMiA2MjIuOTI4IDE2MC4yIDU4My45MiAxMjEuNDYgNTgzLjkyIDEyMS40NiA1NDQuOTc3IDEyMS40NiA1MDUuOTA1IDgyLjYgNTA1LjkwNSA4Mi42IDU0NC45NzcgODIuNiA1ODQuMDQ2IDEyMS4zNCA1ODQuMDQ2IDEyMS4zNCA2MjIuOTkyIDE2MC4xNCA2MjIuOTkyIDE2MC4xNCA2NjIgMTk4Ljk0IDY2MiAxOTguOTQgNzAwLjg3OCAxOTguOTQgNzM5Ljk1IDIzNy44IDczOS45NSAyMzcuOCA3NDAuMDE1IDM5Mi4zNDUgNzQwLjAxNSAzOTIuMzQ1IDcwMC45NDMgMjM3LjggNzAwLjk0MyIvPgogIDwvZz4KIDwvZz4KPC9zdmc+"); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class V { | |
constructor({clientX: clientX = 0, clientY: clientY = 0} = {}) { | |
this.x = clientX; | |
this.y = clientY; | |
} | |
magnitude() { | |
return Math.sqrt(this.x*this.x + this.y*this.y); | |
} | |
normalize() { | |
const mag = this.magnitude(); | |
return new V({ | |
clientX: this.x / mag, | |
clientY: this.y / mag | |
}); | |
} | |
subtract(v) { | |
return new V({ | |
clientX: this.x - v.x, | |
clientY: this.y - v.y | |
}); | |
} | |
degree() { | |
const norm = this.normalize(); | |
return Math.round(Math.atan2(norm.y, norm.x) * 180 / Math.PI); | |
} | |
} | |
const cursor = document.querySelector('.cursor'); | |
Rx.Observable | |
.fromEvent(window, 'mousemove') | |
.throttleTime(30) | |
.map((event) => new V(event)) | |
.do((position) => { | |
cursor.style.setProperty('--posX', `${position.x}px`); | |
cursor.style.setProperty('--posY', `${position.y}px`); | |
}) | |
.bufferCount(2) | |
.map(([previous, current]) => current.subtract(previous).normalize()) | |
.filter((direction) => direction.magnitude()) | |
.map((direction) => direction.degree()) | |
.subscribe((degree) => cursor.style.setProperty('--rotate', `${degree}deg`)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment