Skip to content

Eraser Cursor cursor

The eraser follows your cursor and wipes text away all along the way! ᕕ( ゚ ∀。)ᕗ

TIP

This component is driven by cursor movement; a desktop or mouse-capable device is recommended.

Examples

Basic Usage

Once enabled, the text the eraser sweeps over gradually fades, then slowly drifts back after a while.

Check out the example source code
vue
<template>
  <div class="example-wrap flex flex-col items-center gap-6">
    <!-- 啟用後游標才化為橡皮擦 -->
    <base-checkbox
      v-model="eraserEnabled"
      :label="t('enable')"
      class="example-ctrl"
    />

    <cursor-eraser v-if="eraserEnabled" />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import BaseCheckbox from '../../base-checkbox.vue'
import CursorEraser from '../cursor-eraser.vue'

const { t } = useI18n()

const eraserEnabled = ref(false)
</script>

How it Works

Relying on caretRangeFromPoint, it can tell exactly which characters the cursor is over; each frame it scatters a few sample points across the contact area and erases whichever characters they hit.

(Firefox is fussier and wants caretPositionFromPoint (。-`ω´-))

The neat part is that the fade never touches the DOM — it uses the cool CSS Custom Highlight API, which I've written an article about before.

Each erased character is wrapped into a Range, grouped by "text color × fade level"; whenever a new color shows up, a set of multi-level ::highlight() rules is generated for it on the fly in code, each using color-mix(in srgb, the original color, transparent …) to fade along its own color toward transparent.

The whole process just adds and removes Ranges in the CSS.highlights registry, never modifying any DOM structure, and it clears the highlights on unmount. ( •̀ ω •́ )✧

Source Code

API

Props

interface Props {
  /** 可擦除的範圍,傳入 CSS selector 或元素。預設整個頁面 */
  root?: string | HTMLElement;

  /** 橡皮擦寬邊長度(px)。@default 52 */
  eraserSize?: number;

  /** 橡皮擦橡膠本體顏色(紙套由此衍生;招牌藍黑色帶為固定配色)。@default '#f4f4f2' */
  eraserColor?: string;

  /** 跟隨靈敏度,0~1,越大追得越緊。@default 0.2 */
  followSpeed?: number;

  /** 彈性,0~1,越大Q彈晃動越明顯。@default 0.55 */
  bounciness?: number;

  /** 擦除速度,被擦文字每秒淡化的比例。@default 2 */
  eraseSpeed?: number;

  /** 文字回復速度,每秒回復比例。0 表示永不復原。@default 0.001 */
  regenerationSpeed?: number;

  /** 文字碎屑顏色,預設沿用被擦文字的顏色。@default 'currentColor' */
  crumbColor?: string;

  /** 每個被擦字元噴出的文字碎屑數量。@default 2 */
  crumbCount?: number;

  /** 疊放層級。@default 9990 */
  zIndex?: number;
}

v0.69.0