Skip to content

Commit 49a8d14

Browse files
committed
Updated wave spectrum rendering.
1 parent da08a03 commit 49a8d14

File tree

3 files changed

+83
-41
lines changed

3 files changed

+83
-41
lines changed

src/canvas/CanvasWave.js

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import Entity from 'core/Entity';
22
import { drawPath } from 'drawing/bezierSpline';
3-
import { resetCanvas } from 'utils/canvas';
3+
import { resetCanvas, setColor } from 'utils/canvas';
44

55
export default class CanvasWave extends Entity {
66
static defaultProperties = {
7-
color: '#FFFFFF',
7+
stroke: true,
8+
strokeColor: '#FFFFFF',
9+
fill: false,
10+
fillColor: '#FFFFFF',
11+
taper: false,
812
width: 400,
913
height: 200,
14+
midpoint: 100,
1015
lineWidth: 1.0,
11-
fill: false,
12-
taper: false,
1316
};
1417

1518
constructor(properties, canvas) {
@@ -24,63 +27,73 @@ export default class CanvasWave extends Entity {
2427

2528
render(points, smooth) {
2629
const { canvas, context } = this;
27-
const { width, height, color, lineWidth, fill, taper } = this.properties;
28-
const step = width / (points.length - 1);
30+
const {
31+
width,
32+
height,
33+
midpoint,
34+
stroke,
35+
strokeColor,
36+
fill,
37+
fillColor,
38+
lineWidth,
39+
taper,
40+
} = this.properties;
2941

3042
// Reset canvas
3143
resetCanvas(canvas, width, height);
3244

3345
// Canvas setup
3446
context.lineWidth = lineWidth;
35-
context.strokeStyle = color;
36-
context.fillStyle = color;
47+
context.strokeStyle = strokeColor;
48+
setColor(context, fillColor, 0, 0, 0, height);
3749

3850
// Normalize points
39-
for (let i = 0; i < points.length; i++) {
40-
points[i] = height - points[i] * height;
51+
for (let i = 0; i < points.length; i += 2) {
52+
points[i + 1] = height - points[i + 1] * height;
4153
}
4254

4355
// Taper edges
4456
if (taper) {
45-
points[0] = height / 2;
46-
points[points.length - 1] = height / 2;
57+
points[1] = midpoint;
58+
points[points.length - 1] = midpoint;
4759
}
4860

4961
// Draw wave
5062
if (smooth) {
5163
context.beginPath();
5264

53-
// Remap
54-
points = Array.from(points).flatMap((p, i) => [i * step, p]);
55-
5665
// Draw bezier spline
5766
drawPath(context, points);
5867

68+
if (stroke) {
69+
context.stroke();
70+
}
71+
5972
if (fill) {
60-
context.moveTo(width, height / 2);
61-
context.lineTo(0, height / 2);
73+
context.lineTo(width, midpoint);
74+
context.lineTo(0, midpoint);
6275
context.closePath();
6376
context.fill();
64-
} else {
65-
context.stroke();
6677
}
6778
} else {
6879
context.beginPath();
6980

7081
if (fill) {
71-
context.moveTo(0, height / 2);
82+
context.moveTo(0, midpoint);
83+
}
84+
85+
for (let i = 0; i < points.length; i += 2) {
86+
context.lineTo(points[i], points[i + 1]);
7287
}
7388

74-
for (let i = 0; i < points.length; i++) {
75-
context.lineTo(i * step, points[i]);
89+
if (stroke) {
90+
context.stroke();
7691
}
7792

7893
if (fill) {
79-
context.lineTo(width, height / 2);
94+
context.lineTo(width, midpoint);
8095
context.closePath();
8196
context.fill();
82-
} else {
83-
context.stroke();
8497
}
8598
}
8699
}

src/displays/SoundWaveDisplay.js

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,23 @@ export default class SoundWaveDisplay extends CanvasDisplay {
1414
type: 'display',
1515
label: 'Sound Wave',
1616
defaultProperties: {
17-
color: '#FFFFFF',
17+
stroke: true,
18+
strokeColor: '#FFFFFF',
19+
fill: false,
20+
fillColor: '#FFFFFF',
21+
taper: false,
1822
width: DEFAULT_CANVAS_WIDTH,
1923
height: DEFAULT_CANVAS_HEIGHT / 2,
24+
midpoint: DEFAULT_CANVAS_HEIGHT / 4,
2025
lineWidth: 1.0,
2126
wavelength: 0,
2227
smoothingTimeConstant: 0,
23-
fill: false,
24-
taper: false,
2528
x: 0,
2629
y: 0,
2730
rotation: 0,
2831
opacity: 1.0,
2932
},
3033
controls: {
31-
color: {
32-
label: 'Color',
33-
type: 'color',
34-
},
3534
lineWidth: {
3635
label: 'Line Width',
3736
type: 'number',
@@ -55,10 +54,22 @@ export default class SoundWaveDisplay extends CanvasDisplay {
5554
step: 0.01,
5655
withRange: true,
5756
},
57+
stroke: {
58+
label: 'Stroke',
59+
type: 'toggle',
60+
},
61+
strokeColor: {
62+
label: 'Stroke Color',
63+
type: 'color',
64+
},
5865
fill: {
5966
label: 'Fill',
6067
type: 'toggle',
6168
},
69+
fillColor: {
70+
label: 'Fill Color',
71+
type: 'color',
72+
},
6273
taper: {
6374
label: 'Taper Edges',
6475
type: 'toggle',
@@ -122,13 +133,25 @@ export default class SoundWaveDisplay extends CanvasDisplay {
122133
const changed = super.update(properties);
123134

124135
if (changed) {
136+
const { height } = properties;
137+
138+
if (height !== undefined) {
139+
properties.midpoint = height / 2;
140+
}
141+
125142
this.wave.update(properties);
126143
this.parser.update(properties);
127144
}
128145

129146
return changed;
130147
}
131148

149+
getPoints(data, width) {
150+
const step = width / (data.length - 1);
151+
152+
return Array.from(data).flatMap((n, i) => [i * step, n]);
153+
}
154+
132155
render(scene, data) {
133156
const {
134157
wave,
@@ -137,12 +160,12 @@ export default class SoundWaveDisplay extends CanvasDisplay {
137160
properties: { wavelength },
138161
} = this;
139162

140-
const points = parser.parseTimeData(
163+
const values = parser.parseTimeData(
141164
data.td,
142165
wavelength > 0 ? ~~(width / (wavelength * WAVELENGTH_MAX * width)) : width,
143166
);
144167

145-
wave.render(points, wavelength > 0.02);
168+
wave.render(this.getPoints(values, width), wavelength > 0.02);
146169

147170
const origin = {
148171
x: width / 2,

src/displays/WaveSpectrumDisplay.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,21 @@ export default class WaveSpectrumDisplay extends CanvasDisplay {
1414
defaultProperties: {
1515
width: 770,
1616
height: 240,
17+
midpoint: 240,
1718
x: 0,
1819
y: 0,
1920
stroke: true,
2021
strokeColor: '#FFFFFF',
2122
fill: true,
22-
fillColor: ['#C0C0C0', '#000000'],
23+
fillColor: ['#C0C0C0', '#FFFFFF'],
2324
taper: true,
2425
rotation: 0,
2526
opacity: 1.0,
2627
fftSize: FFT_SIZE,
2728
sampleRate: SAMPLE_RATE,
2829
smoothingTimeConstant: 0.5,
2930
minDecibels: -100,
30-
maxDecibels: -20,
31+
maxDecibels: -14,
3132
minFrequency: 0,
3233
maxFrequency: 2000,
3334
normalize: true,
@@ -69,14 +70,14 @@ export default class WaveSpectrumDisplay extends CanvasDisplay {
6970
width: {
7071
label: 'Width',
7172
type: 'number',
72-
min: 0,
73+
min: 1,
7374
max: stageWidth(),
7475
withRange: true,
7576
},
7677
height: {
7778
label: 'Height',
7879
type: 'number',
79-
min: 0,
80+
min: 1,
8081
max: stageHeight(),
8182
withRange: true,
8283
},
@@ -145,15 +146,20 @@ export default class WaveSpectrumDisplay extends CanvasDisplay {
145146
const changed = super.update(properties);
146147

147148
if (changed) {
149+
const { height } = properties;
150+
151+
if (height !== undefined) {
152+
properties.midpoint = height;
153+
}
154+
148155
this.wave.update(properties);
149156
this.parser.update(properties);
150157
}
151158

152159
return changed;
153160
}
154161

155-
getPoints(fft) {
156-
const { width } = this.properties;
162+
getPoints(fft, width) {
157163
const points = [];
158164

159165
for (let i = 0, j = 0, k = 0; i < fft.length; i += 1) {
@@ -180,7 +186,7 @@ export default class WaveSpectrumDisplay extends CanvasDisplay {
180186
} = this;
181187
const fft = parser.parseFFT(data.fft);
182188

183-
wave.render(this.getPoints(fft), true);
189+
wave.render(this.getPoints(fft, width), true);
184190

185191
const origin = {
186192
x: width / 2,

0 commit comments

Comments
 (0)