<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="800">
<defs>
<filter id="goo">
<feGaussianBlur in="SourceGraphic" stdDeviation="6" result="blur" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 35 -15" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
</filter>
</defs>
</svg>
<div class="page">
<div class="page-bg">
<p>M</p>
<div class="noise"></div>
</div>
<div class="lines">
<div class="line1"></div>
<div class="line2"></div>
<div class="line3"></div>
<div class="line4"></div>
<div class="line5"></div>
</div>
<div class="container">
<div class="child">
<div class="content">
<div>
<div id="button" class="HoverButton">
<div class="bg"></div>
<h1>Hover Me</h1>
</div>
</div>
</div>
</div>
</div>
<div class="images">
<img src="https://foo-exp.s3.amazonaws.com/morph_mouse/img_big.png" class="big" id="bigImg">
<img src="https://foo-exp.s3.amazonaws.com/morph_mouse/img_small.png" class="small" id="smallImg">
</div>
<div class="stamp">
<div class="circle">
<p id="circle-content">EXPERIMENTS . EXPERIMENTS .</p>
</div>
<p>2018</p>
</div>
<div class="design">
<p>Best viewed on Chrome</p>
<a href="https://dribbble.com/eaamst" target="blank">Designed by: Eder Anaya</a>
</div>
</div>
<div id="cursor" class="Cursor">
</div>
*
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
body
html
cursor none
width 100%
height 100%
font-family 'Roboto', sans-serif
background-color #e0dad5
overflow hidden
svg
display none
.page
width 100%
height 100%
background-color #e0dad5
display block
.page-bg
width 100%
height 100%
display block
position absolute
overflow hidden
top 0
left 0
z-index 1
background-color #e0dad5
p
font-family 'Asul', sans-serif
color #dbd6d1
opacity 0.8
font-size 85vmin
margin 0
text-align center
line-height 100vh
.noise
background-image url('https://foo-exp.s3.amazonaws.com/morph_mouse/noise_pattern.png')
background-size 200px 200px
background-repeat repeat
position absolute
top 0
left 0
width 100%
height 100%
mix-blend-mode hard-light
.container
width 100%
height 100%
display table
z-index 100
.child
display table-row
.content
display table-cell
vertical-align middle
text-align center
.HoverButton
position relative
display inline-block
z-index 20
padding 0 2%
overflow hidden
//overflow-x hidden
&:after
content "01"
display block
position absolute
color #ee3d3d
top 5%
right 3%
mix-blend-mode difference
font-family 'Asul', sans-serif
font-size 1.2vmax
font-weight bold
.bg
pointer-events none
position absolute
background-color #ee3d3d
height 100%
width: 125%
display block
//z-index 1
transform translateX(-112%) skew(-10deg)
h1
color #ee3d3d
position relative
font-weight normal
font-family 'Asul', sans-serif
z-index 1
margin 0
font-size 11vmax
mix-blend-mode difference
.images
position absolute
left 50%
top 64vh
transform translate(-50%, 0);
z-index 10
pointer-events none
.big
width 36vmax
.small
width 27vmax
position absolute
left 50%
top 50%
transform translate(-50%, -50%)
.Cursor
pointer-events none
position fixed
display block
border-radius 0
transform-origin center center
mix-blend-mode difference
top 0
left 0
z-index 1000
filter url("#goo")
span
position absolute
display block
width: 26px
height 26px
border-radius 20px
background-color: white
transform-origin center center
transform: translate(-50%, -50%)
.stamp
position absolute
right 6vmax
top 6vmax
z-index 10
p
color #ee3d3d
font-size 2vmax
font-family 'Asul', sans-serif
margin 0
.circle
position absolute
width 1px
height 1px
display block
left 50%
top 50%
background-color transparent
animation rotating 9.5s linear infinite
span
font-family: 'Rubik', sans-serif;
font-weight bold
font-size 0.8vmax
color #ee3d3d
height 5vmax
position absolute
display inline-block
left 0
bottom 0
transform-origin: bottom center
for i in (1..28)
.char{i}
transform rotate((i*13)deg)
@keyframes rotating {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.line
position absolute
background-color #ede8e5
.line-vertical
@extends .line
width 2px
height 100%
top 0
.line-horizontal
@extends .line
width 100%
height 2px
left 0
.lines
position absolute
width 100%
height 100%
left 0
top 0
z-index 2
.line1
@extends .line-horizontal
top 36vh
.line2
@extends .line-horizontal
top 64vh
.line3
@extends .line-vertical
left 22vw
.line4
@extends .line-vertical
left 78vw
.line5
@extends .line-vertical
left 50vw
.design
position absolute
left 10px
top 10px
z-index 5
color black
font-family: 'Work Sans', sans-serif;
font-size 10px
a
color black
View Compiled
const cursor = document.getElementById("cursor");
const amount = 20;
const sineDots = Math.floor(amount * 0.3);
const width = 26;
const idleTimeout = 150;
let lastFrame = 0;
let mousePosition = {x: 0, y: 0};
let dots = [];
let timeoutID;
let idle = false;
let hoverButton;
let hoverTL;
class HoverButton {
constructor(id) {
this.hovered = false;
this.animatingHover = false;
this.forceOut = false;
this.timing = 0.65;
this.el = document.getElementById(id);
this.bg = this.el.getElementsByClassName("bg")[0];
this.el.addEventListener("mouseenter", this.onMouseEnter);
this.el.addEventListener("mouseleave", this.onMouseLeave);
}
onMouseEnter = () => {
this.hoverInAnim();
};
hoverInAnim = () => {
if (!this.hovered) {
this.hovered = true;
this.animatingHover = true;
this.forceOut = false;
TweenMax.fromTo(
this.bg,
this.timing,
{x: "-112%"},
{
x: "-12%",
ease: Power3.easeOut,
onComplete: () => {
this.animatingHover = false;
if (this.forceOut) {
this.foceOut = false;
this.hoverOutAnim();
}
}
}
);
}
};
onMouseLeave = () => {
if (!this.animatingHover) {
this.hoverOutAnim();
} else {
this.forceOut = true;
}
};
hoverOutAnim = () => {
this.hovered = false;
TweenMax.to(this.bg, this.timing, {
x: "100%",
ease: Power3.easeOut,
onComplete: () => {
}
});
};
}
class Dot {
constructor(index = 0) {
this.index = index;
this.anglespeed = 0.05;
this.x = 0;
this.y = 0;
this.scale = 1 - 0.05 * index;
this.range = width / 2 - width / 2 * this.scale + 2;
this.limit = width * 0.75 * this.scale;
this.element = document.createElement("span");
TweenMax.set(this.element, {scale: this.scale});
cursor.appendChild(this.element);
}
lock() {
this.lockX = this.x;
this.lockY = this.y;
this.angleX = Math.PI * 2 * Math.random();
this.angleY = Math.PI * 2 * Math.random();
}
draw(delta) {
if (!idle || this.index <= sineDots) {
TweenMax.set(this.element, {x: this.x, y: this.y});
} else {
this.angleX += this.anglespeed;
this.angleY += this.anglespeed;
this.y = this.lockY + Math.sin(this.angleY) * this.range;
this.x = this.lockX + Math.sin(this.angleX) * this.range;
TweenMax.set(this.element, {x: this.x, y: this.y});
}
}
}
class Circle {
constructor(id) {
const el = document.getElementById(id);
const parent = el.parentElement;
parent.removeChild(el);
const chars = el.innerText.split("");
chars.push(" ");
for (let i = 0; i < chars.length; i++) {
const span = document.createElement("span");
span.innerText = chars[i];
span.className = `char${i + 1}`;
parent.appendChild(span);
}
}
}
function init() {
window.addEventListener("mousemove", onMouseMove);
window.addEventListener("touchmove", onTouchMove);
hoverButton = new HoverButton("button");
// eslint-disable-next-line no-new
new Circle("circle-content");
lastFrame += new Date();
buildDots();
render();
}
/*function limit(value, min, max) {
return Math.min(Math.max(min, value), max);
}*/
function startIdleTimer() {
timeoutID = setTimeout(goInactive, idleTimeout);
idle = false;
}
function resetIdleTimer() {
clearTimeout(timeoutID);
startIdleTimer();
}
function goInactive() {
idle = true;
for (let dot of dots) {
dot.lock();
}
}
function buildDots() {
for (let i = 0; i < amount; i++) {
let dot = new Dot(i);
dots.push(dot);
}
}
const onMouseMove = event => {
mousePosition.x = event.clientX - width / 2;
mousePosition.y = event.clientY - width / 2;
resetIdleTimer();
};
const onTouchMove = () => {
mousePosition.x = event.touches[0].clientX - width / 2;
mousePosition.y = event.touches[0].clientY - width / 2;
resetIdleTimer();
};
const render = timestamp => {
const delta = timestamp - lastFrame;
positionCursor(delta);
lastFrame = timestamp;
requestAnimationFrame(render);
};
const positionCursor = delta => {
let x = mousePosition.x;
let y = mousePosition.y;
dots.forEach((dot, index, dots) => {
let nextDot = dots[index + 1] || dots[0];
dot.x = x;
dot.y = y;
dot.draw(delta);
if (!idle || index <= sineDots) {
const dx = (nextDot.x - dot.x) * 0.35;
const dy = (nextDot.y - dot.y) * 0.35;
x += dx;
y += dy;
}
});
};
init();
View Compiled
This Pen doesn't use any external CSS resources.