synthing

a waveform sequencing synth on the web
Log | Files | Refs | Submodules

commit 508a9a701932331c91e50d5c7c7bfa73c0c3fd6e
parent be87106b3f6f029f98484b120b9914fd873ef9df
Author: Massimo Siboldi <mdsiboldi@gmail.com>
Date:   Mon, 19 Feb 2018 21:30:00 -0800

Split WaveEditor into two parts: canvas and waveform editing logic

Diffstat:
Msrc/WaveEditor/index.js | 46+++++++++++-----------------------------------
Msrc/WaveEditor/style.css | 4++--
Asrc/WaveTable/index.js | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/WaveTable/style.css | 3+++
4 files changed, 67 insertions(+), 37 deletions(-)

diff --git a/src/WaveEditor/index.js b/src/WaveEditor/index.js @@ -1,27 +1,9 @@ import { h, Component } from 'preact'; +import WaveTable from '../WaveTable/'; import consts from '../consts.js'; import helpers from '../helpers.js'; import './style.css'; -const drawArea = helpers.throttle((amplitudes, canvas, begin = 0, end = undefined) => { - const ctx = canvas.getContext("2d"); - const rectWidth = canvas.width / consts.BUF_SIZE; - const roundedWidth = Math.max(1, rectWidth) - const lineWidth = 1; - const halfCanvas = (canvas.height - lineWidth) / 2; - window.requestAnimationFrame(() => { - amplitudes.forEach((amp, idx) => { - amp *= halfCanvas; - const roundedXOffset = Math.round(idx * rectWidth); - ctx.clearRect(roundedXOffset, 0, roundedWidth + 1, canvas.height); - ctx.fillStyle = "#ff735e"; - ctx.fillRect(roundedXOffset, halfCanvas, roundedWidth + 1, -amp); - //ctx.fillStyle = "rgba(255, 115, 94, 0.1)"; // changing color for the border - //ctx.fillRect(roundedXOffset, -amp + halfCanvas, roundedWidth + 1, lineWidth); - }); - }); -}, 20) - const smoothZoneRange = function (waveData, begin, end) { if (begin > end) { let tmp = begin; @@ -37,14 +19,13 @@ const smoothZoneRange = function (waveData, begin, end) { export default class waveEditor extends Component { componentDidMount() { - drawArea(this.props.waveform, this.canvasRef); const handleMove = (ev) => { this.updateWaveform({ x: ev.x + window.scrollX, y: ev.y + window.scrollY }, this.props.waveform); } - this.canvasRef.addEventListener('mousedown', (ev) => { + this.divRef.addEventListener('mousedown', (ev) => { document.addEventListener('mousemove', handleMove); helpers.oneTime(document, 'mouseup', (ev) => { document.removeEventListener('mousemove', handleMove); @@ -58,7 +39,7 @@ export default class waveEditor extends Component { return false; } updateWaveform(mouseData, waveform) { - const waveCanvas = this.canvasRef; + const waveCanvas = this.divRef; const canvasCoords = { x: mouseData.x - waveCanvas.offsetLeft, y: mouseData.y - waveCanvas.offsetTop, @@ -66,13 +47,13 @@ export default class waveEditor extends Component { const newWaveform = waveform.slice(); let zone = helpers.bounded( - Math.floor(consts.BUF_SIZE * canvasCoords.x / waveCanvas.width), + Math.floor(consts.BUF_SIZE * canvasCoords.x / waveCanvas.clientWidth), 0, consts.BUF_SIZE - 1 ); let val = helpers.bounded( - ((waveCanvas.height / 2) - canvasCoords.y) / (waveCanvas.height / 2), + ((waveCanvas.clientHeight / 2) - canvasCoords.y) / (waveCanvas.clientHeight / 2), -1, 1 ); @@ -89,19 +70,14 @@ export default class waveEditor extends Component { this.props.updateWaveform(newWaveform); } - componentWillReceiveProps(newProps) { - if (newProps.waveform !== this.props.waveform) { - drawArea(newProps.waveform, this.canvasRef); - } - } render() { return ( - <canvas - class="waveEditor" - height={400} - width={window.innerWidth - 100} - ref={(canvas) => {this.canvasRef = canvas}}> - </canvas> + <div + class="wave-editor" + ref={(div) => {this.divRef = div}} + > + <WaveTable waveform={this.props.waveform} /> + </div> ); } } diff --git a/src/WaveEditor/style.css b/src/WaveEditor/style.css @@ -1,3 +1,3 @@ -.waveEditor { - background: #f1ddd8; +.wave-editor { + display: inline-flex; } diff --git a/src/WaveTable/index.js b/src/WaveTable/index.js @@ -0,0 +1,51 @@ +import { h, Component} from 'preact'; +import helpers from '../helpers'; +import consts from '../consts'; +import './style.css'; + +const drawArea = helpers.throttle((amplitudes, canvas, begin = 0, end = undefined) => { + const ctx = canvas.getContext("2d"); + const rectWidth = canvas.width / consts.BUF_SIZE; + const roundedWidth = Math.max(1, rectWidth) + const lineWidth = 1; + const halfCanvas = (canvas.height - lineWidth) / 2; + window.requestAnimationFrame(() => { + amplitudes.forEach((amp, idx) => { + amp *= halfCanvas; + const roundedXOffset = Math.round(idx * rectWidth); + ctx.clearRect(roundedXOffset, 0, roundedWidth + 1, canvas.height); + ctx.fillStyle = "#ff735e"; + ctx.fillRect(roundedXOffset, halfCanvas, roundedWidth + 1, -amp); + }); + }); +}, 20) + +export default class WaveTable extends Component { + componentWillUpdate() { + return false; + } + componentDidMount() { + drawArea(this.props.waveform, this.canvasRef); + if (this.props.setCanvasRef) { + this.props.setCanvasRef(this.canvasRef); + } + } + componentWillReceiveProps(newProps) { + if (newProps.waveform !== this.props.waveform) { + drawArea(newProps.waveform, this.canvasRef); + } + } + render() { + const height = this.props.height || 400; + const width = this.props.width || window.innerWidth - 100; + return ( + <canvas + class="wave-table" + style={`color: red; height: ${height}px; width: ${width}px`} + height={height} + width={width} + ref={(canvas) => {this.canvasRef = canvas}}> + </canvas> + ); + } +} diff --git a/src/WaveTable/style.css b/src/WaveTable/style.css @@ -0,0 +1,3 @@ +.wave-table { + background: #f1ddd8; +}