Skip to content

Commit

Permalink
feat: change the cursor animation
Browse files Browse the repository at this point in the history
  • Loading branch information
vittxr committed Jul 28, 2024
1 parent f09c384 commit 7a12d37
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 77 deletions.
32 changes: 12 additions & 20 deletions src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,19 @@ html, body {
@apply hover:underline
}

/* Home page custom cursor */
.cursor {
position: fixed;
width: 40px;
height: 40px;
margin-left: -20px;
margin-top: -20px;
border-radius: 50%;
border: 2px solid #FBAB7E;
transition: transform 0.3s ease;
transform-origin: center center;
pointer-events: none;
z-index: 1000;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
}

.grow, .grow-small {
transform: scale(4);
background: white;
mix-blend-mode: difference;
border: none;
line {
stroke: #3f51b5;
stroke-width: 4;
stroke-linecap: round;
filter: blur(4px);
stroke-dashoffset: 50%;
}

.grow-small {
transform: scale(2);
}
72 changes: 72 additions & 0 deletions src/components/Cursor.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<script lang="ts">
import { gsap } from 'gsap';
import { afterUpdate } from 'svelte';
type Pointer = {
x: number;
y: number;
};
gsap.defaults({ ease: 'none' });
const svgns = 'http://www.w3.org/2000/svg';
let cursor: SVGSVGElement | null = null;
const ease = 0.75;
afterUpdate(() => {
const pointer: Pointer = {
x: window.innerWidth / 2,
y: window.innerHeight / 2,
};
window.addEventListener('mousemove', function (event: MouseEvent) {
pointer.x = event.clientX;
pointer.y = event.clientY;
});
let leader: Pointer | SVGLineElement = pointer;
const total = 150;
for (let i = 0; i < total; i++) {
leader = createLine(leader, i);
}
function createLine(leader: Pointer | SVGLineElement, i: number): SVGLineElement {
const line = document.createElementNS(svgns, 'line');
if (cursor) {
cursor.appendChild(line);
}
gsap.set(line, { x: -15, y: -15, alpha: (total - i) / total });
gsap.to(line, {
duration: 200,
x: '+=1',
y: '+=1',
repeat: -1,
modifiers: {
x: function () {
const posX = parseFloat(gsap.getProperty(line, 'x') as string);
const leaderX = parseFloat(gsap.getProperty(leader, 'x') as string);
const x = posX + (leaderX - posX) * ease;
line.setAttribute('x2', (leaderX - x).toString());
return x;
},
y: function () {
const posY = parseFloat(gsap.getProperty(line, 'y') as string);
const leaderY = parseFloat(gsap.getProperty(leader, 'y') as string);
const y = posY + (leaderY - posY) * ease;
line.setAttribute('y2', (leaderY - y).toString());
return y;
},
},
});
return line;
}
});
</script>

<svg bind:this={cursor} class="cursor z-[-1]"></svg>
57 changes: 0 additions & 57 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,74 +2,17 @@
import '../app.css';
import '$lib/i18n';
import Base from './_fragments/Base.svelte';
import { gsap } from 'gsap';
import { browser } from '$app/environment';
import { locale, waitLocale, isLoading } from 'svelte-i18n';
import { onMount, beforeUpdate, afterUpdate } from 'svelte';
let cursor: HTMLDivElement | null = null;
let cursorScale = [];
let mouseX = 0;
let mouseY = 0;
export const load = async () => {
if (browser) {
locale.set(window.navigator.language);
}
await waitLocale();
};
onMount(() => {
// Initial setup if needed
});
beforeUpdate(() => {
// Any setup before the DOM update
});
afterUpdate(() => {
cursorScale = Array.from(document.querySelectorAll('.cursor-scale'));
gsap.to({}, 0.016, {
repeat: -1,
onRepeat: function () {
gsap.set(cursor, {
css: {
left: mouseX,
top: mouseY,
},
});
},
});
window.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
});
cursor?.classList.remove('grow');
cursor?.classList.remove('grow-small');
cursorScale.forEach((item) => {
console.log('cursor: ', cursor);
item.addEventListener('mousemove', () => {
cursor?.classList.add('grow');
if (item.classList.contains('cursor-scale')) {
cursor?.classList.remove('grow');
cursor?.classList.add('grow-small');
}
});
item.addEventListener('mouseleave', () => {
cursor?.classList.remove('grow');
cursor?.classList.remove('grow-small');
});
});
});
</script>

<div bind:this={cursor} class="cursor"></div>

{#if $isLoading}
Please wait...
{:else}
Expand Down
3 changes: 3 additions & 0 deletions src/routes/home/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
<script lang="ts">
import '$lib/i18n';
import { _ } from 'svelte-i18n';
import HeroSection from '$routes/home/fragments/HeroSection.svelte';
import Cursor from '$components/Cursor.svelte';
</script>

<svelte:head>
<title>vschirmer / home</title>
</svelte:head>

<Cursor />
<HeroSection className="h-full" />

0 comments on commit 7a12d37

Please sign in to comment.