Skip to content

Commit

Permalink
add custom cursor #48
Browse files Browse the repository at this point in the history
  • Loading branch information
ukorvl committed Aug 6, 2023
1 parent 3ef09ac commit d436a8d
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 2 deletions.
2 changes: 2 additions & 0 deletions app/template.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import TopMenu from '@/components/TopMenu/TopMenu';
import SocialIcons from '@/components/SocialIcons/SocialIcons';
import {loadFeatures} from '@/lib/framerMotion/loadFeatures';
import ScrollToTopButton from '@/components/ScrollToTop/ScrollToTop';
import CustomCursor from '@/lib/customCursor/CustomCursor';

/**
* @param {{children}} props Props.
Expand All @@ -25,6 +26,7 @@ export default function Template({children}: {children: React.ReactNode}) {
/>
<SocialIcons />
{children}
<CustomCursor />
</LazyMotion>
);
}
3 changes: 2 additions & 1 deletion components/Gallery/GalleryItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import clsx from 'clsx';
import Image from 'next/image';
import {forwardRef} from 'react';
import {useHotkeys} from 'react-hotkeys-hook';
import {customCursorClickableClass} from '@/lib/customCursor/customCursorClickableClass';
import AppearInViewport from '../AppearInViewport/AppearInViewport';

/**
Expand All @@ -16,7 +17,7 @@ type GalleryItemProps = {

const imgCn = clsx('rounded-md', 'overflow-hidden');
const overflowCn = clsx(
'cursor-pointer',
customCursorClickableClass,
'relative',
'after:absolute',
'after:content-[""]',
Expand Down
14 changes: 14 additions & 0 deletions lib/customCursor/CustomCursor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import dynamic from 'next/dynamic';
import {prefersReducedMotion} from '@/utils/isPrefersReducedMotion';
import options from './customCursorOptions';

const AnimatedCursor = dynamic(() => import('react-animated-cursor'), {
ssr: false,
});

/**
* @returns Custom cursor.
*/
export default function CustomCursor() {
return prefersReducedMotion ? null : <AnimatedCursor {...options} />;
}
1 change: 1 addition & 0 deletions lib/customCursor/customCursorClickableClass.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const customCursorClickableClass = 'custom-cursor-clickable';
29 changes: 29 additions & 0 deletions lib/customCursor/customCursorOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {ComponentProps} from 'react';
import AnimatedCursor from 'react-animated-cursor';
import {customCursorClickableClass} from './customCursorClickableClass';

// eslint-disable-next-line jsdoc/require-jsdoc
type Options = ComponentProps<typeof AnimatedCursor>;

const options: Options = {
innerSize: 12,
outerStyle: {
border: '2px solid white',
},
outerSize: 20,
outerScale: 2,
outerAlpha: 0.2,
color: '255, 255, 255',
innerScale: 0,
clickables: [
'a',
'input[type="text"]',
'input[type="email"]',
'input[type="number"]',
'label[for]',
'button',
`.${customCursorClickableClass}`,
],
};

export default options;
16 changes: 16 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"photoswipe": "^5.3.8",
"postcss": "8.4.23",
"react": "18.2.0",
"react-animated-cursor": "^2.7.0",
"react-dom": "18.2.0",
"react-hotkeys-hook": "^4.4.0",
"react-page-visibility": "^7.0.0",
Expand Down
4 changes: 3 additions & 1 deletion utils/isPrefersReducedMotion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ const query = '(prefers-reduced-motion: reduce)';
/**
* @returns True if the user has requested reduced motion.
*/
export default function isPrefersReducedMotion() {
function isPrefersReducedMotion() {
if (isServer()) {
return false;
}

const mediaQueryList = window.matchMedia(query);
return mediaQueryList.matches;
}

export const prefersReducedMotion = isPrefersReducedMotion();

0 comments on commit d436a8d

Please sign in to comment.