skills/blobity-cursor/SKILL.md
Add Blobity canvas cursor effects to desktop landing pages. Supports HTML, React, Vue 3, Vue 2, and Astro, with light/dark themes, tooltip mode, touch-device skipping, and cleanup patterns. Trigger words: blobity, cursor effect, landing page cursor, Astro cursor, 光标特效
npx skillsauth add shiqkuangsan/oh-my-daily-skills tooyoung:blobity-cursorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Add a canvas-based custom cursor effect to landing pages. The cursor follows the mouse with spring physics, expands to wrap interactive elements, and inverts colors via mix-blend-mode: difference.
Core mechanism: Blobity creates a <canvas> overlay (position: fixed, pointer-events: none, z-index: max) and draws a blob that follows the cursor using the Kinet spring physics engine. With invert: true, the canvas uses mix-blend-mode: difference to create a color-inversion effect.
Minimal working example — copy into any HTML page:
<!-- Hide default cursor -->
<style>
body.blobity-active,
body.blobity-active a,
body.blobity-active button,
body.blobity-active [data-blobity],
body.blobity-active [data-blobity-tooltip] {
cursor: none !important;
}
</style>
<!-- Load Blobity via ESM CDN (npm: import Blobity from 'blobity') -->
<script type="module">
import Blobity from "https://esm.sh/[email protected]";
// Skip touch devices
if ("ontouchstart" in window || navigator.maxTouchPoints > 0) {
throw new Error("Touch device — skip Blobity");
}
const blobity = new Blobity({
licenseKey: "opensource",
invert: true,
zIndex: 50,
color: "#ffffff", // Canvas fill → difference with dark bg = light
dotColor: "#10b981", // Resting cursor dot color
radius: 6,
magnetic: false,
mode: "normal",
focusableElements: "a, button, [data-blobity], [data-blobity-tooltip]",
focusableElementsOffsetX: 5,
focusableElementsOffsetY: 4,
font: "'JetBrains Mono', monospace",
fontSize: 16,
fontWeight: 600,
fontColor: "#0d1117", // Tooltip text color on canvas
tooltipPadding: 12,
});
document.body.classList.add("blobity-active");
</script>
Add data-blobity-tooltip="Label text" to any element for tooltip mode:
<div class="card" data-blobity-tooltip="View details">...</div>
CDN (no build tool):
<script type="module">
import Blobity from "https://esm.sh/[email protected]";
</script>
Other CDNs (
cdn.jsdelivr.net,cdn.blobity.dev) have known 404/connection issues. Useesm.sh.
npm (with bundler):
# pnpm (recommended)
pnpm add blobity
# npm
npm install blobity
# yarn
yarn add blobity
import Blobity from "blobity";
Blobity has
reactandvueas optional peer dependencies. Ignore the warning if you're not using their bindings.
The mix-blend-mode: difference formula is |page_pixel - canvas_pixel|. This means:
Key rule: dark bg uses white color, light bg uses a dark color calculated from your target tint.
| Option | Dark Mode | Light Mode | Notes |
| ----------- | --------- | ---------- | ----------------------------------------------------------------------------- |
| color | #ffffff | #190a11 | Light mode produces soft mint #e6f5ee on white |
| dotColor | #10b981 | #111827 | Accent green / dark gray |
| fontColor | #0d1117 | #000000 | Tooltip text: dark→black on light bg, light→white on dark bg after difference |
Watch for theme attribute changes and update Blobity options dynamically:
const isDark = () =>
document.documentElement.getAttribute("data-theme") !== "light";
// Alternative checks:
// document.documentElement.classList.contains('dark')
// window.matchMedia('(prefers-color-scheme: dark)').matches
const observer = new MutationObserver(() => {
blobity.updateOptions({
color: isDark() ? "#ffffff" : "#190a11",
dotColor: isDark() ? "#10b981" : "#111827",
fontColor: isDark() ? "#0d1117" : "#000000",
});
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ["data-theme", "class"],
});
To calculate custom light-mode colors, see
references/color-math.md.
| Option | Type | Default | Description |
| -------------------------- | ------- | ------------- | -------------------------------------------------- |
| licenseKey | string | — | Use 'opensource' for open-source projects |
| invert | boolean | false | Enable mix-blend-mode: difference on canvas |
| color | string | '#000000' | Canvas fill color when hovering focusable elements |
| dotColor | string | '#000000' | Resting cursor dot color |
| radius | number | 4 | Dot radius in pixels |
| magnetic | boolean | true | Whether cursor snaps to element center on hover |
| mode | string | 'normal' | Cursor mode |
| zIndex | number | -1 | Canvas z-index |
| focusableElements | string | 'a, button' | CSS selector for interactive elements |
| focusableElementsOffsetX | number | 0 | Horizontal padding when wrapping elements |
| focusableElementsOffsetY | number | 0 | Vertical padding when wrapping elements |
| font | string | — | Tooltip font family |
| fontSize | number | 16 | Tooltip font size |
| fontWeight | number | 400 | Tooltip font weight |
| fontColor | string | '#000000' | Tooltip text color on canvas |
| tooltipPadding | number | 4 | Tooltip inner padding |
Add data-blobity-tooltip to elements — cursor morphs into a text label instead of expanding:
<div class="step-card" data-blobity-tooltip="Step 1: Upload">...</div>
<a href="/docs" data-blobity-tooltip="Documentation">Docs</a>
Tooltip elements should be included in focusableElements via [data-blobity-tooltip] selector.
Light mode tooltip text visibility: tooltip background gets darkened by difference blend, so fontColor must also produce a light result after blending. Use #000000 for light mode (becomes white after |#fff - #000| = #fff).
✗ cdn.jsdelivr.net/npm/blobity@latest/lib/blobity.min.js → wrong path
✗ cdn.blobity.dev/by.js → server down
✗ cdn.jsdelivr.net/npm/[email protected] → version doesn't exist
✓ esm.sh/[email protected] → works
This is a mix-blend-mode: difference color math issue. See the Theme Adaptation section — use a dark color value for light backgrounds (NOT white).
Always skip Blobity on touch devices — there's no mouse cursor to replace:
const isTouchDevice = "ontouchstart" in window || navigator.maxTouchPoints > 0;
if (isTouchDevice) return;
Blobity must be destroyed on route change to avoid canvas leaks:
// Astro view transitions
document.addEventListener(
"astro:before-swap",
() => {
observer.disconnect();
document.body.classList.remove("blobity-active");
blobity.destroy();
},
{ once: true },
);
// React Router / Vue Router
onUnmounted(() => {
blobity.destroy();
});
// Or useEffect cleanup in React
Blobity declares react and vue as peer deps. Safe to ignore if not using their framework bindings:
# pnpm
pnpm add blobity --no-strict-peer-dependencies
# npm (if needed)
npm install blobity --legacy-peer-deps
Set zIndex high enough to overlay page content but below modals/dialogs. 50 works for most cases. If your site has a sticky header at z-index: 100+, either raise Blobity's value or accept the cursor rendering behind the header.
Add a playful bounce effect when user scrolls:
let scrollTimeout = null;
window.addEventListener(
"scroll",
() => {
if (scrollTimeout) return;
scrollTimeout = setTimeout(() => {
blobity.bounce();
scrollTimeout = null;
}, 150);
},
{ passive: true },
);
| File | Content |
| -------------------------- | ----------------------------------------------------------------------------- |
| references/frameworks.md | React hook, Vue 3 composable, Vue 2 mixin — complete templates |
| references/color-math.md | mix-blend-mode: difference color calculation, lookup table, reverse formula |
development
Show OpenAI Codex release highlights in Chinese. Fetch GitHub release notes, summarize feature-level changes, skip bug-fix/chore noise by default, and append a mandatory highlights section. Trigger words: Codex updates, Codex features, Codex 新功能, Codex 更新, OpenAI Codex releases
development
清理当前项目的 Claude Code 会话:列出 ~/.claude/projects 下最近会话,按序号或 sessionId 选择,经二次确认后删除对应 .jsonl 与同名附件目录。Trigger words: 清理 cc 会话, 删除历史会话, cc resume 会话, clean cc sessions, cc session cleaner
development
Create simple Three.js web apps with scene setup, lighting, geometries, materials, animations, OrbitControls, particles, and responsive rendering. Use for Three.js scenes, WebGL demos, 3D showcases, and interactive 3D web content. Trigger: threejs, Three.js, 3D scene, WebGL, 三维展示, 3D showcase, interactive 3D
development
为 Claude Code 定义个性化身份风格(人设)。触发词:定义人设、创建身份、persona、角色设定、CLAUDE.local.md