Jack-o'-Lantern Cursor
Le curseur se transforme en tête de citrouille qui sème une traînée de mini-citrouilles s'estompant dans le sillage. Canvas pur, zéro image externe.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Curseurs comprend 26 effets, dont 1 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Un sprite citrouille est dessiné une seule fois sur un <canvas> hors-écran (160×160 px) au chargement : corps en ellipses orange dégradées (createRadialGradient), tige verte, visage triangulaire avec ombre portée jaune (shadowBlur) — aucun asset externe. Ce sprite est réutilisé à chaque frame via drawImage() pour le curseur principal et chaque particule de traînée.
À chaque pointermove, la position du curseur est lue en coordonnées canvas (multipliée par devicePixelRatio plafonné à 2) et une particule est poussée dans le tableau trail[] si plus de 28 ms se sont écoulées depuis la dernière. Chaque particule porte une taille (s), une opacité (a), un angle de rotation (r) et une vitesse angulaire (vr) aléatoires.
La boucle requestAnimationFrame efface le canvas à chaque image, parcourt trail[] de la plus ancienne à la plus récente (l'alpha décroît ×0,9 et la taille ×0,965 par frame), supprime les particules sous 0,05 d'opacité, puis dessine le curseur principal avec un léger rebond sinusoïdal (sin(bob)) et une oscillation en rotation.
Accessibilité
- Mouvement réduit : sous
prefers-reduced-motion: reduce, le script ne pousse aucune particule danstrail[]et désactive l'animation de balancement sinusoïdal — le curseur citrouille s'affiche de façon statique, sans traînée ni oscillation. Note : la règle CSScursor: nonereste active ; pour rétablir le curseur système, ajouter@media (prefers-reduced-motion: reduce) { .jol-scene { cursor: auto } }. - Clavier : l'effet est purement décoratif et ne réagit pas aux événements clavier.
- Tactile :
pointermovecapture aussi les déplacements tactiles (doigt). Sur les appareils mobiles, la traînée de citrouilles apparaît sous le doigt. - Sémantique :
.jol-hintportearia-hidden="true"pour ne pas parasiter les lecteurs d'écran. La zone d'effet elle-même n'a pas de rôle ARIA — elle est purement visuelle. - Contraste : l'effet ne modifie aucun texte ni élément interactif existant.
cursor: nonesur.jol-scenemasque le curseur système uniquement dans la zone de l'effet.
Compatibilité navigateur
Canvas 2D et JS vanilla, aucune dépendance. requestAnimationFrame disponible depuis Chrome 24, Firefox 23, Safari 6.1. devicePixelRatio depuis Chrome 29, Firefox 18, Safari 8. performance.now() depuis Chrome 24, Firefox 15, Safari 8. Non vérifié sur Safari réel ; attendu complet.
Sans JavaScript, .jol-scene affiche son fond radial-gradient sans curseur ni traînée — la zone reste accessible et lisible. La règle cursor: none continue de masquer le curseur système ; sans JS, ajouter .jol-scene { cursor: default } ou retirer l'attribut si l'effet n'est pas chargé.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0805-root">
<div class="jol-scene" data-jol="">
<canvas class="jol-canvas"></canvas>
<div class="jol-hint" aria-hidden="true">Laisse une traînée de citrouilles…</div>
</div>
</div>
Paiement unique, sans abonnement — le code est à toi pour toujours
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Zone d'activation — attribut data-jol |
présent sur .jol-scene |
Chaque élément portant cet attribut devient une zone indépendante : curseur et traînée confinés dans son getBoundingClientRect(). Plusieurs zones peuvent coexister dans la même page sans interférence. |
Fond de scène — CSS sur .jol-scene |
radial-gradient(circle at 50% 40%, #211326, #070409 72%) |
Remplacer par n'importe quel fond (couleur unie, image, autre gradient) pour adapter la palette à votre page. L'effet canvas est transparent — seul ce fond et les citrouilles sont visibles. |
Taille du curseur citrouille — constante JS 56 |
56 × DPR = 56–112 px | Modifier l'entier 56 dans var i = 56 * l * a pour agrandir (80) ou réduire (36) le curseur principal. Les particules de traînée ont leur propre facteur s: .32 + .12 * Math.random(). |
| Densité de la traînée — délai entre particules | 28 ms |
Réduire à 15 ms pour une traînée très dense sur les mouvements rapides ; augmenter à 60 ms pour une traînée clairsemée. Modifier la comparaison performance.now() - s > 28 dans le JS. |
Vitesse de disparition des particules — facteur .9 |
a *= .9 (alpha) et s *= .965 (taille) |
Réduire le facteur d'alpha (.85) pour une traînée qui s'efface plus vite ; l'augmenter (.93) pour des citrouilles qui persistent plus longtemps. Modifier de même le facteur de taille pour contrôler le rétrécissement. |
Texte d'invitation — .jol-hint |
"Laisse une traînée de citrouilles…" | Remplacer le contenu HTML ou masquer avec .jol-hint { display: none } si l'invitation n'est pas souhaitée. Le hint est aria-hidden et n'a aucun impact fonctionnel. |
FAQ
data-jol sur n'importe quel élément — une bannière, une carte, un modal — avec position: relative; overflow: hidden; cursor: none. Le curseur citrouille reste confiné dans ce conteneur grâce au calcul de position relatif à getBoundingClientRect(). Plusieurs zones indépendantes peuvent coexister dans la même page.performance.now() - s > 28 par false (ou Infinity) : aucune particule ne sera jamais enregistrée dans trail[]. Le curseur principal est affiché de façon statique (sans rebond sinusoïdal) ; aucune traînée n'est enregistrée.pointermove est déclenché par les glissements tactiles (pointerType === 'touch'). Sur mobile, la traînée de citrouilles apparaît sous le doigt. Pour désactiver l'effet sur tactile uniquement, ajouter dans le listener : if (a.pointerType !== 'mouse') return; avant la mise à jour des coordonnées.