<div class="app" id="app">
<audio id="wouf" src="https://www.sound-fishing.net/download.php?id=1855"></audio>
<h1 class="title">Move the mouse for dog walking</h1>
</div>
* {
padding: 0;
margin: 0;
}
body {
overflow: hidden;
height: 100vh;
/** https://dev.to/alvarosaburido/use-custom-emoji-as-a-cursor-using-css-3j7 */
cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='40' height='48' viewport='0 0 100 100' style='fill:black;font-size:24px;'><text y='50%'>🐕</text></svg>")
16 0, auto;
}
.app {
display: flex;
align-items: center;
flex-direction: column;
height: 100vh;
width: 100%;
background-image: linear-gradient(to top, #ffde92, #ffe19b, #ffe4a4, #ffe6ac, #ffe9b5);
}
.title {
font-family: system-ui;
text-transform: uppercase;
text-align: center;
color: white;
font-size: 50px;
text-shadow: 0 5px 5px #00000085;
margin-top: 50px;
z-index: 2;
line-height: 50px;
}
.pow {
position: absolute;
width: 100px;
height: 100px;
opacity: 0.7;
transform-origin: 50px;
}
.pow__center {
position: absolute;
height: 50px;
width: 50px;
top: 50px;
left: 25px;
background-color: #4D4637;
border-radius: 100px;
box-shadow: inset 5px 5px 0px 0px black;
}
.pow__finger {
position: absolute;
height: 25px;
width: 25px;
background-color: #4D4637;
border-radius: 100%;
box-shadow: inset 5px 5px 0px 0px black;
}
.pow__finger:nth-child(2) {
top: 43px;
left: 2px;
}
.pow__finger:nth-child(3) {
top: 20px;
left: 24px;
height: 28px;
}
.pow__finger:nth-child(4) {
top: 20px;
right: 24px;
height: 28px;
}
.pow__finger:nth-child(5) {
top: 43px;
right: 2px;
}
/**
* Here is a tutorial for walking your dog !
* Made with all my love on Twitch.tv ! <3
*
* Follow me :p
* https://twitch.tv/emilienjc
* https://github.com/EmilienLeroy
* https://codepen.io/emilienleroy/
* https://twitter.com/LeroyEmilien
*/
const pows = [];
const app = document.querySelector('#app');
const wouaf = document.querySelector('#wouf');
let left = false;
document.addEventListener('click', () => {
wouaf.volume = 0.2;
wouaf.play();
});
document.addEventListener('mousemove', (e) => {
const previousPow = pows[pows.length - 1];
if (pows.length === 0) {
const pow = createPow(e.clientX, e.clientY);
pows.push(pow);
app.append(pow);
return;
}
if (previousPow) {
const { x, y } = previousPow.getBoundingClientRect();
const distance = getDistance({ x: e.clientX, y: e.clientY }, { x, y });
if (distance > 150) {
const angle = getAngle({ x: e.clientX, y: e.clientY }, { x, y }) - 90;
const pow = createPow(e.clientX, e.clientY, left, angle);
left = !left;
pows.push(pow);
app.append(pow);
if (pows.length > 10) {
pows.shift().removePow();
}
}
}
});
function createPow(x, y, left = false, angle = 0) {
const pow = document.createElement('div');
const animation = left ?
`rotate(${angle}deg) translate(-50px, -20px)` :
`rotate(${angle}deg) translate(50px, -20px)`;
pow.style.top = `${y}px`;
pow.style.left = `${x}px`;
pow.classList.add('pow');
pow.innerHTML = `
<div class="pow__center"></div>
<div class="pow__finger"></div>
<div class="pow__finger"></div>
<div class="pow__finger"></div>
<div class="pow__finger"></div>
`;
pow.animate([
{
transform: `scale(0.9) ${animation}` ,
opacity: '0'
},
{
transform: `scale(1) ${animation}`,
opacity: '0.7'
}
], {
duration: 500,
easing: 'ease',
fill: 'both',
})
pow.removePow = () => {
pow.animate([
{ opacity: 0.7 },
{ opacity: 0 }
], {
duration: 1000,
easing: 'ease',
}).onfinish = () => pow.remove();
}
return pow;
}
/**
* https://gist.github.com/conorbuck/2606166
*/
function getAngle(pos1, pos2) {
return Math.atan2(pos2.y - pos1.y, pos2.x - pos1.x) * 180 / Math.PI;
}
/**
* https://gist.github.com/timohausmann/5003280
*/
function getDistance(pos1, pos2) {
let xs = pos2.x - pos1.x;
let ys = pos2.y - pos1.y;
ys *= ys;
xs *= xs;
return Math.sqrt(xs + ys);
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.