canvas-oscilloscope
Version:
HTML5 Canvas oscilloscope simulator with responsive rendering, customizable waveforms, and real-time visualization capabilities.
167 lines (166 loc) • 9.04 kB
TypeScript
/**
* HTML5 Canvas-based oscilloscope simulator with responsive rendering,
* customizable waveforms, and real-time visualization capabilities.
*
* Features automatic viewport adjustment, debounced rendering optimization,
* and configurable grid/waveform styling through HTML attributes.
*/
/**
* 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.
*/
export type WaveformSampler = (period: number, periodOffset: number, timeOffset: number, progress: number) => number;
declare class Oscilloscope {
private static readonly DefaultPeakVoltage;
private static readonly DefaultPeriod;
private static readonly MinCanvasSize;
private static readonly PI2;
private observer;
private canvas;
private ctx;
private options;
private clientArea;
private targetCanvas?;
private targetCtx?;
/**
* A static private method to implement the debounce function. Debounce means that if the same event is triggered multiple times within a certain period, only the last operation will be executed.
* @typeParam T - The array type of the callback function parameters.
* @param callback - The callback function to be debounced. The `this` context of this function is an instance of the `Oscilloscope` class.
* @param delay - The debounce delay time, in milliseconds.
* @returns Returns a new function that will debounce the input callback function when called.
*/
private static debounce;
/**
* A public method to draw waveforms (with debounce processing).
*
* This method is a debounced drawing method used to draw waveforms on the canvas.
* Debounce processing ensures that performance issues do not occur during high-frequency calls (such as window resize events).
*
* @param peakVoltage - Optional parameter, peak voltage (unit: mV), default value is {@link Oscilloscope.DefaultPeakVoltage} (1000mV).
* @param waveformPeriod - Optional parameter, waveform period (unit: ns), default value is {@link Oscilloscope.DefaultPeriod} (1000ns).
* @param waveformSampler - Optional parameter, waveform sampling function, which receives four parameters:
* `peakAmplitude` - Peak amplitude,
* `waveformPeriod` - Waveform period,
* `timeOffset` - Time offset,
* `pixelProgress` - Current pixel drawing progress (between 0 and 1).
*
* @example
* // Draw a default sine wave (1V peak, 1μs period)
* oscope.drawWaveform();
*
* // Draw a custom triangle wave (500mV peak, 2000ns period)
* oscope.drawWaveform(500, 2000, (voltage, period, time, progress) => {
* return (time % period) / period * 2 - 1; // Generate a triangle wave
* });
*
* @see {@link Oscilloscope.debounce} Details of the debounce implementation
* @see {@link Oscilloscope.drawInternal} Actual drawing logic
*/
readonly drawWaveform: (peakAmplitude?: number, waveformPeriod?: number, waveformSampler?: WaveformSampler) => void;
/**
* Constructor of the Oscilloscope class, used to initialize an oscilloscope instance.
* @param canvasElementOrId - Can be an HTMLCanvasElement object or a string representing the ID of the canvas element.
* @param timeAxisDivisions - Number of divisions on the time axis, default is 14.
* @param amplitudeAxisDivisions - Number of divisions on the amplitude axis, default is 10.
*/
constructor(canvasElementOrId: HTMLCanvasElement | string, timeAxisDivisions?: number, amplitudeAxisDivisions?: number);
/**
* Draw the internal waveform of the oscilloscope.
* @param peakAmplitude Peak voltage (mV), default is 1000mV (1V).
* @param waveformPeriod Waveform period (ns), default is 1000ns (1μs).
* @param waveformSampler Optional waveform sampling function.
*/
private drawInternal;
/**
* Draw the waveform on the canvas.
* @param peakAmplitude Peak voltage (mV).
* @param waveformPeriod Waveform period (ns).
* @param nsPerPixel Time axis scale (ns/pixel).
* @param mvPerPixel Amplitude axis scale (mV/pixel).
* @param waveformSampler Waveform sampling function.
*/
private drawWave;
/**
* Draw the oscilloscope grid and coordinate system.
* @param centerX Horizontal center coordinate of the canvas (pixels).
* @param centerY Vertical center coordinate of the canvas (pixels).
* @param xScale Horizontal scaling factor (pixels/unit).
* @param yScale Vertical scaling factor (pixels/unit).
* @param timePerDivision Width of each division on the time axis (nanoseconds/division).
* @param amplitudePerDivision Height of each division on the amplitude axis (millivolts/division).
*/
private drawGrid;
/**
* Callback function to handle canvas size changes.
* @param newWidth New canvas width (pixels).
* @param newHeight New canvas height (pixels).
*/
private handleResize;
/**
* Initialize the resize observer.
* Determine the observation target and calculation method based on whether the canvas fills the parent container.
*/
private initResizeObserver;
/**
* Calculate the axis base value and scaling ratio.
* @param totalRange Total range value (time range in ns or voltage range in mV).
* @param divisionCount Number of axis divisions.
* @param availablePixels Available pixel size.
* @returns An object containing the scaling ratio and base value per division.
*/
private calculateBase;
/**
* Destroy resources related to the oscilloscope instance.
* This method is used to clean up resources related to the oscilloscope instance, mainly disconnect the ResizeObserver listener and clear the drawing context.
* After calling this method, the oscilloscope will no longer respond to window size change events and cannot continue drawing operations.
*/
dispose(): void;
/**
* Convert the time value to a more readable unit representation.
* @param time Time value, in nanoseconds.
* @returns An object containing the converted time value and the corresponding time unit.
*/
private convertTimeUnit;
/**
* Draw a sine waveform.
* @param peakToPeak Peak-to-peak voltage (mV), the voltage difference between the highest and lowest points of the waveform.
* @param waveformPeriod Waveform period (ns).
*/
drawSinWave(peakToPeak: number, waveformPeriod: number): void;
/**
* Draw a frequency-swept sine wave.
* @param peakToPeak Peak-to-peak voltage (mV).
* @param startFreq Starting frequency (Hz).
* @param endFreq Ending frequency (Hz).
* @param bidirectional Whether to perform bidirectional scanning.
*/
drawSineSweepWave(peakToPeak: number, startFreq: number, endFreq: number, bidirectional?: boolean): void;
/**
* Draw a unipolar pulse waveform.
* @param peakAmplitude Pulse peak amplitude (mV).
* @param waveformPeriod Waveform period (ns).
* @param pulseWidth Pulse width (ns).
*/
drawPulseWave(peakToPeak: number, waveformPeriod: number, pulseWidth: number): void;
/**
* Draw a bipolar pulse waveform.
* @param peakToPeak Peak-to-peak voltage (mV), the voltage difference between the highest and lowest points of the waveform.
* @param waveformPeriod Waveform period (ns).
* @param pulseWidth Pulse width (ns).
*/
drawBipolarPulse(peakToPeak: number, waveformPeriod: number, pulseWidth: number): void;
/**
* Draw a triangle waveform.
* @param peakToPeak - Peak-to-peak voltage (mV), the voltage difference between the highest and lowest points of the waveform.
* @param waveformPeriod - Waveform period (ns), the time required to complete one full waveform.
* @param pulseWidth - Rise time (ns), the time required to rise from the trough to the peak.
*/
drawTriangleWave(peakToPeak: number, waveformPeriod: number, pulseWidth: number): void;
}
export { Oscilloscope };