# Canvas Oscilloscope Simulator

An oscilloscope simulator based on HTML5 Canvas, featuring responsive rendering, customizable waveforms, and real - time visualization.

## Table of Contents
- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
- [API Documentation](#api-documentation)
  - [Oscilloscope Class](#oscilloscope-class)
    - [Constructor](#constructor)
    - [Main Methods](#main-methods)
  - [Type Definitions](#type-definitions)
- [Waveform Drawing Examples](#waveform-drawing-examples)
  - [Sine Wave](#sine-wave)
  - [Square Wave](#square-wave)
  - [Triangle Wave](#triangle-wave)
  - [Unipolar Pulse Wave](#unipolar-pulse-wave)
  - [Bipolar Pulse Wave](#bipolar-pulse-wave)
  - [Frequency - Swept Sine Wave](#frequency-swept-sine-wave)
- [Configuration Options](#configuration-options)
- [Development Guide](#development-guide)
  - [Build the Project](#build-the-project)
  - [Development Mode](#development-mode)
  - [Testing](#testing)
- [Contribution Guide](#contribution-guide)
- [License](#license)

## Features
- **High - Performance Rendering**: Fully implemented using HTML5 Canvas to ensure smooth real - time visualization.
- **Responsive Design**: Automatically adjusts the viewport to fit different screen sizes.
- **Customizable Waveforms**: Supports custom waveform sampling functions and provides a variety of preset waveforms.
- **Accurate Axis System**: Comes with grids and scale labels, supporting custom division of the time and amplitude axes.
- **TypeScript Support**: Written in TypeScript, providing type definition files.

## Installation
```:bash
npm install canvas-oscilloscope
```

Install using yarn:
```:bash
yarn add canvas-oscilloscope
```

## Quick Start
```:typescript
import Oscilloscope from 'canvas-oscilloscope';

// Get the canvas element by ID
const oscilloscope = new Oscilloscope('my-canvas');

// Draw a default sine wave
oscilloscope.drawSinWave(1000, 1000); // Peak - to - peak voltage 1000mV, period 1000ns
```

## API Documentation

### Oscilloscope Class

#### Constructor
```:typescript
new Oscilloscope(
  canvasElementOrId: HTMLCanvasElement | string,
  timeAxisDivisions?: number,
  amplitudeAxisDivisions?: number
);
```

- `canvasElementOrId`: Can be an `HTMLCanvasElement` object or a string representing the ID of the canvas element.
- `timeAxisDivisions`: Number of divisions on the time axis, with a default value of 14.
- `amplitudeAxisDivisions`: Number of divisions on the amplitude axis, with a default value of 10.

#### Main Methods

| Method Name | Description | Parameters |
| --- | --- | --- |
| `drawWaveform` | Draws a custom waveform with debounce processing | `peakAmplitude` (optional, peak voltage, unit: mV), `waveformPeriod` (optional, waveform period, unit: ns), `waveformSampler` (optional, waveform sampling function) |
| `drawSinWave` | Draws a sine waveform | `peakToPeak` (peak - to - peak voltage, unit: mV), `waveformPeriod` (waveform period, unit: ns) |
| `drawSineSweepWave` | Draws a frequency - swept sine wave | `peakToPeak` (peak - to - peak voltage, unit: mV), `startFreq` (starting frequency, unit: Hz), `endFreq` (ending frequency, unit: Hz),`bidirectional`(Whether to perform bidirectional scanning.) |
| `drawPulseWave` | Draws a unipolar pulse waveform | `peakToPeak` (peak - to - peak voltage, unit: mV), `waveformPeriod` (waveform period, unit: ns), `pulseWidth` (pulse width, unit: ns) |
| `drawBipolarPulse` | Draws a bipolar pulse waveform | `peakToPeak` (peak - to - peak voltage, unit: mV), `waveformPeriod` (waveform period, unit: ns), `pulseWidth` (pulse width, unit: ns) |
| `drawTriangleWave` | Draws a triangle waveform | `peakToPeak` (peak - to - peak voltage, unit: mV), `waveformPeriod` (waveform period, unit: ns), `pulseWidth` (rise time, unit: ns) |
| `dispose` | Destroys the resources related to the oscilloscope instance, disconnects the `ResizeObserver` listener, and clears the drawing context | None |

### Type Definitions

#### Options Interface
```:typescript
interface Options {
  gridColor: string;    // Grid line color (default: "#e0e0e0")
  axisColor: string;    // Axis color (default: "#607D8B")
  waveColor: string;    // Waveform color (default: "#2196F3")
  textColor: string;    // Text color (default: "#455A64")
  fontSize: string;      // Font size (default: "12px")
  fontFamily: string;   // Font family (default: "sans-serif")
  timeAxisDivisions: number;    // Number of divisions on the time axis (default: 14)
  amplitudeAxisDivisions: number; // Number of divisions on the amplitude axis (default: 10)
  padding: {            // Canvas padding (in pixels)
    top: number;        // Top padding (default: 40)
    left: number;       // Left padding (default: 60)
    right: number;      // Right padding (default: 20)
    bottom: number;     // Bottom padding (default: 40)
  };
}
```

#### ClientArea Interface
```:typescript
interface ClientArea {
  top: number;          // Top coordinate of the available area
  left: number;         // Left coordinate of the available area
  right: number;        // Right coordinate of the available area
  bottom: number;       // Bottom coordinate of the available area
  clientWidth: number;  // Width of the available area (in pixels)
  clientHeight: number; // Height of the available area (in pixels)
  centerX: number;      // Horizontal center point coordinate (left + clientWidth/2)
  centerY: number;      // Vertical center point coordinate (top + clientHeight/2)
}
```

#### WaveformSampler Type
```:typescript
/**
 * Type definition for the waveform sampling function, used to generate waveform data displayed on the oscilloscope.
 * This function will be called at each pixel position when drawing the waveform, and calculates the voltage value at the corresponding position based on the input parameters.
 * 
 * @param period - The period of the waveform, in nanoseconds (ns). Represents the time required for the waveform to complete one full cycle.
 * @param periodOffset - The offset of the current time point within one period, in nanoseconds (ns). The value range is `[0, period)`.
 * @param timeOffset - The total time offset, in nanoseconds (ns). Represents the absolute time from the start point of the waveform.
 * @param progress - The horizontal progress of the current pixel in the drawing area, with a value range of `[0, 1]`. 0 represents the leftmost side of the drawing area, and 1 represents the rightmost side.
 * @returns The voltage value at the current position, in millivolts (mV). This value will be used to determine the vertical position of the waveform.
 */
type WaveformSampler = (period: number, periodOffset: number, timeOffset: number, progress: number) => number;
```

## Waveform Drawing Examples

### Sine Wave
```:typescript
// Draw a sine wave with a peak - to - peak voltage of 1000mV and a period of 1000ns
oscilloscope.drawSinWave(1000, 1000);
```

### Square Wave
```: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));
```

### Triangle Wave
```:typescript
// Draw a triangle wave with a peak - to - peak voltage of 1000mV, a period of 1000ns, and a rise time of 300ns
oscilloscope.drawTriangleWave(1000, 1000, 300);
```

### Unipolar Pulse Wave
```:typescript
// Draw a unipolar pulse wave with a peak - to - peak voltage of 1000mV, a period of 1000ns, and a pulse width of 200ns
oscilloscope.drawPulseWave(1000, 1000, 200);
```

### Bipolar Pulse Wave
```:typescript
// Draw a bipolar pulse wave with a peak - to - peak voltage of 1000mV, a period of 1000ns, and a pulse width of 200ns
oscilloscope.drawBipolarPulse(1000, 1000, 200);
```

### Frequency - Swept Sine Wave
```:typescript
// Draw a frequency - swept sine wave with a peak - to - peak voltage of 1000mV, a starting frequency of 1MHz, and an ending frequency of 10MHz
oscilloscope.drawSineScanWave(1000, 1e6, 10e6);
```

## Configuration Options
You can configure the style of the oscilloscope through HTML attributes:
```:html
<canvas 
  id="my-canvas"
  grid-color="#e0e0e0"
  axis-color="#607D8B"
  wave-color="#2196F3"
  text-color="#455A64">
</canvas>
```

The meanings of each attribute are as follows:
- `grid-color`: Grid line color.
- `axis-color`: Axis color.
- `wave-color`: Waveform color.
- `text-color`: Text color.

## Development Guide

### Build the Project
```:bash
npm run build
```

### Development Mode
```:bash
npm run watch
```

## Contribution Guide
We welcome you to submit Pull Requests. Before submitting, please ensure that:
1. Update the relevant documentation.
2. Follow the existing code style.

## License
This project is licensed under the [MIT License](https://opensource.org/licenses/MIT).