synthing

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

commit 108684b5e5e27a45551461832bd5f285bb62929c
parent d403e80f994b8a43a863dc3783ed65172e585741
Author: Massimo Siboldi <mdsiboldi@gmail.com>
Date:   Wed, 14 Mar 2018 23:37:10 -0700

Add help section

Diffstat:
Msrc/App/index.js | 2++
Asrc/ClickOutside/index.js | 27+++++++++++++++++++++++++++
Asrc/Help/Help.css | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Help/index.js | 44++++++++++++++++++++++++++++++++++++++++++++
Msrc/store.js | 4++++
5 files changed, 126 insertions(+), 0 deletions(-)

diff --git a/src/App/index.js b/src/App/index.js @@ -6,6 +6,7 @@ import CircleButton from '../CircleButton/'; import HSlider from '../HSlider/'; import Param from '../Param/'; import Wheel from '../Wheel/'; +import Help from '../Help/'; import './App.css'; import '../iconfont/style.css'; import consts from '../consts.js'; @@ -179,6 +180,7 @@ class App extends Component { volume={this.props.volume} adsr={this.props.adsr} ></Synth> + <Help /> </div> ); } diff --git a/src/ClickOutside/index.js b/src/ClickOutside/index.js @@ -0,0 +1,27 @@ +import { h, Component } from 'preact'; + +export default class ClickOutside extends Component { + handleClick = (ev) => { + if (!this.elRef.contains(ev.target)) { + console.log('actioning'); + this.props.action(); + } + } + componentDidMount() { + console.log('mounting') + // setTimeout ensures the click event doesn't get triggered while mounting + window.setTimeout(() => { + document.addEventListener('click', this.handleClick); + }, 0); + } + componentWillUnmount() { + document.removeEventListener('click', this.handleClick); + } + render() { + return ( + <div ref={ref => {this.elRef = ref}}> + {this.props.children} + </div> + ); + } +} diff --git a/src/Help/Help.css b/src/Help/Help.css @@ -0,0 +1,49 @@ +.help-modal { + display: flex; + align-items: center; + justify-content: center; + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background: rgba(255, 255, 255, 0.3); +} + +.help-container { + box-sizing: border-box; + background: aqua; + padding: 30px 60px; + margin: 30px; + overflow-y: auto; + max-height: calc(100vh - 60px); + max-width: 900px; +} + +.help-tag { + display: flex; + align-items: center; + justify-content: center; + background: aqua; + position: fixed; + bottom: 25px; + right: 25px; + border-radius: 9999px; + height: 2em; + width: 2em; + z-index: 100; + cursor: pointer; + opacity: 0.8; +} + +.help-tag:hover { + opacity: 1; +} + +.keyboard { + width: 100%; +} + +* { + text-align: left; +} diff --git a/src/Help/index.js b/src/Help/index.js @@ -0,0 +1,44 @@ +import { h } from 'preact'; +import { connect } from 'preact-redux'; +import ClickOutside from '../ClickOutside/'; +import './Help.css'; + +const setHelpOpen = (value) => ({type: 'SET_HELP_OPEN', value}); + +export default connect(state => ({open: state.helpOpen}), {setHelpOpen})((props) => { + const closeIfOpen = () => { + if (props.open) + props.setHelpOpen(false); + } + const modal = props.open ? ( + <div class="help-modal"> + <ClickOutside action={closeIfOpen}> + <div class="help-container"> + <h1>Help</h1> + <h2>Keybindings</h2> + <img class="keyboard" src="../../AudioKeys/images/audiokeys-mapping-rows1.jpg" /> + <h2>About</h2> + Synthing allows you to experiment with and visualize a waveform's effect on generated sound. Works best in Chrome. + <h2>Overview</h2> + <ul> + <li>Draw on the waveform to alter it.</li> + <li>Use the sequencer to activate different waveforms at different times. You can mute, solo, and mix waveforms.</li> + <li>Press play to start the sequencer, and feel free to change the bpm to make it faster or slower.</li> + </ul> + </div> + </ClickOutside> + </div> + ) : ''; + + return ( + <div class="help"> + <div + class="help-tag" + onClick={props.setHelpOpen.bind(null, !props.open)} + > + ? + </div> + {modal} + </div> + ); +}) diff --git a/src/store.js b/src/store.js @@ -11,6 +11,7 @@ const initialState = { playing: false, numBeats, editingToneIdx: 0, + helpOpen: false, adsr: { attack: 0.3, decay: 1, @@ -133,6 +134,9 @@ const globalReducer = (state, action) => { state.tones.length - 2 ); break; + case 'SET_HELP_OPEN': + updates.helpOpen = action.value; + break; default: break; }