# Canvas Oscilloscope Simulator

基于 HTML5 Canvas 的示波器模拟器，具备响应式渲染、可定制波形和实时可视化等功能。

## 目录
- [功能特性](#功能特性)
- [安装](#安装)
- [快速开始](#快速开始)
- [API 文档](#api-文档)
  - [Oscilloscope 类](#oscilloscope-类)
    - [构造函数](#构造函数)
    - [主要方法](#主要方法)
  - [类型定义](#类型定义)
- [波形绘制示例](#波形绘制示例)
  - [正弦波](#正弦波)
  - [方波](#方波)
  - [三角波](#三角波)
  - [单极性脉冲波](#单极性脉冲波)
  - [双极性脉冲波](#双极性脉冲波)
  - [频率扫描正弦波](#频率扫描正弦波)
- [配置选项](#配置选项)
- [开发指南](#开发指南)
  - [构建项目](#构建项目)
  - [开发模式](#开发模式)
  - [测试](#测试)
- [贡献指南](#贡献指南)
- [许可证](#许可证)

## 功能特性
- **高性能渲染**：完全基于 HTML5 Canvas 实现，确保流畅的实时可视化。
- **响应式设计**：自动调整视图端口以适应不同屏幕尺寸。
- **可定制波形**：支持自定义波形采样函数，也提供多种预设波形。
- **精确的坐标轴系统**：带有网格和刻度标签，支持时间轴和幅度轴自定义分割。
- **TypeScript 支持**：使用 TypeScript 编写，提供类型定义文件。

## 安装
```bash
npm install canvas-oscilloscope
```

使用 yarn 安装：
```bash
yarn add canvas-oscilloscope
```

## 快速开始
```typescript
import Oscilloscope from 'canvas-oscilloscope';

// 通过 ID 获取 canvas 元素
const oscilloscope = new Oscilloscope('my-canvas');

// 绘制默认正弦波
oscilloscope.drawSinWave(1000, 1000); // 峰峰值 1000mV，周期 1000ns
```

## API 文档

### Oscilloscope 类

#### 构造函数
```typescript
new Oscilloscope(
  canvasElementOrId: HTMLCanvasElement | string,
  timeAxisDivisions?: number,
  amplitudeAxisDivisions?: number
);
```

- `canvasElementOrId`：可以是 `HTMLCanvasElement` 对象，也可以是 canvas 元素的 ID 字符串。
- `timeAxisDivisions`：时间轴分割数，默认值为 14。
- `amplitudeAxisDivisions`：幅度轴分割数，默认值为 10。

#### 主要方法

| 方法名 | 描述 | 参数 |
| --- | --- | --- |
| `drawWaveform` | 绘制自定义波形，经过防抖处理 | `peakAmplitude`（可选，峰值电压，单位：mV），`waveformPeriod`（可选，波形周期，单位：ns），`waveformSampler`（可选，波形采样函数） |
| `drawSinWave` | 绘制正弦波形 | `peakToPeak`（峰峰值电压，单位：mV），`waveformPeriod`（波形周期，单位：ns） |
| `drawSineScanWave` | 绘制频率扫描正弦波 | `peakToPeak`（峰峰值电压，单位：mV），`startFreq`（起始频率，单位：Hz），`endFreq`（结束频率，单位：Hz） |
| `drawPulseWave` | 绘制单极性脉冲波形 | `peakToPeak`（峰峰值电压，单位：mV），`waveformPeriod`（波形周期，单位：ns），`pulseWidth`（脉冲宽度，单位：ns） |
| `drawBipolarPulse` | 绘制双极性脉冲波形 | `peakToPeak`（峰峰值电压，单位：mV），`waveformPeriod`（波形周期，单位：ns），`pulseWidth`（脉冲宽度，单位：ns） |
| `drawTriangleWave` | 绘制三角波形 | `peakToPeak`（峰峰值电压，单位：mV），`waveformPeriod`（波形周期，单位：ns），`pulseWidth`（上升沿时间，单位：ns） |
| `dispose` | 销毁示波器实例相关资源，断开 `ResizeObserver` 监听并清空绘图上下文 | 无 |

### 类型定义

#### Options 接口
```typescript
interface Options {
  gridColor: string;    // 网格线颜色 (默认: "#e0e0e0")
  axisColor: string;    // 坐标轴颜色 (默认: "#607D8B")
  waveColor: string;    // 波形颜色 (默认: "#2196F3")
  textColor: string;    // 文本颜色 (默认: "#455A64")
  fontSize: string;      // 字体大小 (默认: "12px")
  fontFamily: string;   // 字体类型 (默认: "sans-serif")
  timeAxisDivisions: number;    // 时间轴分割数 (默认: 14)
  amplitudeAxisDivisions: number; // 幅度轴分割数 (默认: 10)
  padding: {            // 画布内边距（像素）
    top: number;        // 上边距 (默认: 40)
    left: number;       // 左边距 (默认: 60)
    right: number;      // 右边距 (默认: 20)
    bottom: number;     // 下边距 (默认: 40)
  };
}
```

#### ClientArea 接口
```typescript
interface ClientArea {
  top: number;          // 可用区域顶部坐标
  left: number;         // 可用区域左侧坐标
  right: number;        // 可用区域右侧坐标
  bottom: number;       // 可用区域底部坐标
  clientWidth: number;  // 可用区域宽度（像素）
  clientHeight: number; // 可用区域高度（像素）
  centerX: number;      // 水平中心点坐标 (left + clientWidth/2)
  centerY: number;      // 垂直中心点坐标 (top + clientHeight/2)
}
```

#### WaveformSampler 类型
```typescript
/**
 * 波形采样函数类型定义，用于生成示波器显示的波形数据。
 * 该函数会在绘制波形的每个像素位置被调用，根据传入的参数计算对应位置的电压值。
 * 
 * @param period - 波形的周期，单位为纳秒 (ns)。表示波形完成一个完整循环所需的时间。
 * @param periodOffset - 当前时间点在一个周期内的偏移量，单位为纳秒 (ns)。取值范围为 `[0, period)`。
 * @param timeOffset - 总时间偏移量，单位为纳秒 (ns)。表示从波形起始点开始的绝对时间。
 * @param progress - 当前像素在绘制区域的水平进度，取值范围为 `[0, 1]`。0 表示绘制区域的最左侧，1 表示最右侧。
 * @returns 当前位置对应的电压值，单位为毫伏 (mV)。该值将用于确定波形在垂直方向上的位置。
 */
type WaveformSampler = (period: number, periodOffset: number, timeOffset: number, progress: number) => number;
```

## 波形绘制示例

### 正弦波
```typescript
// 绘制峰峰值 1000mV，周期 1000ns 的正弦波
oscilloscope.drawSinWave(1000, 1000);
```

### 方波
```typescript
function getWaveformSampler(period:number,amp:number):WaveformSampler{
  const halfPeriod = period / 2;
  const halfAmp = amp / 2;
  return(period, periodOffset, time) => periodOffset < halfPeriod ? halfAmp : -halfAmp;
}
oscilloscope.drawWaveform(1000/2, 1000, getWaveformSampler(1000,1000));
```

### 三角波
```typescript
// 绘制峰峰值 1000mV，周期 1000ns，上升沿时间 300ns 的三角波
oscilloscope.drawTriangleWave(1000, 1000, 300);
```

### 单极性脉冲波
```typescript
// 绘制峰峰值 1000mV，周期 1000ns，脉冲宽度 200ns 的单极性脉冲波
oscilloscope.drawPulseWave(1000, 1000, 200);
```

### 双极性脉冲波
```typescript
// 绘制峰峰值 1000mV，周期 1000ns，脉冲宽度 200ns 的双极性脉冲波
oscilloscope.drawBipolarPulse(1000, 1000, 200);
```

### 频率扫描正弦波
```typescript
// 绘制峰峰值 1000mV，起始频率 1MHz，结束频率 10MHz 的频率扫描正弦波
oscilloscope.drawSineScanWave(1000, 1e6, 10e6);
```

## 配置选项
可以通过 HTML 属性对示波器的样式进行配置：
```html
<canvas 
  id="my-canvas"
  grid-color="#e0e0e0"
  axis-color="#607D8B"
  wave-color="#2196F3"
  text-color="#455A64">
</canvas>
```
各属性含义如下：
- `grid-color`：网格线颜色。
- `axis-color`：坐标轴颜色。
- `wave-color`：波形颜色。
- `text-color`：文本颜色。

## 开发指南

### 构建项目
```bash
npm run build
```

### 开发模式
```bash
npm run watch
```

## 贡献指南
欢迎提交 Pull Request。在提交前请确保：
1. 更新相关文档。
2. 遵循现有代码风格。

## 许可证
本项目采用 [MIT 许可证](https://opensource.org/licenses/MIT)。