commit 108684b5e5e27a45551461832bd5f285bb62929c
parent d403e80f994b8a43a863dc3783ed65172e585741
Author: Massimo Siboldi <mdsiboldi@gmail.com>
Date: Wed, 14 Mar 2018 23:37:10 -0700
Add help section
Diffstat:
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;
}