Skip to content

橡皮擦游標 cursor

橡皮擦會跟著游標移動並一路擦掉文字!ᕕ( ゚ ∀。)ᕗ

TIP

此元件靠游標移動觸發,建議用電腦或可使用滑鼠的裝置瀏覽。

技術關鍵字

名稱 描述
Document caretRangeFromPoint()取得指定座標處的文字插入點(Range),可用來定位游標壓在哪個字元上
CSS Custom Highlight API以 Range 標記任意文字範圍並用 ::highlight() 套用樣式,不需修改 DOM 結構即可改變文字外觀

使用範例

基本用法

勾選啟用後,橡皮擦掃過的文字會逐漸變淡,一段時間後會慢慢浮現回來。

查看範例原始碼
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>

原理

依靠 caretRangeFromPoint,讓我們可以明確得知游標碰到甚麼文字,並每幀在接觸範圍灑幾個取樣點,命中哪些字就擦哪些。

(Firefox 毛比較多,得改用 caretPositionFromPoint(。-`ω´-))

特點是淡化效果完全不碰 DOM,使用 CSS Custom Highlight API 這個酷東西,之前還寫過文章分享應用方式。

把被擦的字包成 Range,依「文字顏色 × 淡化程度」分組,每冒出一種新顏色就用程式即時生出一組多階 ::highlight() 規則,再用 color-mix(in srgb, 原色, transparent …) 沿各自原色慢慢淡到透明。

整個過程只是在 CSS.highlights 註冊表裡加加減減 Range,不會修改任何 DOM 結構,元件移除時只要把 highlight 清乾淨即可。( •̀ ω •́ )✧

原始碼

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