npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@astralume/keyboard

v0.1.0

Published

A scalable Vue 3 visual keyboard component with themes, key states, holding hints and animation APIs.

Readme

@astralume/keyboard

English documentation is available in the second half of this README.

@astralume/keyboard 是一个 Vue 3 可视化键盘组件。它可以展示高保真键盘布局,监听真实键盘和鼠标输入,显示按下、成功、失败、教学提示、锁定按下、时间轴动画和波纹动画等状态。

组件源码位于 src/lib。本仓库的演示页面位于 src/demo,不会进入 npm 包。npm 包只发布 dist 内的组件产物。

功能特性

  • Vue 3 组件,支持 TypeScript 类型。
  • 支持紧凑键盘、合并全键盘、分区全键盘三种布局。
  • 支持整体缩放,通过 widthkeySizegapXgapY 控制比例。
  • 支持真实键盘输入、鼠标/触摸输入和按键事件抛出。
  • 支持普通全面接管和增强接管。增强接管会尝试使用 Fullscreen API 与 Keyboard Lock API。
  • 支持 holding、locked、success、error、自定义状态。
  • 支持 timeline 脚本动画、蛇形波纹动画、typed-array 高频帧渲染。
  • 支持主题、CSS 变量、自定义 class、自定义单键样式。

安装

pnpm add @astralume/keyboard

也可以使用 npm 或 yarn:

npm install @astralume/keyboard
yarn add @astralume/keyboard

快速开始

<script setup lang="ts">
import VisualKeyboard from '@astralume/keyboard'
import '@astralume/keyboard/style.css'
</script>

<template>
  <VisualKeyboard />
</template>

推荐用法

大多数情况下,只需要传入少量 options。组件会把缺失项与默认配置合并。

<script setup lang="ts">
import { computed } from 'vue'
import VisualKeyboard, { type PartialDeep, type KeyboardOptions } from '@astralume/keyboard'
import '@astralume/keyboard/style.css'

const keyboardOptions = computed<PartialDeep<KeyboardOptions>>(() => ({
  layout: {
    mode: 'compact',
    width: 960,
    keySize: 56,
    gapX: 4,
    gapY: 4,
  },
  appearance: {
    theme: 'demo2',
  },
  behavior: {
    defaultPressState: 'success',
    pointerBehavior: 'press',
  },
}))
</script>

<template>
  <VisualKeyboard :options="keyboardOptions" />
</template>

完整示例

<script setup lang="ts">
import { ref } from 'vue'
import VisualKeyboard, {
  type KeyEventPayload,
  type KeyboardOptions,
  type StateDefinitionMap,
  type TimelineItem,
} from '@astralume/keyboard'
import '@astralume/keyboard/style.css'

const keyboardRef = ref<InstanceType<typeof VisualKeyboard> | null>(null)

const options: KeyboardOptions = {
  layout: {
    mode: 'compact',
    width: 960,
    keySize: 56,
    gapX: 4,
    gapY: 4,
    blockGapScale: 4,
    paddingScale: 2.5,
    topRowHeight: 'compact',
    splitRatios: [0.5, 0.44, 0.4],
  },
  appearance: {
    theme: 'demo2',
    keyRadiusPercent: 25,
    topKeyRadiusPercent: 25,
    boardClass: '',
    keyClass: '',
    boardStyleVars: {},
    keyStyleVars: {},
    keyClassMap: {},
    keyStyleVarsMap: {},
  },
  behavior: {
    captureAllKeys: false,
    enhancedCapture: false,
    pointerBehavior: 'press',
    defaultPressState: 'success',
    renderMode: 'vue',
  },
  states: {
    holdingState: 'holding',
    lockedState: 'default',
  },
}

const stateDefinitions: StateDefinitionMap = {
  teaching: {
    styleVars: {
      '--vk-key-bg': '#e9ddff',
      '--vk-key-color': '#4c2c85',
    },
  },
}

const timeline: TimelineItem[] = [
  { keyId: 'KeyH', at: 0, duration: 120, visualState: 'success', pressed: true },
  { keyId: 'KeyI', at: 150, duration: 120, visualState: 'success', pressed: true },
]

function handleKeyEvent(payload: KeyEventPayload) {
  console.log(payload.keyId, payload.phase)
}

function playWave() {
  keyboardRef.value?.playWave({
    tailLength: 7,
    speed: 1,
    maxActiveWaves: 8,
  })
}
</script>

<template>
  <VisualKeyboard
    ref="keyboardRef"
    :options="options"
    :holding-keys="['KeyA', 'KeyS']"
    :locked-keys="['Escape']"
    :state-definitions="stateDefinitions"
    :timeline="timeline"
    :timeline-playing="false"
    @key-event="handleKeyEvent"
  />

  <button type="button" @click="playWave">播放波纹</button>
</template>

Props

| Prop | 类型 | 默认值 | 说明 | | ------------------ | ------------------------------- | ------- | --------------------------------------------------------------------------- | | options | PartialDeep<KeyboardOptions> | {} | 键盘配置。可以只传局部配置,组件会与默认配置合并。 | | holdingKeys | string[] | [] | 教学提示按键。可以传 keyId,例如 KeyA,也可以传部分显示文本,例如 A。 | | lockedKeys | string[] | [] | 持续按下的按键。适合展示“某个键保持按下”的状态。 | | keyStateMap | Record<string, KeyStateInput> | {} | 外部直接指定某些按键的状态。key 可以是 keyId 或显示文本。 | | stateDefinitions | StateDefinitionMap | {} | 自定义状态定义。用于把状态名映射成 class、CSS 变量和 pressed 覆盖。 | | resolveKeyView | (payload) => KeyStateInput | null | 渲染前的状态解析钩子。适合把业务判断映射成状态。 | | plugins | VisualKeyboardPlugin[] | [] | 插件列表。插件可以处理输入事件或参与状态解析。 | | timeline | TimelineItem[] | [] | 声明式时间轴动画。 | | timelinePlaying | boolean | false | 是否播放 timeline。 |

KeyboardOptions

KeyboardOptions 分为四组:layoutappearancebehaviorstates

layout

| 字段 | 类型 | 默认值 | 作用 | | --------------- | ------------------------------------ | ------------------ | ----------------------------------------------------------------------------------------------------------- | | mode | 'compact' \| 'full' \| 'separated' | 'compact' | 布局模式。compact 是主键盘,full 是主键盘加右侧合并区域,separated 是主键盘、导航区和数字区分离显示。 | | width | number | 960 | 键盘最终显示宽度,单位 px。组件会按这个宽度整体缩放。 | | keySize | number | 56 | 标准按键边长,单位 px。布局内部以它作为基准计算。 | | gapX | number | 4 | 按键横向间隙,单位 px。 | | gapY | number | 4 | 按键纵向间隙,单位 px。 | | blockGapScale | number | 4 | 全键盘模式下,不同键盘区之间的横向间距倍数。实际间距为 gapX * blockGapScale。 | | paddingScale | number | 2.5 | 键盘背景内边距倍数。实际内边距为 gapX/gapY * paddingScale。 | | topRowHeight | 'compact' \| 'full' | 'compact' | 顶部功能键高度。compact 约为标准键高的三分之二,full 等于标准键高。 | | splitRatios | [number, number, number] | [0.5, 0.44, 0.4] | 动态宽度按键比例。依次控制 Tab/反斜杠Caps/Enter左 Shift/右 Shift。值会限制在 0 到 1。 |

appearance

| 字段 | 类型 | 默认值 | 作用 | | --------------------- | ---------------------------------------- | --------- | --------------------------------------------------------------------- | | theme | string | 'demo2' | 主题名称。内置主题包括 demo1demo2demo1-darkdemo2-dark。 | | keyRadiusPercent | number | 25 | 普通按键圆角百分比。0 表示直角,50 表示最大圆角。 | | topKeyRadiusPercent | number | 25 | 顶部功能键圆角百分比。 | | boardClass | string | '' | 追加到键盘背景上的 class。 | | keyClass | string | '' | 追加到所有按键上的 class。 | | boardStyleVars | Record<string, string> | {} | 写到键盘背景上的 CSS 变量或样式。 | | keyStyleVars | Record<string, string> | {} | 写到所有按键上的 CSS 变量或样式。 | | keyClassMap | Record<string, string \| string[]> | {} | 给单个按键追加 class。key 可以是 keyId 或显示文本。 | | keyStyleVarsMap | Record<string, Record<string, string>> | {} | 给单个按键追加 CSS 变量或样式。key 可以是 keyId 或显示文本。 |

behavior

| 字段 | 类型 | 默认值 | 作用 | | ------------------- | ------------------------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | captureAllKeys | boolean | false | 是否阻止可捕获键盘事件的默认行为和传播。浏览器保留快捷键不一定能被普通页面拦截。 | | enhancedCapture | boolean | false | 是否启用增强接管。开启后会在用户输入时尝试 Fullscreen API 和 Keyboard Lock API。 | | pointerBehavior | 'press' \| 'emit' \| 'none' \| 'toggle' \| 'lock' \| 'custom' \| string | 'press' | 鼠标/触摸行为。press 临时按下,emit 只抛事件,none 忽略状态,toggle 点击切换,lock 点击后保持按下,custom 留给外部逻辑处理。 | | defaultPressState | string | 'success' | 真实键盘或鼠标按下时默认触发的视觉状态。可设为 none 表示不显示状态色,设为 default 表示只显示主题原本按下态。 | | renderMode | 'vue' \| 'hybrid' \| 'frame' | 'vue' | 渲染模式。vue 适合普通使用,hybridframe 适合更高频动画。 |

states

| 字段 | 类型 | 默认值 | 作用 | | -------------- | -------- | ----------- | -------------------------------- | | holdingState | string | 'holding' | holdingKeys 使用的视觉状态名。 | | lockedState | string | 'default' | lockedKeys 使用的视觉状态名。 |

状态系统

状态可以是字符串,也可以是对象。

type KeyStateInput = string | KeyLayerState | null | undefined

KeyLayerState 字段:

| 字段 | 类型 | 说明 | | ------------- | ------------------------ | ------------------------------------------------------------------- | | pressed | boolean | 是否显示按下形态。 | | visualState | string | 视觉状态名,例如 successerrorholdingwave。 | | priority | number | 状态优先级。数值越大越晚合成,越容易覆盖低优先级状态。 | | className | string \| string[] | 附加 class。 | | styleVars | Record<string, string> | 附加 CSS 变量或样式。它会略高于同层默认状态定义,适合逐键动画颜色。 |

内置状态

| 状态名 | 说明 | | --------- | ------------------------------------ | | success | 成功状态,默认是绿色系。 | | error | 失败状态,默认是红色系。 | | holding | 教学提示状态。 | | wave | 波纹动画状态。 | | default | 不追加视觉状态,但可以保留按下形态。 | | none | 不渲染视觉状态。 |

自定义状态

const stateDefinitions = {
  warning: {
    styleVars: {
      '--vk-key-bg': '#fff1b8',
      '--vk-key-color': '#705600',
    },
  },
  pressedBlue: {
    pressed: true,
    styleVars: {
      '--vk-key-bg': '#dbeafe',
      '--vk-key-color': '#1d4ed8',
    },
  },
}

事件

组件会抛出 key-event

<VisualKeyboard @key-event="handleKeyEvent" />

KeyEventPayload 字段:

| 字段 | 类型 | 说明 | | ------------- | --------------- | --------------------------------------------- | | keyId | string | 标准按键 id,例如 KeyAEscapeSpace。 | | label | string | 按键显示文本。 | | codes | number[] | 兼容旧 keyCode 的数字列表。 | | source | string | 输入来源,例如 physicalpointer。 | | phase | string | 输入阶段,例如 downupcancel。 | | nativeEvent | Event \| null | 原生事件。 | | repeat | boolean | 是否是键盘 repeat。 | | timestamp | number | 事件时间戳。 |

命令式 API

通过 ref 获取组件实例:

const keyboardRef = ref<InstanceType<typeof VisualKeyboard> | null>(null)

keyboardRef.value?.playWave()

| 方法 | 说明 | | ----------------------------------------- | ------------------------------------------ | | requestEnhancedCapture() | 手动请求增强接管。浏览器通常需要用户手势。 | | releaseEnhancedCapture() | 释放 Keyboard Lock 等增强接管状态。 | | getVisibleKeys() | 获取当前可见交互键列表。 | | setLayerState(layerName, keyRef, state) | 设置某一层中的单个按键状态。 | | setLayerStates(layerName, changes) | 批量设置某一层中的按键状态。 | | clearLayer(layerName?) | 清理指定状态层;不传时清空所有状态层。 | | playTimeline(items, options?) | 播放脚本化时间轴。 | | pauseTimeline(target?) | 暂停时间轴。 | | resumeTimeline(target?) | 恢复时间轴。 | | seekTimeline(time, target?) | 跳转时间轴到指定毫秒。 | | stopTimeline(target?, options?) | 停止时间轴。 | | playWave(options?) | 播放蛇形波纹动画。 | | startFrameRenderer(source, options?) | 启动 typed-array 高频帧渲染器。 | | stopFrameRenderer(clearFrameLayer?) | 停止 typed-array 高频帧渲染器。 | | clearTransientActiveKeys() | 清理临时按下态,适合页面失焦后手动兜底。 |

时间轴动画

keyboardRef.value?.playTimeline(
  [
    { keyId: 'KeyH', at: 0, duration: 120, visualState: 'success', pressed: true },
    { keyId: 'KeyI', at: 150, duration: 120, visualState: 'success', pressed: true },
  ],
  {
    layerName: 'typing',
    autoClear: true,
    loop: false,
  },
)

TimelineItem 字段:

| 字段 | 类型 | 说明 | | ------------- | ------------------------- | -------------------------------- | | keyId | string | 目标按键 id。 | | key | string | keyId 的兼容别名。 | | at | number | 事件开始时间,单位毫秒。 | | start | number | at 的兼容别名。 | | action | string | setclear。默认是 set。 | | state | string \| KeyLayerState | 要写入的状态。 | | pressed | boolean | 是否显示按下形态。 | | visualState | string | 视觉状态名。 | | priority | number | 事件优先级。 | | className | string \| string[] | 附加 class。 | | styleVars | Record<string, string> | 附加 CSS 变量或样式。 | | duration | number | 持续时间,结束后会自动 clear。 |

波纹动画

playWave 默认按视觉行蛇形播放:第一行从左到右,第二行从右到左,依次交替。蛇头颜色较深,尾巴逐渐变浅。

keyboardRef.value?.playWave({
  speed: 1,
  tailLength: 7,
  maxActiveWaves: 8,
  headColor: '#0a2644',
  tailColor: '#f4faff',
})

WaveOptions 常用字段:

| 字段 | 类型 | 默认值 | 说明 | | ---------------- | --------------------------------- | --------- | -------------------------------------------- | | speed | number | 1 | 播放速度倍率。越大越快。 | | step | number | 34 | 每步间隔,单位毫秒,会受 speed 影响。 | | tailLength | number | 7 | 蛇身长度,也就是同一时间最多显示的尾巴段数。 | | headColor | string | #0a2644 | 蛇头背景色。 | | tailColor | string | #f4faff | 尾巴末端背景色。 | | headTextColor | string | #f6fbff | 蛇头文字色。 | | tailTextColor | string | #1d4a70 | 尾巴文字色。 | | maxActiveWaves | number | 6 | 最大并发波数量。重复点击时会复用波纹层。 | | loop | boolean \| 'infinite' \| number | false | 是否循环播放。 | | repeatDelay | number | 0 | 每轮循环之间的延迟。 |

高频帧渲染

如果你需要播放非常长、非常密集的动画,可以使用 startFrameRenderer。它使用 typed array 存储每一帧状态,并只提交发生变化的按键。

const startedAt = performance.now()

keyboardRef.value?.startFrameRenderer((frame, now) => {
  const elapsed = now - startedAt
  if (elapsed > 3000) {
    return false
  }

  frame.setKey('KeyA', {
    pressed: true,
    stateId: 1,
    intensity: 1,
  })
})

主题与样式扩展

必须引入组件样式:

import '@astralume/keyboard/style.css'

内置主题:

  • demo1 亮色立体主题。
  • demo2 亮色简洁主题。
  • demo1-dark 暗色立体主题。
  • demo2-dark 暗色简洁主题。

可以通过 CSS 变量覆盖主题:

<VisualKeyboard
  :options="{
    appearance: {
      boardClass: 'my-keyboard',
      keyStyleVars: {
        '--vk-key-bg': '#111827',
        '--vk-key-color': '#f9fafb',
      },
    },
  }"
/>
.my-keyboard {
  --vk-board-bg: #f8fafc;
}

全面接管与增强接管

captureAllKeys 会尽可能阻止页面内可捕获键盘事件的默认行为和传播。

const options = {
  behavior: {
    captureAllKeys: true,
  },
}

enhancedCapture 会尝试使用 Fullscreen API 和 Keyboard Lock API。

const options = {
  behavior: {
    enhancedCapture: true,
  },
}

浏览器仍可能保留系统级快捷键或部分浏览器快捷键,例如某些关闭标签、切换应用、系统截图快捷键。这不是组件可以完全绕过的限制。

发布包边界

组件代码:

  • src/lib 用于 npm 包构建。
  • src/lib/index.ts 是包入口。

演示代码:

  • src/demo 只用于本仓库调试和展示。
  • dist-demo 是演示页构建产物,不会发布到 npm。

npm 包内容通过 files 限制,只发布:

  • dist/index.js
  • dist/index.cjs
  • dist/index.d.ts
  • dist/style.css
  • 相关类型声明文件

本地开发

pnpm install
pnpm dev

构建

pnpm build

pnpm build 会生成库模式产物:

  • dist/index.js 是 ESM 入口。
  • dist/index.cjs 是 CommonJS 入口。
  • dist/index.d.ts 是类型入口。
  • dist/style.css 是组件样式。

演示页单独构建:

pnpm build:demo

发布前检查

pnpm lint
pnpm format:check
pnpm build
pnpm pack --dry-run

正式发布:

npm publish --access public

@astralume/keyboard

@astralume/keyboard is a Vue 3 visual keyboard component. It renders a high-fidelity keyboard, listens to physical keyboard and pointer input, and supports pressed states, success/error states, teaching hints, locked keys, timeline animations, wave animations, and high-frequency frame rendering.

The component source lives in src/lib. The demo app lives in src/demo and is not published to npm. The npm package only publishes compiled files from dist.

Features

  • Vue 3 component with TypeScript types.
  • Compact keyboard, merged full keyboard, and separated full keyboard layouts.
  • Scalable layout controlled by width, keySize, gapX, and gapY.
  • Physical keyboard input, pointer input, and normalized key events.
  • Basic key capture and optional enhanced capture with Fullscreen API and Keyboard Lock API.
  • Built-in and custom visual states.
  • Timeline animation, snake-like wave animation, and typed-array frame rendering.
  • Theme presets, CSS variables, custom classes, and per-key style overrides.

Installation

pnpm add @astralume/keyboard

Or:

npm install @astralume/keyboard
yarn add @astralume/keyboard

Quick Start

<script setup lang="ts">
import VisualKeyboard from '@astralume/keyboard'
import '@astralume/keyboard/style.css'
</script>

<template>
  <VisualKeyboard />
</template>

Recommended Usage

You can pass only the options you need. Missing fields are merged with the default options.

<script setup lang="ts">
import { computed } from 'vue'
import VisualKeyboard, { type PartialDeep, type KeyboardOptions } from '@astralume/keyboard'
import '@astralume/keyboard/style.css'

const keyboardOptions = computed<PartialDeep<KeyboardOptions>>(() => ({
  layout: {
    mode: 'compact',
    width: 960,
    keySize: 56,
    gapX: 4,
    gapY: 4,
  },
  appearance: {
    theme: 'demo2',
  },
  behavior: {
    defaultPressState: 'success',
    pointerBehavior: 'press',
  },
}))
</script>

<template>
  <VisualKeyboard :options="keyboardOptions" />
</template>

Props

| Prop | Type | Default | Description | | ------------------ | ------------------------------- | ------- | ----------------------------------------------------------------------------------------------- | | options | PartialDeep<KeyboardOptions> | {} | Keyboard layout, appearance, behavior, and state options. | | holdingKeys | string[] | [] | Keys highlighted as teaching hints. Values can be key ids such as KeyA or labels such as A. | | lockedKeys | string[] | [] | Keys that should stay visually pressed. | | keyStateMap | Record<string, KeyStateInput> | {} | External per-key state map. Keys can be key ids or labels. | | stateDefinitions | StateDefinitionMap | {} | Custom state definitions. | | resolveKeyView | (payload) => KeyStateInput | null | Hook for resolving per-key visual state before rendering. | | plugins | VisualKeyboardPlugin[] | [] | Plugin list for input and rendering extensions. | | timeline | TimelineItem[] | [] | Declarative timeline animation. | | timelinePlaying | boolean | false | Whether to play the declarative timeline. |

KeyboardOptions

layout

| Field | Type | Default | Description | | --------------- | ------------------------------------ | ------------------ | ------------------------------------------------------------------------- | | mode | 'compact' \| 'full' \| 'separated' | 'compact' | Layout mode. | | width | number | 960 | Final rendered keyboard width in pixels. | | keySize | number | 56 | Base key size in pixels. | | gapX | number | 4 | Horizontal gap between keys. | | gapY | number | 4 | Vertical gap between rows. | | blockGapScale | number | 4 | Gap multiplier between keyboard blocks. | | paddingScale | number | 2.5 | Board padding multiplier. | | topRowHeight | 'compact' \| 'full' | 'compact' | Function-key row height mode. | | splitRatios | [number, number, number] | [0.5, 0.44, 0.4] | Dynamic split ratios for Tab/Backslash, Caps/Enter, and left/right Shift. |

appearance

| Field | Type | Default | Description | | --------------------- | ---------------------------------------- | --------- | -------------------------------------------------------------------------- | | theme | string | 'demo2' | Theme name. Built-in themes: demo1, demo2, demo1-dark, demo2-dark. | | keyRadiusPercent | number | 25 | Regular key radius percentage. | | topKeyRadiusPercent | number | 25 | Top-row key radius percentage. | | boardClass | string | '' | Extra class added to the keyboard board. | | keyClass | string | '' | Extra class added to all keys. | | boardStyleVars | Record<string, string> | {} | Inline CSS variables or styles for the board. | | keyStyleVars | Record<string, string> | {} | Inline CSS variables or styles for all keys. | | keyClassMap | Record<string, string \| string[]> | {} | Extra classes for specific keys. | | keyStyleVarsMap | Record<string, Record<string, string>> | {} | Inline CSS variables or styles for specific keys. |

behavior

| Field | Type | Default | Description | | ------------------- | ------------------------------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------- | | captureAllKeys | boolean | false | Prevent default behavior and propagation for capturable keyboard events. | | enhancedCapture | boolean | false | Try to use Fullscreen API and Keyboard Lock API. | | pointerBehavior | 'press' \| 'emit' \| 'none' \| 'toggle' \| 'lock' \| 'custom' \| string | 'press' | Pointer input behavior. | | defaultPressState | string | 'success' | Visual state used when a key is pressed. | | renderMode | 'vue' \| 'hybrid' \| 'frame' | 'vue' | Rendering mode. Use vue for normal usage and hybrid/frame for high-frequency animation. |

states

| Field | Type | Default | Description | | -------------- | -------- | ----------- | ----------------------------------- | | holdingState | string | 'holding' | Visual state used by holdingKeys. | | lockedState | string | 'default' | Visual state used by lockedKeys. |

Imperative API

| Method | Description | | ----------------------------------------- | ------------------------------------------------------ | | requestEnhancedCapture() | Request enhanced keyboard capture. | | releaseEnhancedCapture() | Release enhanced keyboard capture. | | getVisibleKeys() | Get currently visible interactive keys. | | setLayerState(layerName, keyRef, state) | Set one key state in a layer. | | setLayerStates(layerName, changes) | Set multiple key states in a layer. | | clearLayer(layerName?) | Clear a state layer, or clear all layers when omitted. | | playTimeline(items, options?) | Play a scripted timeline. | | pauseTimeline(target?) | Pause timelines. | | resumeTimeline(target?) | Resume timelines. | | seekTimeline(time, target?) | Seek a timeline to a specific time. | | stopTimeline(target?, options?) | Stop timelines. | | playWave(options?) | Play the snake-like wave animation. | | startFrameRenderer(source, options?) | Start the typed-array frame renderer. | | stopFrameRenderer(clearFrameLayer?) | Stop the typed-array frame renderer. | | clearTransientActiveKeys() | Clear temporary pressed states. |

Wave Animation

playWave moves in a snake-like path: first row left to right, second row right to left, and so on. The head is darker and the tail fades to a lighter color.

keyboardRef.value?.playWave({
  speed: 1,
  tailLength: 7,
  maxActiveWaves: 8,
  headColor: '#0a2644',
  tailColor: '#f4faff',
})

Local Development

pnpm install
pnpm dev

Build

pnpm build

Demo build:

pnpm build:demo

Prepublish Checklist

pnpm lint
pnpm format:check
pnpm build
pnpm pack --dry-run

Publish:

npm publish --access public