timeline-canvas 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +162 -0
- package/README_CN.md +164 -0
- package/dist/ContextMenuPlugin-B9TmnnaU.mjs +1 -0
- package/dist/ContextMenuPlugin-Crk3ma0O.d.mts +10 -0
- package/dist/DarkThemePlugin-CRFdrOR3.mjs +1 -0
- package/dist/DarkThemePlugin-IbJNx65n.d.mts +6 -0
- package/dist/EventMediaPlugin-DPPdLbey.mjs +1 -0
- package/dist/EventMediaPlugin-daiUXxsT.d.mts +6 -0
- package/dist/EventTooltipPlugin-Ce6xChyf.mjs +1 -0
- package/dist/EventTooltipPlugin-b5fqBb8j.d.mts +28 -0
- package/dist/LightThemePlugin-BOreTGti.mjs +1 -0
- package/dist/LightThemePlugin-DrdhIHgA.d.mts +6 -0
- package/dist/Logger-Bwd6lZLT.mjs +1 -0
- package/dist/PerformanceOverlayPlugin-BFU4Le2k.d.mts +6 -0
- package/dist/PerformanceOverlayPlugin-Bx-DkYbW.mjs +1 -0
- package/dist/builtin-plugin/ContextMenuPlugin.d.mts +3 -0
- package/dist/builtin-plugin/ContextMenuPlugin.mjs +1 -0
- package/dist/builtin-plugin/DarkThemePlugin.d.mts +3 -0
- package/dist/builtin-plugin/DarkThemePlugin.mjs +1 -0
- package/dist/builtin-plugin/EventMediaPlugin.d.mts +3 -0
- package/dist/builtin-plugin/EventMediaPlugin.mjs +1 -0
- package/dist/builtin-plugin/EventTooltipPlugin.d.mts +3 -0
- package/dist/builtin-plugin/EventTooltipPlugin.mjs +1 -0
- package/dist/builtin-plugin/LightThemePlugin.d.mts +3 -0
- package/dist/builtin-plugin/LightThemePlugin.mjs +1 -0
- package/dist/builtin-plugin/MutexGuardPlugin.d.mts +6 -0
- package/dist/builtin-plugin/MutexGuardPlugin.mjs +1 -0
- package/dist/builtin-plugin/PerformanceOverlayPlugin.d.mts +3 -0
- package/dist/builtin-plugin/PerformanceOverlayPlugin.mjs +1 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.mjs +1 -0
- package/dist/performanceMonitor-Cf-Ah4F7.mjs +1 -0
- package/dist/types-CkHQNcJ5.mjs +1 -0
- package/dist/types-D5-4YwEP.d.mts +600 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# Timeline Canvas
|
|
2
|
+
|
|
3
|
+
A powerful, high-performance timeline component built with HTML5 Canvas and TypeScript.
|
|
4
|
+
|
|
5
|
+
[document Chinese Only](https://umbrella22.github.io/timeline-canvas/index.html)
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🚀 **High Performance**: Built with Canvas API for smooth rendering of large datasets.
|
|
10
|
+
- 🎨 **Themable**: Built-in Light and Dark themes, with support for custom themes.
|
|
11
|
+
- 🖱️ **Interactive**:
|
|
12
|
+
- Drag and drop events to move them.
|
|
13
|
+
- Resize events from both ends.
|
|
14
|
+
- Split events with double-click.
|
|
15
|
+
- Zooming (Ctrl/Cmd + Scroll) and Panning.
|
|
16
|
+
- Context menu support.
|
|
17
|
+
- 📏 **Smart Guides**: Alignment guides and snapping for precise event placement.
|
|
18
|
+
- ⏱️ **Time Indicator**: Draggable time head with snapping support.
|
|
19
|
+
- 🔌 **Plugin System**: Extensible architecture with built-in plugins for themes, context menus, and more.
|
|
20
|
+
- 📝 **TypeScript**: Written in TypeScript with full type definitions.
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install timeline-canvas
|
|
26
|
+
# or
|
|
27
|
+
pnpm add timeline-canvas
|
|
28
|
+
# or
|
|
29
|
+
yarn add timeline-canvas
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Basic Usage
|
|
33
|
+
|
|
34
|
+
1. Create a container with a canvas element in your HTML:
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<div style="width: 100%; height: 500px;">
|
|
38
|
+
<canvas id="timeline-canvas"></canvas>
|
|
39
|
+
</div>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
1. Initialize the Timeline:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { Timeline } from "timeline-canvas";
|
|
46
|
+
|
|
47
|
+
// Initialize
|
|
48
|
+
const timeline = new Timeline("timeline-canvas", {
|
|
49
|
+
startTime: 0,
|
|
50
|
+
endTime: 100,
|
|
51
|
+
trackHeight: 40,
|
|
52
|
+
// ... other options
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Add a track
|
|
56
|
+
timeline.addTrack();
|
|
57
|
+
|
|
58
|
+
// Add an event (trackIndex, startTime, endTime, title)
|
|
59
|
+
timeline.addEvent(0, 10, 30, "My Event", "Description");
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Configuration
|
|
63
|
+
|
|
64
|
+
The `Timeline` constructor accepts an options object:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
interface TimelineOptions {
|
|
68
|
+
// Dimensions
|
|
69
|
+
canvasHeight?: number;
|
|
70
|
+
trackHeight?: number;
|
|
71
|
+
trackMargin?: number;
|
|
72
|
+
timelineHeight?: number;
|
|
73
|
+
|
|
74
|
+
// Time Settings
|
|
75
|
+
startTime?: number;
|
|
76
|
+
endTime?: number;
|
|
77
|
+
secondWidth?: number; // Pixels per second
|
|
78
|
+
snapInterval?: number;
|
|
79
|
+
snapToSeconds?: boolean;
|
|
80
|
+
|
|
81
|
+
// Features
|
|
82
|
+
enableTimeIndicator?: boolean;
|
|
83
|
+
enableEventResize?: boolean;
|
|
84
|
+
enableEventSplit?: boolean;
|
|
85
|
+
enableContextMenu?: boolean;
|
|
86
|
+
readOnly?: boolean;
|
|
87
|
+
autoAddTrack?: boolean;
|
|
88
|
+
|
|
89
|
+
// Styling
|
|
90
|
+
colors?: Partial<TimelineColors>;
|
|
91
|
+
eventTextStyle?: Partial<EventTextStyle>;
|
|
92
|
+
theme?: TimelinePlugin; // Initial theme
|
|
93
|
+
|
|
94
|
+
// Callbacks
|
|
95
|
+
onEventAdd?: (data: EventAddData) => void;
|
|
96
|
+
onEventUpdate?: (data: EventUpdateData) => void;
|
|
97
|
+
onEventClick?: (data: EventClickData) => void;
|
|
98
|
+
// ... and more
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## API Reference
|
|
103
|
+
|
|
104
|
+
### Core Methods
|
|
105
|
+
|
|
106
|
+
- **`addTrack()`**: Adds a new empty track.
|
|
107
|
+
- **`removeTrack()`**: Removes the last track.
|
|
108
|
+
- **`addEvent(trackIndex, startTime, endTime, title, ...)`**: Adds an event to a specific track.
|
|
109
|
+
- **`updateEvent(trackIndex, eventIndex, updates)`**: Updates an existing event.
|
|
110
|
+
- **`deleteEvent(trackIndex, eventIndex)`**: Deletes an event.
|
|
111
|
+
- **`loadData(data)`**: Loads tracks and events from a JSON object.
|
|
112
|
+
- **`setZoomLevel(level)`**: Sets the zoom level (1.0 is default).
|
|
113
|
+
- **`setTimeIndicator(seconds)`**: Moves the time indicator to a specific time.
|
|
114
|
+
- **`setTheme('light' | 'dark')`**: Switches between built-in themes.
|
|
115
|
+
|
|
116
|
+
### Plugins
|
|
117
|
+
|
|
118
|
+
The library comes with several built-in plugins:
|
|
119
|
+
|
|
120
|
+
- **`DarkThemePlugin`**: Dark mode theme.
|
|
121
|
+
- **`LightThemePlugin`**: Light mode theme (default).
|
|
122
|
+
- **`ContextMenuPlugin`**: Adds right-click context menu support.
|
|
123
|
+
- **`PerformanceOverlayPlugin`**: Displays FPS and render time for debugging.
|
|
124
|
+
- **`EventMediaPlugin`**: Support for rendering media (images, waveforms) inside events.
|
|
125
|
+
|
|
126
|
+
Usage:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { Timeline, PerformanceOverlayPlugin } from "timeline-canvas";
|
|
130
|
+
|
|
131
|
+
const timeline = new Timeline("canvas-id");
|
|
132
|
+
timeline.usePlugin(new PerformanceOverlayPlugin());
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Development
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Run these from the repo root (monorepo)
|
|
139
|
+
# Install dependencies
|
|
140
|
+
pnpm install
|
|
141
|
+
|
|
142
|
+
# Start development server
|
|
143
|
+
pnpm dev
|
|
144
|
+
|
|
145
|
+
# Build the library
|
|
146
|
+
pnpm build
|
|
147
|
+
|
|
148
|
+
# Run documentation site
|
|
149
|
+
pnpm docs:dev
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## MCP (for VS Code Copilot Chat)
|
|
153
|
+
|
|
154
|
+
This repo includes a minimal MCP server (stdio) so an AI agent can scaffold builtin plugins, wire exports, run basic validation, and trigger a small allowlisted set of pnpm scripts.
|
|
155
|
+
|
|
156
|
+
- Install & start (recommended): `pnpm install` then `pnpm mcp`
|
|
157
|
+
- VS Code sample config: see .vscode/mcp.json
|
|
158
|
+
- Docs: see packages/mcp-service/README.md (or README_CN.md)
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT
|
package/README_CN.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Timeline Canvas
|
|
2
|
+
|
|
3
|
+
一个基于 HTML5 Canvas 和 TypeScript 构建的强大、高性能时间轴组件。
|
|
4
|
+
|
|
5
|
+
[文档地址](https://umbrella22.github.io/timeline-canvas/index.html)
|
|
6
|
+
|
|
7
|
+
## 特性
|
|
8
|
+
|
|
9
|
+
- 🚀 **高性能**: 基于 Canvas API 构建,可流畅渲染大量数据。
|
|
10
|
+
- 🎨 **主题支持**: 内置亮色和暗色主题,支持自定义主题。
|
|
11
|
+
- 🖱️ **交互丰富**:
|
|
12
|
+
- 拖拽移动事件。
|
|
13
|
+
- 从两端调整事件大小。
|
|
14
|
+
- 双击切割事件。
|
|
15
|
+
- 缩放 (Ctrl/Cmd + 滚动) 和平移。
|
|
16
|
+
- 支持右键菜单。
|
|
17
|
+
- 📏 **智能辅助线**: 对齐辅助线和吸附功能,实现精确的事件放置。
|
|
18
|
+
- ⏱️ **时间指示器**: 可拖动的时间头,支持吸附。
|
|
19
|
+
- 🔌 **插件系统**: 可扩展架构,内置主题、右键菜单等插件。
|
|
20
|
+
- 📝 **TypeScript**: 使用 TypeScript 编写,提供完整的类型定义。
|
|
21
|
+
|
|
22
|
+
## 安装
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install timeline-canvas
|
|
26
|
+
# or
|
|
27
|
+
pnpm add timeline-canvas
|
|
28
|
+
# or
|
|
29
|
+
yarn add timeline-canvas
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 基础用法
|
|
33
|
+
|
|
34
|
+
1. 在 HTML 中创建一个包含 canvas 元素的容器:
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<div style="width: 100%; height: 500px;">
|
|
38
|
+
<canvas id="timeline-canvas"></canvas>
|
|
39
|
+
</div>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
1. 初始化 Timeline:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { Timeline } from "timeline-canvas";
|
|
46
|
+
|
|
47
|
+
// 初始化
|
|
48
|
+
const timeline = new Timeline("timeline-canvas", {
|
|
49
|
+
startTime: 0,
|
|
50
|
+
endTime: 100,
|
|
51
|
+
trackHeight: 40,
|
|
52
|
+
// ... 其他选项
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// 添加一个轨道
|
|
56
|
+
timeline.addTrack();
|
|
57
|
+
|
|
58
|
+
// 添加一个事件 (轨道索引, 开始时间, 结束时间, 标题)
|
|
59
|
+
timeline.addEvent(0, 10, 30, "我的事件", "描述信息");
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 配置
|
|
63
|
+
|
|
64
|
+
`Timeline` 构造函数接受一个配置对象:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
interface TimelineOptions {
|
|
68
|
+
// 尺寸设置
|
|
69
|
+
canvasHeight?: number;
|
|
70
|
+
trackHeight?: number;
|
|
71
|
+
trackMargin?: number;
|
|
72
|
+
timelineHeight?: number;
|
|
73
|
+
|
|
74
|
+
// 时间设置
|
|
75
|
+
startTime?: number;
|
|
76
|
+
endTime?: number;
|
|
77
|
+
secondWidth?: number; // 每秒对应的像素宽度
|
|
78
|
+
snapInterval?: number;
|
|
79
|
+
snapToSeconds?: boolean;
|
|
80
|
+
|
|
81
|
+
// 功能开关
|
|
82
|
+
enableTimeIndicator?: boolean;
|
|
83
|
+
enableEventResize?: boolean;
|
|
84
|
+
enableEventSplit?: boolean;
|
|
85
|
+
enableContextMenu?: boolean;
|
|
86
|
+
readOnly?: boolean;
|
|
87
|
+
autoAddTrack?: boolean;
|
|
88
|
+
|
|
89
|
+
// 样式设置
|
|
90
|
+
colors?: Partial<TimelineColors>;
|
|
91
|
+
eventTextStyle?: Partial<EventTextStyle>;
|
|
92
|
+
theme?: TimelinePlugin; // 初始主题
|
|
93
|
+
|
|
94
|
+
// 回调函数
|
|
95
|
+
onEventAdd?: (data: EventAddData) => void;
|
|
96
|
+
onEventUpdate?: (data: EventUpdateData) => void;
|
|
97
|
+
onEventClick?: (data: EventClickData) => void;
|
|
98
|
+
// ... 更多回调
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## API 参考
|
|
103
|
+
|
|
104
|
+
### 核心方法
|
|
105
|
+
|
|
106
|
+
- **`addTrack()`**: 添加一个新的空轨道。
|
|
107
|
+
- **`removeTrack()`**: 移除最后一个轨道。
|
|
108
|
+
- **`addEvent(trackIndex, startTime, endTime, title, ...)`**: 向指定轨道添加事件。
|
|
109
|
+
- **`updateEvent(trackIndex, eventIndex, updates)`**: 更新现有事件。
|
|
110
|
+
- **`deleteEvent(trackIndex, eventIndex)`**: 删除事件。
|
|
111
|
+
- **`loadData(data)`**: 从 JSON 对象加载轨道和事件数据。
|
|
112
|
+
- **`setZoomLevel(level)`**: 设置缩放级别 (默认为 1.0)。
|
|
113
|
+
- **`setTimeIndicator(seconds)`**: 将时间指示器移动到指定时间。
|
|
114
|
+
- **`setTheme('light' | 'dark')`**: 切换内置主题。
|
|
115
|
+
|
|
116
|
+
### 插件
|
|
117
|
+
|
|
118
|
+
本库自带几个内置插件:
|
|
119
|
+
|
|
120
|
+
- **`DarkThemePlugin`**: 暗色模式主题。
|
|
121
|
+
- **`LightThemePlugin`**: 亮色模式主题 (默认)。
|
|
122
|
+
- **`ContextMenuPlugin`**: 添加右键菜单支持。
|
|
123
|
+
- **`PerformanceOverlayPlugin`**: 显示 FPS 和渲染时间,用于调试。
|
|
124
|
+
- **`EventMediaPlugin`**: 支持在事件内渲染媒体内容(图片、波形图)。
|
|
125
|
+
|
|
126
|
+
使用方法:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { Timeline, PerformanceOverlayPlugin } from "timeline-canvas";
|
|
130
|
+
|
|
131
|
+
const timeline = new Timeline("canvas-id");
|
|
132
|
+
timeline.usePlugin(new PerformanceOverlayPlugin());
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## 开发
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# 在仓库根目录执行以下命令(monorepo)
|
|
139
|
+
# 安装依赖
|
|
140
|
+
pnpm install
|
|
141
|
+
|
|
142
|
+
# 启动开发服务器
|
|
143
|
+
pnpm dev
|
|
144
|
+
|
|
145
|
+
# 构建库
|
|
146
|
+
pnpm build
|
|
147
|
+
|
|
148
|
+
# 运行文档站点
|
|
149
|
+
pnpm docs:dev
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## MCP(面向 VS Code Copilot Chat)
|
|
153
|
+
|
|
154
|
+
本仓库提供一个最小可用的 MCP server(stdio),用于让 AI 以“工具调用”的方式完成:生成内置插件骨架、自动挂到导出、做基础校验、以及触发 allowlist 内的仓库脚本。
|
|
155
|
+
|
|
156
|
+
- 安装与启动(推荐):在仓库根目录执行 `pnpm install`,然后 `pnpm mcp`
|
|
157
|
+
- VS Code 配置示例:见 .vscode/mcp.json
|
|
158
|
+
- 说明与工具列表:见 packages/mcp-service/README_CN.md
|
|
159
|
+
|
|
160
|
+
> VS Code / Copilot Chat 的 MCP 配置入口可能随版本变化。核心是把一个 **stdio server** 配置为在 `packages/mcp-service` 目录启动(`pnpm start`),并将工作目录/环境变量指向仓库根目录(见 packages/mcp-service/README_CN.md)。
|
|
161
|
+
|
|
162
|
+
## 许可证
|
|
163
|
+
|
|
164
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e}from"./Logger-Bwd6lZLT.mjs";import{t}from"./types-CkHQNcJ5.mjs";const n=e(`ContextMenuPlugin`);function r(e={}){return{metadata:{name:`context-menu`,version:`1.0.0`,description:`Context menu as plugin, supports HTML takeover`,type:t.EXTENSION},activate(t){let r=t.config&&t.config.contextMenuHtml||void 0,i=e.htmlTemplate||(typeof r==`string`?r:void 0),a=!!i;a&&(!i||i.trim()===``)&&(n.warn(`htmlTemplate is empty, falling back to Canvas rendering`),a=!1),t.api.registerRenderLayer({name:`context-menu-overlay`,position:`overlay`,render(e,n,r,o){if(!r.enableContextMenu||!o.contextMenuVisible||!o.contextMenuEvent){let e=t.api.getData(`contextMenuContainer`)||null;e&&(e.style.display=`none`),o.contextMenuBounds=null;return}let{padding:s,itemHeight:c,borderRadius:l,borderWidth:u,minWidth:d,fontSize:f,fontFamily:p,fontWeight:m}=r.contextMenuStyle;e.save(),e.font=`${m} ${f}px ${p}`;let h=d,g=`${m}-${f}-${p}`,_=t.api.getData(`contextMenuTextWidthCache`)||{},v=_[g]||{};for(let t of r.contextMenuItems){let n=v[t.name],r=n===void 0?e.measureText(t.name).width:n;n===void 0&&(v[t.name]=r),h=Math.max(h,r+s*2)}_[g]=v,t.api.setData(`contextMenuTextWidthCache`,_);let y=h,b=r.contextMenuItems.length*c+s*2,x=t.timeline.getCanvas().getBoundingClientRect(),S=o.contextMenuX,C=o.contextMenuY;if(S+y>x.width&&(S=x.width-y-5),C+b>x.height&&(C=x.height-b-5),o.contextMenuBounds={x:S,y:C,width:y,height:b,itemHeight:c,padding:s},a){let n=t.api.getData(`contextMenuContainer`)||null;if(!n){n=document.createElement(`div`),n.style.position=`absolute`,n.style.zIndex=`1000`,n.style.boxShadow=`0 2px 10px rgba(0,0,0,0.3)`,n.style.border=`${u}px solid ${r.colors.contextMenuBorder}`,n.style.borderRadius=`${l}px`,n.style.font=`${m} ${f}px ${p}`,n.style.background=r.colors.contextMenuBackground,n.style.color=r.colors.contextMenuText;let e=t.timeline.getCanvas().parentElement||document.body;e.style.position=e.style.position||`relative`,e.appendChild(n),t.api.setData(`contextMenuContainer`,n)}if(n.style.display=`block`,n.style.left=`${S}px`,n.style.top=`${C}px`,n.style.width=`${y}px`,n.style.height=`${b}px`,i)n.innerHTML=i;else{let e=``;for(let t=0;t<r.contextMenuItems.length;t++){let n=r.contextMenuItems[t],i=o.hoveredContextMenuItem===t,a=i?r.colors.contextMenuHoverBackground:`transparent`,l=i?r.colors.contextMenuHoverText:r.colors.contextMenuText;e+=`<div style="height:${c}px; padding:${s}px; background:${a}; color:${l}; display:flex; align-items:center;">${n.name}</div>`}n.innerHTML=e}e.restore();return}e.shadowColor=`rgba(0, 0, 0, 0.3)`,e.shadowBlur=10,e.shadowOffsetX=0,e.shadowOffsetY=2,e.fillStyle=r.colors.contextMenuBackground,e.beginPath(),e.roundRect?e.roundRect(S,C,y,b,l):(e.moveTo(S+l,C),e.lineTo(S+y-l,C),e.quadraticCurveTo(S+y,C,S+y,C+l),e.lineTo(S+y,C+b-l),e.quadraticCurveTo(S+y,C+b,S+y-l,C+b),e.lineTo(S+l,C+b),e.quadraticCurveTo(S,C+b,S,C+b-l),e.lineTo(S,C+l),e.quadraticCurveTo(S,C,S+l,C)),e.fill(),e.shadowColor=`transparent`,e.strokeStyle=r.colors.contextMenuBorder,e.lineWidth=u,e.stroke(),e.font=`${m} ${f}px ${p}`;for(let t=0;t<r.contextMenuItems.length;t++){let n=r.contextMenuItems[t],i=C+s+t*c;o.hoveredContextMenuItem===t&&(e.fillStyle=r.colors.contextMenuHoverBackground,e.beginPath(),t===0?e.roundRect?e.roundRect(S+u,i,y-u*2,c,[l-u,l-u,0,0]):e.fillRect(S+u,i,y-u*2,c):t===r.contextMenuItems.length-1&&e.roundRect?e.roundRect(S+u,i,y-u*2,c,[0,0,l-u,l-u]):e.fillRect(S+u,i,y-u*2,c),e.fill()),e.fillStyle=o.hoveredContextMenuItem===t?r.colors.contextMenuHoverText:r.colors.contextMenuText,e.textAlign=`left`,e.textBaseline=`middle`,e.fillText(n.name,S+s,i+c/2)}e.restore()}})},deactivate(e){e.api.unregisterRenderLayer(`context-menu-overlay`);let t=e.api.getData(`contextMenuContainer`)||null;t&&t.parentElement&&t.parentElement.removeChild(t)},destroy(e){let t=e.api.getData(`contextMenuContainer`)||null;t&&t.parentElement&&t.parentElement.removeChild(t)}}}export{r as t};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { t as TimelinePlugin } from "./types-D5-4YwEP.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/builtin/ContextMenuPlugin.d.ts
|
|
4
|
+
interface ContextMenuPluginOptions {
|
|
5
|
+
/** 自定义 HTML 模板字符串。传入此参数将自动启用 HTML 渲染模式 */
|
|
6
|
+
htmlTemplate?: string;
|
|
7
|
+
}
|
|
8
|
+
declare function ContextMenuPlugin(options?: ContextMenuPluginOptions): TimelinePlugin;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { ContextMenuPlugin as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./types-CkHQNcJ5.mjs";const t={canvasBackground:`#1E1E2E`,timelineBackground:`#2D2D3D`,trackBackground:`#2A2A3A`,trackBackgroundSelected:`#3A3A4A`,timelineText:`#CCCCDD`,timelineGrid:`#5A5A7A`,timelineSubGrid:`#3A3A4A`,trackText:`#CCCCDD`,eventColors:[`#FF6B6B`,`#4ECDC4`,`#45B7D1`,`#96CEB4`,`#FECA57`,`#FF9FF3`],eventText:`#FFFFFF`,eventBorder:`#FFFFFF`,eventBorderSelected:`#FFD700`,eventOverlay:`rgba(255, 255, 255, 0.2)`,dragPreviewValid:`rgba(100, 255, 100, 0.5)`,dragPreviewInvalid:`rgba(255, 100, 100, 0.5)`,dragPreviewBorderValid:`#00FF00`,dragPreviewBorderInvalid:`#FF0000`,timeIndicator:`#FF6B6B`,guideLine:`#00D9FF`,guideLineLabel:`#00D9FF`,dragTimeReferenceLine:`#FFD700`,dragTimeReferenceLabel:`#FFD700`,dragTimeReferenceLabelBackground:`rgba(0, 0, 0, 0)`,scrollbarTrack:`rgba(255, 255, 255, 0.6)`,scrollbarHandle:`rgba(150, 150, 150, 0.8)`,scrollbarHandleHover:`rgba(0, 0, 0, 0.85)`,scrollbarHandleHighlight:`rgba(255, 255, 255, 0.3)`,scrollbarBorder:`rgba(255, 255, 255, 0.9)`,contextMenuBackground:`#2D2D3D`,contextMenuBorder:`#5A5A7A`,contextMenuText:`#CCCCDD`,contextMenuHoverBackground:`#3A3A4A`,contextMenuHoverText:`#FFFFFF`,eventDurationLabel:`#FFD700`},n={metadata:{name:`theme-dark`,version:`1.0.0`,description:`Dark theme for timeline`,type:e.THEME},activate(e){e.config.colors={...e.config.colors,...t},e.api.registerRenderLayer({name:`theme-dark-background`,position:`background`,render(e,t,n){e.fillStyle=n.colors.canvasBackground,e.fillRect(0,0,t.width,t.height)}})},deactivate(e){e.api.unregisterRenderLayer(`theme-dark-background`)}};export{n as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./types-CkHQNcJ5.mjs";function t(e,t=!0){let n=Math.round(e),r=Math.floor(n/3600),i=Math.floor(n%3600/60),a=n%60;return t?`${r.toString().padStart(2,`0`)}:${i.toString().padStart(2,`0`)}:${a.toString().padStart(2,`0`)}`:`${r.toString().padStart(2,`0`)}:${i.toString().padStart(2,`0`)}`}function n(){let e=new Date;return e.getHours()*3600+e.getMinutes()*60+e.getSeconds()}function r(e,t,n,r){return!n||e<r?t*60:[{threshold:10,seconds:.5},{threshold:8,seconds:1},{threshold:5,seconds:2},{threshold:3,seconds:5},{threshold:2,seconds:10},{threshold:0,seconds:15}].find(t=>e>=t.threshold)?.seconds??15}function i(e,t){return Math.round(e/t)*t}function a(e,t=3){let n=10**t;return Math.round(e*n)/n}function o(e,n){return`${t(e)} - ${t(n)}`}function s(e){return`持续 ${t(a(e))}`}function c(e,t,n,r,i,a,o=!1){e.beginPath(),e.moveTo(t+a,n),e.lineTo(t+r-a,n),e.arcTo(t+r,n,t+r,n+a,a),e.lineTo(t+r,n+i-a),e.arcTo(t+r,n+i,t+r-a,n+i,a),e.lineTo(t+a,n+i),e.arcTo(t,n+i,t,n+i-a,a),e.lineTo(t,n+a),e.arcTo(t,n,t+a,n,a),e.closePath(),o?e.stroke():e.fill()}function l(e,t,n,r,i,a){return n+(e-t)*r*i-a}const u={canvasBackground:`#1E1E2E`,timelineBackground:`#2D2D3D`,trackBackground:`#2A2A3A`,trackBackgroundSelected:`#3A3A4A`,timelineText:`#CCCCDD`,timelineGrid:`#5A5A7A`,timelineSubGrid:`#3A3A4A`,trackText:`#CCCCDD`,eventColors:[`#FF6B6B`,`#4ECDC4`,`#45B7D1`,`#96CEB4`,`#FECA57`,`#FF9FF3`],eventText:`#FFFFFF`,eventBorder:`#FFFFFF`,eventBorderSelected:`#FFD700`,eventOverlay:`rgba(255, 255, 255, 0.2)`,dragPreviewValid:`rgba(100, 255, 100, 0.5)`,dragPreviewInvalid:`rgba(255, 100, 100, 0.5)`,dragPreviewBorderValid:`#00FF00`,dragPreviewBorderInvalid:`#FF0000`,timeIndicator:`#FF6B6B`,guideLine:`#00D9FF`,guideLineLabel:`#00D9FF`,dragTimeReferenceLine:`#FFD700`,dragTimeReferenceLabel:`#FFD700`,dragTimeReferenceLabelBackground:`rgba(0, 0, 0, 0)`,scrollbarTrack:`rgba(255, 255, 255, 0.6)`,scrollbarHandle:`rgba(150, 150, 150, 0.8)`,scrollbarHandleHover:`rgba(0, 0, 0, 0.85)`,scrollbarHandleHighlight:`rgba(255, 255, 255, 0.3)`,scrollbarBorder:`rgba(255, 255, 255, 0.9)`,contextMenuBackground:`#2D2D3D`,contextMenuBorder:`#5A5A7A`,contextMenuText:`#CCCCDD`,contextMenuHoverBackground:`#3A3A4A`,contextMenuHoverText:`#FFFFFF`,eventDurationLabel:`#FFD700`},d={titleFontSize:`auto`,timeFontSize:`auto`,titleFontFamily:`Arial`,timeFontFamily:`Arial`,titleFontWeight:`bold`,timeFontWeight:`normal`,titleColor:null,timeColor:null,textAlign:`left`,verticalAlign:`middle`,titleOffsetY:0,timeOffsetY:0,showTitle:!0,showTime:!0,minHeightForTitle:40,minHeightForTime:50},f={borderRadius:2,enableSelectionGlow:!1,selectionGlowBlur:10},p=[{type:`edit`,name:`编辑`},{type:`delete`,name:`删除`},{type:`export`,name:`导出`}],m={fontSize:14,fontFamily:`Arial, sans-serif`,fontWeight:`normal`,padding:8,itemHeight:32,borderRadius:6,borderWidth:1,minWidth:120},h={timelineHeight:60,trackHeight:80,trackMargin:10,firstTrackTopMargin:10,secondWidth:100/3600,startTime:0,endTime:86400,startPaddingTime:.5,endPaddingTime:0,autoFitOnInit:!0,minAutoFitZoom:1,maxAutoFitZoom:3,timeUnit:`second`,timeFormat:`24h`,snapInterval:15,snapToSeconds:!0,secondPrecisionZoomThreshold:1.5,timeIndicatorWidth:3,timeIndicatorSnapThreshold:10,timeIndicatorHeadSize:12,timeIndicatorTriangleHeight:8,guideLineSnapThreshold:1,enableTimeIndicator:!0,enableEventResize:!0,enableEventSplit:!0,enableContextMenu:!0,resizeHandleWidth:8,minEventDuration:.25,debug:!1,enablePerformanceMonitor:!1,autoAddTrack:!0,autoRemoveEmptyLastTrack:!0,readOnly:!1,showEventDurationLabel:!0,formatEventDuration:null};function g(e){return{id:e.id,startTime:e.startTime,endTime:e.endTime,duration:e.duration,title:e.title,description:e.description,color:e.color,...e.readonly?{readonly:e.readonly}:{},...e.customData?{customData:{...e.customData}}:{}}}function _(){return{metadata:{name:`event-media`,version:`1.0.0`,description:`Render images and waveforms inside event blocks`,type:e.RENDER},async activate(e){let t=new Map,n=new Map,r=new Map;e.api.setData(`eventMediaImageCache`,t),e.api.setData(`eventMediaImageLoading`,n),e.api.setData(`eventMediaWaveCache`,r);let i=(t,n,r,i,a,o,s,l,u,d)=>{let f=e.api.getData(`eventMediaImageCache`),p=e.api.getData(`eventMediaImageLoading`),m=e.api.getData(`eventMediaWaveCache`),h=r.tracks[i].events[a],g=s+u,_=n.eventBlockStyle.borderRadius;t.save(),_>0?(c(t,o,g,l,d,_),t.clip()):(t.beginPath(),t.rect(o,g,l,d),t.clip());let v=h.media&&h.media.images||[];if(v.length>0&&f&&p)for(let e of v){let n=`${i}_${a}_${e.src}`,r=f.get(n);if(!r&&!p.get(n)){let t=fetch(e.src).then(e=>e.blob()).then(e=>createImageBitmap(e)).then(e=>(f.set(n,e),e)).catch(()=>void 0);p.set(n,t)}if(r=f.get(n),r){let n=e.fit||`cover`,i=e.opacity===void 0?.35:e.opacity,a=l,s=d;if(n!==`stretch`){let e=r.width,t=r.height,i=n===`cover`?Math.max(l/e,d/t):Math.min(l/e,d/t);a=Math.max(1,Math.floor(e*i)),s=Math.max(1,Math.floor(t*i))}let c=o+(l-a)/2,u=g+(d-s)/2,f=t.globalAlpha;t.globalAlpha=i,t.drawImage(r,0,0,r.width,r.height,c,u,a,s),t.globalAlpha=f}}let y=h.media&&h.media.waveform||void 0;if(y){let e=`${i}_${a}_wf`,n=m?m.get(e):void 0;if(!n){let t=y.data;n=Array.isArray(t)?new Float32Array(t):t,m&&m.set(e,n)}let r=y.opacity===void 0?.5:y.opacity,s=t.globalAlpha;t.globalAlpha=r,y.backgroundColor&&(t.fillStyle=y.backgroundColor,t.fillRect(o,g,l,d));let c=g+d/2,u=Math.max(1,Math.floor((d-2)/2));t.strokeStyle=y.color||`#00A0FF`,t.lineWidth=1,t.beginPath();let f=n.length;for(let e=0;e<l;e++){let r=Math.min(f-1,Math.max(0,Math.floor(e/Math.max(1,l-1)*f))),i=Math.max(-1,Math.min(1,n[r])),a=c-i*u,s=c+i*u;t.moveTo(o+e,a),t.lineTo(o+e,s)}t.stroke(),t.globalAlpha=s}t.restore()};e.api.registerEventHandler(`render:event:media`,i),e.api.setData(`eventMediaHandler`,i)},deactivate(e){let t=e.api.getData(`eventMediaHandler`);t&&e.api.unregisterEventHandler(`render:event:media`,t);let n=e.api.getData(`eventMediaImageCache`);n&&n.clear();let r=e.api.getData(`eventMediaImageLoading`);r&&r.clear();let i=e.api.getData(`eventMediaWaveCache`);i&&i.clear()}}}export{i as _,p as a,d as c,a as d,s as f,r as g,n as h,h as i,c as l,o as m,g as n,m as o,t as p,u as r,f as s,_ as t,l as u};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e}from"./Logger-Bwd6lZLT.mjs";import{t}from"./types-CkHQNcJ5.mjs";const n=e(`EventTooltipPlugin`);function r(e={}){let{htmlTemplate:r,showDelay:i=300,maxWidth:a=300,padding:o=8,borderRadius:s=4,backgroundColor:c=`#333`,textColor:l=`#fff`,borderColor:u=`#555`,fontSize:d=12,fontFamily:f=`Arial, sans-serif`}=e,p={visible:!1,title:``,x:0,y:0,trackIndex:-1,eventIndex:-1},m=null,h=null;function g(e,t,n){return e.measureText(t).width>n}return{metadata:{name:`event-tooltip`,version:`1.0.0`,description:`Tooltip plugin for displaying full event title when text is truncated`,type:t.EXTENSION},activate(e){let t=e.timeline.getCanvas(),_=n=>{let r=t.getBoundingClientRect(),a=n.clientX-r.left,o=n.clientY-r.top,s=e.config,c=e.state,l=e.timeline.getEventAtPosition(a,o);if(l){let{trackIndex:n,eventIndex:r}=l,u=c.tracks[n]?.events[r];if(!u){v();return}if(h&&h.trackIndex===n&&h.eventIndex===r&&p.visible){p.x=a,p.y=o,e.timeline.draw();return}h={trackIndex:n,eventIndex:r},m&&=(clearTimeout(m),null);let d=u.duration*s.secondWidth*c.zoomLevel-20,f=t.getContext(`2d`);if(!f)return;let _=s.eventTextStyle,y=_.titleFontSize===`auto`?Math.max(10,Math.min(14,s.trackHeight*.175)):_.titleFontSize;f.font=`${_.titleFontWeight} ${y}px ${_.titleFontFamily}`,g(f,u.title,d)?m=setTimeout(()=>{p={visible:!0,title:u.title,x:a,y:o,trackIndex:n,eventIndex:r},e.timeline.draw()},i):v()}else v()},v=()=>{m&&=(clearTimeout(m),null),h=null,p.visible&&(p.visible=!1,e.timeline.draw())},y=()=>{v()};t.addEventListener(`mousemove`,_),t.addEventListener(`mouseleave`,y),e.api.setData(`tooltipMouseMoveHandler`,_),e.api.setData(`tooltipMouseLeaveHandler`,y),e.api.registerRenderLayer({name:`event-tooltip-overlay`,position:`overlay`,render(t,i,m,h){if(!p.visible||!p.title){let t=e.api.getData(`tooltipContainer`)||null;t&&(t.style.display=`none`);return}let g=e.timeline.getCanvas().getBoundingClientRect(),_=p.x,v=p.y-10;t.save(),t.font=`${d}px ${f}`;let y=p.title.split(``),b=[],x=``;for(let e of y){let n=x+e;t.measureText(n).width>a-o*2?x?(b.push(x),x=e):b.push(e):x=n}x&&b.push(x);let S=0;for(let e of b){let n=t.measureText(e).width;S=Math.max(S,n)}S=Math.min(S+o*2,a);let C=d*1.4,w=b.length*C+o*2;if(v-=w,_+S>g.width&&(_=g.width-S-5),_<5&&(_=5),v<5&&(v=p.y+20),r){let i=r(p.title);if(!i||i.trim()===``)n.warn(`htmlTemplate returned empty content, falling back to Canvas rendering`);else{let n=e.api.getData(`tooltipContainer`)||null;if(!n){n=document.createElement(`div`),n.style.position=`absolute`,n.style.zIndex=`1001`,n.style.pointerEvents=`none`,n.style.boxShadow=`0 2px 8px rgba(0,0,0,0.3)`,n.style.border=`1px solid ${u}`,n.style.borderRadius=`${s}px`,n.style.padding=`${o}px`,n.style.fontSize=`${d}px`,n.style.fontFamily=f,n.style.backgroundColor=c,n.style.color=l,n.style.maxWidth=`${a}px`,n.style.wordWrap=`break-word`,n.style.whiteSpace=`pre-wrap`;let t=e.timeline.getCanvas().parentElement||document.body;t.style.position=t.style.position||`relative`,t.appendChild(n),e.api.setData(`tooltipContainer`,n)}n.style.display=`block`,n.style.left=`${_}px`,n.style.top=`${v}px`,n.innerHTML=i,t.restore();return}}if(t.shadowColor=`rgba(0, 0, 0, 0.3)`,t.shadowBlur=8,t.shadowOffsetX=0,t.shadowOffsetY=2,t.fillStyle=c,t.beginPath(),t.roundRect)t.roundRect(_,v,S,w,s);else{let e=_,n=v,r=S,i=w,a=s;t.moveTo(e+a,n),t.lineTo(e+r-a,n),t.quadraticCurveTo(e+r,n,e+r,n+a),t.lineTo(e+r,n+i-a),t.quadraticCurveTo(e+r,n+i,e+r-a,n+i),t.lineTo(e+a,n+i),t.quadraticCurveTo(e,n+i,e,n+i-a),t.lineTo(e,n+a),t.quadraticCurveTo(e,n,e+a,n)}t.fill(),t.shadowColor=`transparent`,t.shadowBlur=0,t.strokeStyle=u,t.lineWidth=1,t.stroke(),t.fillStyle=l,t.font=`${d}px ${f}`,t.textAlign=`left`,t.textBaseline=`top`;for(let e=0;e<b.length;e++)t.fillText(b[e],_+o,v+o+e*C);t.restore()}})},deactivate(e){let t=e.timeline.getCanvas(),n=e.api.getData(`tooltipMouseMoveHandler`),r=e.api.getData(`tooltipMouseLeaveHandler`);n&&t.removeEventListener(`mousemove`,n),r&&t.removeEventListener(`mouseleave`,r),m&&=(clearTimeout(m),null),e.api.unregisterRenderLayer(`event-tooltip-overlay`);let i=e.api.getData(`tooltipContainer`)||null;i&&i.parentElement&&i.parentElement.removeChild(i)},destroy(e){let t=e.api.getData(`tooltipContainer`)||null;t&&t.parentElement&&t.parentElement.removeChild(t),m&&=(clearTimeout(m),null)}}}export{r as t};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { t as TimelinePlugin } from "./types-D5-4YwEP.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/plugins/builtin/EventTooltipPlugin.d.ts
|
|
4
|
+
interface EventTooltipPluginOptions {
|
|
5
|
+
/** 自定义 HTML 模板函数,接收事件标题,返回 HTML 字符串。传入此参数将自动启用 HTML 渲染模式 */
|
|
6
|
+
htmlTemplate?: (title: string) => string;
|
|
7
|
+
/** tooltip 显示延迟(毫秒),默认 300 */
|
|
8
|
+
showDelay?: number;
|
|
9
|
+
/** tooltip 最大宽度,默认 300 */
|
|
10
|
+
maxWidth?: number;
|
|
11
|
+
/** tooltip 内边距,默认 8 */
|
|
12
|
+
padding?: number;
|
|
13
|
+
/** tooltip 圆角,默认 4 */
|
|
14
|
+
borderRadius?: number;
|
|
15
|
+
/** tooltip 背景色,默认 '#333' */
|
|
16
|
+
backgroundColor?: string;
|
|
17
|
+
/** tooltip 文字颜色,默认 '#fff' */
|
|
18
|
+
textColor?: string;
|
|
19
|
+
/** tooltip 边框颜色,默认 '#555' */
|
|
20
|
+
borderColor?: string;
|
|
21
|
+
/** tooltip 字体大小,默认 12 */
|
|
22
|
+
fontSize?: number;
|
|
23
|
+
/** tooltip 字体,默认 'Arial, sans-serif' */
|
|
24
|
+
fontFamily?: string;
|
|
25
|
+
}
|
|
26
|
+
declare function EventTooltipPlugin(options?: EventTooltipPluginOptions): TimelinePlugin;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { EventTooltipPlugin as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./types-CkHQNcJ5.mjs";const t={canvasBackground:`#FFFFFF`,timelineBackground:`#FFFFFF`,trackBackground:`#FFFFFF`,trackBackgroundSelected:`rgba(63, 118, 252, 0.1)`,trackBackgroundOdd:`#FFFFFF`,trackBackgroundEven:`#F9FAFD`,timelineText:`#969BA5`,timelineGrid:`#E5E5E5`,timelineSubGrid:`#fff`,trackText:`#CCCCDD`,eventColors:[`rgba(63, 118, 252, 0.16)`],eventText:`#FFFFFF`,eventBorder:`#FFFFFF`,eventBorderSelected:`#3F76FC`,eventOverlay:`rgba(255, 255, 255, 0.2)`,dragPreviewValid:`rgba(100, 255, 100, 0.5)`,dragPreviewInvalid:`rgba(255, 100, 100, 0.5)`,dragPreviewBorderValid:`#00FF00`,dragPreviewBorderInvalid:`#FF0000`,timeIndicator:`#3F76FC`,guideLine:`#00D9FF`,guideLineLabel:`#00D9FF`,dragTimeReferenceLine:`#FFD700`,dragTimeReferenceLabel:`#FFD700`,dragTimeReferenceLabelBackground:`rgba(0, 0, 0, 0)`,scrollbarTrack:`rgba(63, 118, 252, 0.08)`,scrollbarHandle:`rgba(63, 118, 252, 0.5)`,scrollbarHandleHover:`rgba(63, 118, 252, 0.8)`,scrollbarHandleHighlight:`rgba(63, 118, 252, 0.12)`,scrollbarBorder:`rgba(63, 118, 252, 0.6)`,contextMenuBackground:`#2D2D3D`,contextMenuBorder:`#5A5A7A`,contextMenuText:`#CCCCDD`,contextMenuHoverBackground:`#4a00e0`,contextMenuHoverText:`#FFFFFF`,eventDurationLabel:`#3F76FC`},n={metadata:{name:`theme-light`,version:`1.0.0`,description:`Light theme for timeline`,type:e.THEME},activate(e){e.config.colors={...e.config.colors,...t},e.api.registerRenderLayer({name:`theme-light-background`,position:`background`,render(e,t,n){e.fillStyle=n.colors.canvasBackground,e.fillRect(0,0,t.width,t.height)}})},deactivate(e){e.api.unregisterRenderLayer(`theme-light-background`)}};export{n as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e={pipeline:`color: #2196F3; font-weight: bold;`,pipelineLayer:`color: #64B5F6;`,pipelineSkip:`color: #90A4AE;`,stateMachine:`color: #4CAF50; font-weight: bold;`,stateTransition:`color: #81C784;`,stateEnter:`color: #A5D6A7;`,stateExit:`color: #C8E6C9;`,eventRender:`color: #FF9800; font-weight: bold;`,eventInfo:`color: #FFB74D;`,eventSkip:`color: #FFCC80;`,dataUpdate:`color: #9C27B0; font-weight: bold;`,dataInfo:`color: #BA68C8;`,scheduler:`color: #00BCD4; font-weight: bold;`,schedulerInfo:`color: #4DD0E1;`,plugin:`color: #E91E63; font-weight: bold;`,pluginInfo:`color: #F48FB1;`,reset:`color: inherit; font-weight: normal;`},t={enabled:!0,level:`info`},n=new Map;var r=class{constructor(e){this.enabled=e?.enabled??!0,this.level=e?.level??`info`,this.prefix=e?.prefix??`Timeline`,this.useGlobalConfig=e?.useGlobalConfig??!0}setEnabled(e){this.enabled=e}setLevel(e){this.level=e}setPrefix(e){this.prefix=e}rank(e){switch(e){case`debug`:return 10;case`info`:return 20;case`warn`:return 30;case`error`:return 40}}shouldLog(e){return this.useGlobalConfig?t.enabled?this.rank(e)>=this.rank(t.level):!1:this.enabled&&this.rank(e)>=this.rank(this.level)}debug(...e){this.shouldLog(`debug`)&&console.debug(`[${this.prefix}]`,...e)}debugStyled(e,t,...n){this.shouldLog(`debug`)&&console.debug(`%c[${this.prefix}] ${t}`,e,...n)}info(...e){this.shouldLog(`info`)&&console.info(`[${this.prefix}]`,...e)}warn(...e){this.shouldLog(`warn`)&&console.warn(`[${this.prefix}]`,...e)}error(...e){this.shouldLog(`error`)&&console.error(`[${this.prefix}]`,...e)}};function i(e){let t=n.get(e);return t||(t=new r({prefix:e,useGlobalConfig:!0}),n.set(e,t)),t}function a(e){e.enabled!==void 0&&(t.enabled=e.enabled),e.level!==void 0&&(t.level=e.level)}export{i,r as n,a as r,e as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./performanceMonitor-Cf-Ah4F7.mjs";import{t}from"./types-CkHQNcJ5.mjs";const n={metadata:{name:`performance-overlay`,version:`1.0.0`,description:`Draw performance metrics overlay`,type:t.TOOL},activate(t){let n=new e(t.config.enablePerformanceMonitor||t.config.debug);t.api.setPerformanceProvider(n),t.api.setData(`perfMonitor`,n),t.api.setData(`perfOverlayPos`,{x:10,y:10}),t.api.setData(`perfOverlayDragging`,!1),t.api.setData(`perfOverlayOffset`,{x:0,y:0});let r=t.timeline.getCanvas(),i=e=>{let n=r.getBoundingClientRect(),i=e.clientX-n.left,a=e.clientY-n.top,o=t.api.getData(`perfOverlaySize`),s=t.api.getData(`perfOverlayPos`)||{x:10,y:10};o&&i>=s.x&&i<=s.x+o.width&&a>=s.y&&a<=s.y+o.height&&(t.api.setData(`perfOverlayDragging`,!0),t.api.setData(`perfOverlayOffset`,{x:i-s.x,y:a-s.y}),e.stopPropagation(),e.preventDefault())},a=e=>{if(!t.api.getData(`perfOverlayDragging`))return;let n=r.getBoundingClientRect(),i=e.clientX-n.left,a=e.clientY-n.top,o=t.api.getData(`perfOverlayOffset`)||{x:0,y:0},s=t.api.getData(`perfOverlaySize`)||{width:0,height:0},c=i-o.x,l=a-o.y;c=Math.max(0,Math.min(n.width-s.width,c)),l=Math.max(0,Math.min(n.height-s.height,l)),t.api.setData(`perfOverlayPos`,{x:c,y:l}),t.timeline.draw(),e.stopPropagation(),e.preventDefault()},o=e=>{t.api.getData(`perfOverlayDragging`)&&t.api.setData(`perfOverlayDragging`,!1)};r.addEventListener(`mousedown`,i,{capture:!0}),r.addEventListener(`mousemove`,a,{capture:!0}),window.addEventListener(`mouseup`,o,{capture:!0}),t.api.setData(`perfOverlayListeners`,{onMouseDown:i,onMouseMove:a,onMouseUp:o}),t.api.registerRenderLayer({name:`performance-overlay`,position:`overlay`,render(e){let n=t.api.getData(`perfMonitor`),r=!!(t.config.enablePerformanceMonitor||t.config.debug);n&&(r?n.enable():n.disable());let i=t.api.getPerformanceStats();if(i.size===0)return;let a=t.api.getFPS(),o=Array.from(i.entries()),s=[`background`,`tracks`,`timeline`,`interaction`,`guideLines`,`scrollbar`,`overlay`,`dragPreview`],c=t.timeline.getLastLayerTimes?t.timeline.getLastLayerTimes():void 0,l=c?s.filter(e=>c[e]!==void 0).length:0,u=c?1+l:0,d=25+(1+o.length+u)*20+30,f=t.api.getData(`perfOverlayPos`)||{x:10,y:10};t.api.setData(`perfOverlaySize`,{width:280,height:d}),e.fillStyle=`rgba(0, 0, 0, 0.8)`,e.fillRect(f.x,f.y,280,d),e.strokeStyle=`rgba(100, 255, 100, 0.6)`,e.lineWidth=2,e.strokeRect(f.x,f.y,280,d),e.fillStyle=`#00FF00`,e.font=`bold 16px monospace`,e.textAlign=`left`,e.fillText(`性能监控报告`,f.x+10,f.y+20);let p=f.y+20+25;if(e.fillStyle=a>=55?`#00FF00`:a>=30?`#FFFF00`:`#FF0000`,e.font=`bold 14px monospace`,e.fillText(`FPS: ${a.toFixed(1)}`,f.x+10,p),e.font=`12px monospace`,p+=20,c){e.fillStyle=`#00FFFF`,e.font=`bold 12px monospace`,e.fillText(`Layer Times (ms):`,f.x+10,p),p+=20,e.font=`12px monospace`,e.fillStyle=`#FFFFFF`;for(let t of s)c[t]!==void 0&&(e.fillText(`${t}: ${c[t].toFixed(2)}`,f.x+10,p),p+=20)}o.forEach(([t,n])=>{let r=`#00FF00`;n.average>16&&(r=`#FFFF00`),n.average>33&&(r=`#FF0000`),e.fillStyle=r;let i=`${t}: ${n.average.toFixed(2)}ms (${n.min.toFixed(1)}-${n.max.toFixed(1)})`;e.fillText(i,f.x+10,p),p+=20})}})},deactivate(e){e.api.unregisterRenderLayer(`performance-overlay`);let t=e.api.getData(`perfOverlayListeners`),n=e.timeline.getCanvas();t&&(n.removeEventListener(`mousedown`,t.onMouseDown,!0),n.removeEventListener(`mousemove`,t.onMouseMove,!0),window.removeEventListener(`mouseup`,t.onMouseUp,!0))}};export{n as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../Logger-Bwd6lZLT.mjs";import"../types-CkHQNcJ5.mjs";import{t as e}from"../ContextMenuPlugin-B9TmnnaU.mjs";export{e as ContextMenuPlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../types-CkHQNcJ5.mjs";import{t as e}from"../DarkThemePlugin-CRFdrOR3.mjs";export{e as DarkTheme,e as DarkThemePlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"../EventMediaPlugin-DPPdLbey.mjs";import"../performanceMonitor-Cf-Ah4F7.mjs";import"../types-CkHQNcJ5.mjs";export{e as EventMediaPlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../Logger-Bwd6lZLT.mjs";import"../types-CkHQNcJ5.mjs";import{t as e}from"../EventTooltipPlugin-Ce6xChyf.mjs";export{e as EventTooltipPlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../types-CkHQNcJ5.mjs";import{t as e}from"../LightThemePlugin-BOreTGti.mjs";export{e as LightTheme,e as LightThemePlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"../types-CkHQNcJ5.mjs";function t(){return{metadata:{name:`MutexGuardPlugin`,version:`1.0.0`,description:`Disallow parallel existence of mutex-tagged events across tracks`,type:e.EXTENSION},activate(e){e.api.registerEventHandler(`validate:event:move`,t=>{let{fromTrackIndex:n,fromEventIndex:r,newStartTime:i,duration:a}=t,o=e.state,s=i+a,c=o.tracks[n]?.events[r];if(!c)return!0;let l=Array.isArray(c.customData?.mutex)?c.customData.mutex:[];if(l.length===0)return!0;for(let e=0;e<o.tracks.length;e++){let t=o.tracks[e];for(let a=0;a<t.events.length;a++){if(e===n&&a===r)continue;let o=t.events[a],c=Array.isArray(o.customData?.mutex)?o.customData.mutex:[];if(c.length!==0&&l.some(e=>c.includes(e))&&!(s<=o.startTime||i>=o.endTime))return!1}}return!0})}}}export{t as MutexGuardPlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../performanceMonitor-Cf-Ah4F7.mjs";import"../types-CkHQNcJ5.mjs";import{t as e}from"../PerformanceOverlayPlugin-Bx-DkYbW.mjs";export{e as PerformanceOverlayPlugin};
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { C as ZoomData, S as Track, _ as TimelineColors, a as ContextMenuItem, b as TimelineOptions, c as EventClickData, d as EventMoveData, f as EventTextStyle, g as TimelineCallbacks, h as TimeIndicatorMoveData, i as ContextMenuData, l as EventDeleteData, m as LoadDataFormat, n as Timeline, o as ContextMenuStyle, p as EventUpdateData, r as ChangeType, s as EventAddData, u as EventEditData, v as TimelineConfig, x as TimelineState, y as TimelineEvent } from "./types-D5-4YwEP.mjs";
|
|
2
|
+
import { t as ContextMenuPlugin } from "./ContextMenuPlugin-Crk3ma0O.mjs";
|
|
3
|
+
import { t as DarkThemePlugin } from "./DarkThemePlugin-IbJNx65n.mjs";
|
|
4
|
+
import { t as EventMediaPlugin } from "./EventMediaPlugin-daiUXxsT.mjs";
|
|
5
|
+
import { t as EventTooltipPlugin } from "./EventTooltipPlugin-b5fqBb8j.mjs";
|
|
6
|
+
import { t as LightThemePlugin } from "./LightThemePlugin-DrdhIHgA.mjs";
|
|
7
|
+
import { t as PerformanceOverlayPlugin } from "./PerformanceOverlayPlugin-BFU4Le2k.mjs";
|
|
8
|
+
|
|
9
|
+
//#region src/utils/time.d.ts
|
|
10
|
+
declare function formatTime(seconds: number, showSeconds?: boolean): string;
|
|
11
|
+
declare function getCurrentTime(): number;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { type ChangeType, type ContextMenuData, type ContextMenuItem, ContextMenuPlugin, type ContextMenuStyle, DarkThemePlugin, type EventAddData, type EventClickData, type EventDeleteData, type EventEditData, EventMediaPlugin, type EventMoveData, type EventTextStyle, EventTooltipPlugin, type EventUpdateData, LightThemePlugin, type LoadDataFormat, PerformanceOverlayPlugin, type TimeIndicatorMoveData, Timeline, type TimelineCallbacks, type TimelineColors, type TimelineConfig, type TimelineEvent, type TimelineOptions, type TimelineState, type Track, type ZoomData, formatTime, getCurrentTime };
|