UNPKG

canvas-oscilloscope

Version:

HTML5 Canvas oscilloscope simulator with responsive rendering, customizable waveforms, and real-time visualization capabilities.

167 lines (166 loc) 9.04 kB
/** * 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 };