main.main
header
h1
strong Mutant
| Cursor
p SVG + JS + MicroInteractions
svg#svg-cursor.svg-cursor(width='1em' height='1em')
g.svg-cursor__lines(stroke-width='2px' stroke='black')
line(x1='0' y1='.5em' x2='1em' y2='.5em')
line(x1='0' y1='.5em' x2='1em' y2='.5em')
line(x1='0' y1='.5em' x2='1em' y2='.5em')
ul.actions
li.actions__item
a.custom-cursor.custom-cursor--action(href='javascript:void(0)' title='Fire action cursor') Action cursor
li.actions__item
a.custom-cursor.custom-cursor--close(href='javascript:void(0)' title='Fire close cursor') Close cursor
li.actions__item
a.custom-cursor.custom-cursor--action(href='#modal' title='Help') Help
article#modal.modal
.modal__content
header.modal__header
h2 How the hell it works?
p.space It's simple, jus drop this JavaScript in your HTML:
ul.code.space
li.code__line document.body.addEventListener("mousemove", function(event) {
li.code__line.code__push1 moveCursor(event);
li.code__line.space });
li.code__line.space var svgCursor = document.getElementById('svg-cursor');
li.code__line function moveCursor(e) {
li.code__line.code__push1 var x = e.clientX - 5,
li.code__line.code__push3.space y = e.clientY - 5;
li.code__line.code__push1.space svgCursor.setAttribute('style', 'left: ' + x + 'px; top: ' + y + 'px');
li.code__line.code__push1 if (e.target.className.indexOf('custom-cursor') > -1) {
li.code__line.code__push3 switch (e.target.className) {
li.code__line.code__push5 case 'custom-cursor custom-cursor--action':
li.code__line.code__push8 svgCursor.setAttribute('class', 'svg-cursor svg-cursor__action')
li.code__line.code__push8 break;
li.code__line.code__push5 case 'custom-cursor custom-cursor--close':
li.code__line.code__push8 svgCursor.setAttribute('class', 'svg-cursor svg-cursor__close')
li.code__line.code__push8 break;
li.code__line.code__push3 }
li.code__line.code__push1 } else {
li.code__line.code__push3 svgCursor.setAttribute('class', 'svg-cursor');
li.code__line.code__push1 }
li.code__line }
p.space Now add these classes to some DOM elements and check it out!
ul.code.space
li.code__line custom-cursor custom-cursor--hover
li.code__line.code__comment // or
li.code__line custom-cursor custom-cursor--close
p Remember...
strong IE Sucks!
.modal__close
a.custom-cursor.custom-cursor--close(href='#' title='Close modal')
svg(width='2em' height='2em')
circle(cx='1em' cy='1em' r='.8em' fill='#ff6a6a')
.modal__background
View Compiled
@charset 'utf-8';
@import 'compass/reset';
@import 'https://fonts.googleapis.com/css?family=Open+Sans:300,700';
@import 'https://fonts.googleapis.com/css?family=Bitter:400,700';
@import 'https://fonts.googleapis.com/css?family=Anonymous+Pro:400';
$yellow: #f1c40f;
$lime: #76c900;
$navy: #0a4069;
$cyan: #57caf4;
$red: #ec008c;
$white: #fefefe;
$gray: #444;
$lightGray: lighten($gray, 30);
$fastDuration: .3s;
$normalDuration: .6s;
$slowDuration: 1s;
$bezier: cubic-bezier(0.76, -0.53, 0.32, 1.4);
html,
body,
main {
height: 100%;
width: 100%;
box-sizing: border-box;
}
h1
{
font-size: 2.5em;
margin: 2em 0 .5em;
font-family: 'Bitter', serif;
font-weight: 400;
}
em,
strong
{
font-weight: 700;
}
.main {
display: flex;
align-items: center;
justify-content: flex-start;
flex-direction: column;
}
body {
font-family: 'Open Sans', sans-serif;
font-weight: 400;
font-size: 1em;
line-height: 2em;
color: $gray;
background-color: #d0d0d0;
text-align: center;
}
*,
*:hover {
cursor: none;
}
a {
&:hover {
color: red;
}
svg {
pointer-events: none;
}
}
.space
{
margin-bottom: 1em;
}
.actions {
margin-top: 2em;
display: flex;
&__item
{
text-align: center;
a {
display: inline-block;
width: 9em;
padding: 1em 0;
color: $gray;
text-decoration: none;
}
&:last-child
{
margin: 0 1em;
background-color: #fafafa;
}
}
}
.svg-cursor {
position: absolute;
pointer-events: none;
z-index: 1000;
font-size: 1.5em;
&__lines {
transform: scale(.8) rotate(0);
transform-origin: .5em .5em;
transition: all $normalDuration $bezier;
line {
transition: all $normalDuration $bezier;
transform-origin: .5em .5em;
&:nth-of-type(1) {
transform: rotate(45deg);
}
&:nth-of-type(2) {
transform: scaleX(.65) translateY(-.35em);
}
&:nth-of-type(3) {
transform: scaleY(.65) rotate(90deg) translateY(.35em);
}
}
}
&__action {
animation: bounce $slowDuration linear infinite;
}
&__close {
.svg-cursor__lines {
transform: scale(.8) rotate(360deg);
line {
transform-origin: .5em .5em;
&:nth-child(1) {
transform: rotate(45deg);
}
&:nth-child(2) {
transform: scaleX(0) translateY(0);
}
&:nth-child(3) {
transform: scaleY(1) rotate(-45deg) translateY(0);
}
}
}
}
}
@keyframes bounce {
30% {
transform: translate(.5em, .5em);
}
40% {
transform: translate(0, 0);
}
50% {
transform: translate(.25em, .25em);
}
60%,
100% {
transform: translate(0, 0);
}
}
.modal {
display: flex;
align-items: center;
justify-content: center;
position: fixed;
width: 100vw;
height: 100vh;
z-index: 10;
transform: scale(0);
transition: transform $fastDuration ease-in-out;
&__header {
font-weight: 700;
font-size: 2em;
margin-bottom: .5em;
font-family: 'Bitter', serif;
}
&__content {
position: relative;
z-index: 2;
box-sizing: border-box;
padding: 2em 2.4em 2.4em;
background-color: #fafafa;
max-height: 80vh;
display: flex;
flex-direction: column;
align-items: flex-start;
}
&__background {
width: 100vw;
height: 100vh;
z-index: 1;
position: absolute;
left: 0;
top: 0;
background-color: rgba(black, .15);
opacity: 0;
transition: opacity $normalDuration linear;
transition-delay: 0s;
}
&__close {
position: absolute;
top: 0;
right: 0;
transform: translate(50%, -50%);
height: 2em;
a
{
display: inline-block;
}
}
&:target {
.modal__background {
opacity: 1;
transition-delay: $normalDuration;
}
transform: scale(1);
}
}
.code {
width: 100%;
max-height: 15em;
padding: .8em 1em 1em;
box-sizing: border-box;
font-family: 'Anonymous Pro';
background-color: #f0f0f0;
overflow: auto;
box-shadow: inset 0 -1em 2em -1em rgba(black, .2);
&__line {
font-size: .8em;
line-height: 1.75em;
text-align: left;
}
@for $i from 1 to 9 {
&__push#{$i}
{
padding-left: 1em * $i;
}
}
&__comment {
color: gray;
}
}
View Compiled
document.body.addEventListener("mousemove", function(event) {
moveCursor(event);
});
var svgCursor = document.getElementById('svg-cursor');
function moveCursor(e) {
var x = e.clientX - 5,
y = e.clientY - 5;
svgCursor.setAttribute('style', 'left: ' + x + 'px; top: ' + y + 'px');
if (e.target.className.indexOf('custom-cursor') > -1) {
switch (e.target.className) {
case 'custom-cursor custom-cursor--action':
svgCursor.setAttribute('class', 'svg-cursor svg-cursor__action')
break;
case 'custom-cursor custom-cursor--close':
svgCursor.setAttribute('class', 'svg-cursor svg-cursor__close')
break;
}
} else {
svgCursor.setAttribute('class', 'svg-cursor');
}
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.