logo

Aki UI

アキ ウイ

Mouse Effect Card

マウスエフェクトカード

A field of dots that parts around the cursor. Each dot subscribes to the same pair of motion values↗↗ holding the pointer position and derives its own offset from them, so the whole field updates outside React — no state changes, no re-render per frame. Within the repulsion radius the offset is the unit vector away from the pointer scaled by how close it is, and a spring on each axis gives the dots weight on the way out and on the way back. Opacity is driven from the same distance over a slightly wider radius, which is what makes the cursor look like it is carrying a light. Dots thin out towards the edges on a probability that falls with distance from the centre, so the field fades into the card rather than stopping at a rectangle; that randomness is why generation happens in an effect and never during server render. Arrow keys walk a virtual pointer in fifths of the card, so the effect is reachable without a mouse. Adapted from Kokonut UI↗↗ under the MIT licence.

Case study

Acme

Move the cursor across the field, or focus the card and use the arrow keys.

Installation

Copy and paste the following code into a new component file:1

"use client"

/**
* Adapted for Aki UI from Kokonut UI's Mouse Effect Card.
* Original author: @dorianbaffier — https://kokonutui.com
* Copyright (c) 2025 kokonutUI, MIT License.
* https://github.com/kokonut-labs/kokonutui
*
* Reworked here onto the local palette, with shadcn primitives and
* class-variance-authority removed and motion/react swapped for framer-motion.

How to use it2

"use client"

import { MouseEffectCard } from "@/components/ui/mouse-effect-card"

export default function Page() {
return (
<MouseEffectCard>
<h2 className="text-lg font-medium">Acme</h2>
<p className="text-sm text-[#888888]">Move the cursor across the field.</p>
</MouseEffectCard>

Props

MouseEffectCard

NameDefaultDescription
children—

ReactNode

Centred content, laid over the field and not clickable

width400

number

Card width in pixels; the field is generated to fit

height340

number

Card height in pixels

dotSize2

number

Diameter of one dot in pixels

spacing18

number

Grid pitch before thinning — lower means many more dots

radius80

number

Pixels within which a dot is pushed away

strength20

number

Pixels a dot moves at the centre of the pointer

darkfalse

boolean

Render the dark palette