diff options
Diffstat (limited to 'app/client')
| -rw-r--r-- | app/client/common/header.component.js | 18 | ||||
| -rw-r--r-- | app/client/common/paramGroup.component.js | 23 | ||||
| -rw-r--r-- | app/client/common/slider.component.js | 40 | ||||
| -rw-r--r-- | app/client/index.jsx | 25 | ||||
| -rw-r--r-- | app/client/live/actions.js | 10 | ||||
| -rw-r--r-- | app/client/live/components/player.component.js | 16 | ||||
| -rw-r--r-- | app/client/live/index.js | 126 | ||||
| -rw-r--r-- | app/client/live/reducer.js | 35 | ||||
| -rw-r--r-- | app/client/socket.js | 60 | ||||
| -rw-r--r-- | app/client/store.js | 26 |
10 files changed, 379 insertions, 0 deletions
diff --git a/app/client/common/header.component.js b/app/client/common/header.component.js new file mode 100644 index 0000000..bb2ec04 --- /dev/null +++ b/app/client/common/header.component.js @@ -0,0 +1,18 @@ +import { h, Component } from 'preact' +import { connect } from 'react-redux' + +function Header(props) { + return ( + <header> + live cortex + </header> + ) +} + +const mapStateToProps = state => ({ +}) + +const mapDispatchToProps = (dispatch, ownProps) => ({ +}) + +export default connect(mapStateToProps, mapDispatchToProps)(Header) diff --git a/app/client/common/paramGroup.component.js b/app/client/common/paramGroup.component.js new file mode 100644 index 0000000..276425b --- /dev/null +++ b/app/client/common/paramGroup.component.js @@ -0,0 +1,23 @@ +import { h, Component } from 'preact' +import { connect } from 'react-redux' + +function ParamGroup(props) { + return ( + <div class='paramGroup'> + <label> + <h3>{props.title}</h3> + <input type='checkbox' /> + </label> + {props.children} + </div> + ) +} + +const mapStateToProps = state => ({ + +}) + +const mapDispatchToProps = (dispatch, ownProps) => ({ +}) + +export default connect(mapStateToProps, mapDispatchToProps)(ParamGroup) diff --git a/app/client/common/slider.component.js b/app/client/common/slider.component.js new file mode 100644 index 0000000..8932fbd --- /dev/null +++ b/app/client/common/slider.component.js @@ -0,0 +1,40 @@ +import { h, Component } from 'preact' +import { connect } from 'react-redux' + +class Slider extends Component { + render(){ + const props = this.props + const name = props.name + const title = props.title || name.replace(/_/g, ' ') + let step; + if (props.type === 'int') { + step = 1 + } else { + step = (props.max - props.min) / 100 + } + return ( + <div class='slider'> + <label> + <span>{title}</span> + <input type='text' + /> + </label> + <input + type='range' + min={props.min} + max={props.max} + step={step} + /> + </div> + ) + } +} + +const mapStateToProps = state => ({ +}) + +const mapDispatchToProps = (dispatch, ownProps) => ({ + ...ownProps, +}) + +export default connect(mapStateToProps, mapDispatchToProps)(Slider) diff --git a/app/client/index.jsx b/app/client/index.jsx new file mode 100644 index 0000000..63757bf --- /dev/null +++ b/app/client/index.jsx @@ -0,0 +1,25 @@ +import { h, render } from 'preact' +import { Provider } from 'react-redux' +// import { } from 'react-router-redux' +import { BrowserRouter, Route } from 'react-router-dom' +// import client from './client' +import socket from './socket' + +import { store, history } from './store' + +import Header from './common/header.component' +import Live from './live' + +const app = ( + <Provider store={store}> + <BrowserRouter> + <div> + <Header /> + <Route path='/' component={Live} /> + <Route path='/live/' component={Live} /> + </div> + </BrowserRouter> + </Provider> +) + +render(app, document.getElementById('container')) diff --git a/app/client/live/actions.js b/app/client/live/actions.js new file mode 100644 index 0000000..30a25ff --- /dev/null +++ b/app/client/live/actions.js @@ -0,0 +1,10 @@ +import socket from '../socket' + +export const loadOptFromServer = (opt) => ({ + type: 'LIVE_LOAD_OPT_FROM_SERVER', opt, +}) +// export const updateOptFromServer = (key, value) => { +// return { +// type: 'LIVE_LOAD_OPT_FROM_SERVER', opt, +// } +// } diff --git a/app/client/live/components/player.component.js b/app/client/live/components/player.component.js new file mode 100644 index 0000000..3c5fc9e --- /dev/null +++ b/app/client/live/components/player.component.js @@ -0,0 +1,16 @@ +import { h, Component } from 'preact' +import { connect } from 'react-redux' + +function Player(props) { + return ( + <div className='player' /> + ) +} + +const mapStateToProps = state => ({ +}) + +const mapDispatchToProps = (dispatch, ownProps) => ({ +}) + +export default connect(mapStateToProps, mapDispatchToProps)(Player) diff --git a/app/client/live/index.js b/app/client/live/index.js new file mode 100644 index 0000000..80f531a --- /dev/null +++ b/app/client/live/index.js @@ -0,0 +1,126 @@ +import { h, Component } from 'preact' +import { connect } from 'react-redux' + +import Player from './components/player.component' +import ParamGroup from '../common/paramGroup.component' +import Slider from '../common/slider.component' + +function App(props) { + return ( + <div className='app'> + <Player /> + <div className='params'> + + <ParamGroup + title='Transition' + > + <Slider + name='transition_period' + min={10} max={5000} type='int' + /> + <Slider + name='transition_min' + min={0.001} max={0.2} type='float' + /> + <Slider + name='transition_max' + min={0.1} max={1.0} type='float' + /> + </ParamGroup> + + <ParamGroup + title='Recursion' + toggle='recursive' + > + <Slider + name='recursive_frac' + min={0.01} max={0.3} type='float' + /> + <Slider + name='recurse_roll' + min={-5} max={5} type='int' + /> + <Slider + name='recurse_roll_axis' + min={0} max={1} type='int' + /> + </ParamGroup> + + <ParamGroup + title='Sequence' + toggle='sequence' + > + <Slider + name='sequence_frac' + min={0.01} max={0.3} type='float' + /> + <Slider + name='process_frac' + min={0} max={1} type='float' + /> + </ParamGroup> + + <ParamGroup + title='Clahe' + toggle='clahe' + > + <Slider + name='clip_limit' + min={1.0} max={4.0} type='float' + /> + </ParamGroup> + + <ParamGroup + title='Posterize' + toggle='posterize' + > + <Slider + name='spatial_window' + min={2} max={128} type='int' + /> + <Slider + name='color_window' + min={2} max={128} type='int' + /> + </ParamGroup> + + <ParamGroup + title='Blur' + toggle='blur' + > + <Slider + name='blur_radius' + min={3} max={7} type='int' + /> + <Slider + name='blur_sigma' + min={0} max={2} type='float' + /> + </ParamGroup> + + <ParamGroup + title='Canny Edge Detection' + toggle='canny' + > + <Slider + name='canny_lo' + min={10} max={200} type='int' + /> + <Slider + name='canny_hi' + min={10} max={200} type='int' + /> + </ParamGroup> + + </div> + </div> + ) +} + +const mapStateToProps = state => ({ +}) + +const mapDispatchToProps = (dispatch, ownProps) => ({ +}) + +export default connect(mapStateToProps, mapDispatchToProps)(App) diff --git a/app/client/live/reducer.js b/app/client/live/reducer.js new file mode 100644 index 0000000..9d41c6f --- /dev/null +++ b/app/client/live/reducer.js @@ -0,0 +1,35 @@ +import { combineReducers } from 'redux' + +const liveInitialState = { + loading: false, + error: null, + opt: {}, +} + +const liveReducer = (state = liveInitialState, action) => { + let results; + + switch(action.type) { + case 'LIVE_LOAD_OPT_FROM_SERVER': + return { + ...state, + loading: false, + error: null, + opt: action.opt, + } + + case 'LIVE_SET_OPT': + return { + ...state, + opt: { + ...state.opt, + [action.key]: action.value, + } + } + + default: + return state + } +} + +export default liveReducer diff --git a/app/client/socket.js b/app/client/socket.js new file mode 100644 index 0000000..289fc4e --- /dev/null +++ b/app/client/socket.js @@ -0,0 +1,60 @@ +let socket = io.connect('/client') +let got_frame = false + +socket.on('res', (data) => { + switch (data.cmd) { + case 'get_last_frame': + console.log('get last frame!') + if (data.res !== 'working') { + socket.emit('cmd', { + cmd: 'get_last_frame', + }) + } + break + default: + break + } + console.log(data) +}) + +socket.on('frame', (data) => { + got_frame = true + const blob = new Blob([data.frame], { type: 'image/jpg' }) + const url = URL.createObjectURL(blob) + const img = new Image () + img.onload = function() { + URL.revokeObjectURL(url) + const player = document.querySelector('.player') + player.innerHTML = '' + player.appendChild(img) + } + img.src = url +}) + +socket.emit('cmd', { + cmd: 'get_params', +}) + +setTimeout(() => { + if (!got_frame) { + // socket.emit('cmd', { + // cmd: 'get_last_frame', + // }) + } +}, 500) + +export function get_params(key, value) { + socket.emit('cmd', { + cmd: 'get_params', + }) +} +export function send_param(key, value) { + socket.emit('cmd', { + cmd: 'send_param', + payload: { + 'key': key, + 'value': value, + } + }) +} +export { socket } diff --git a/app/client/store.js b/app/client/store.js new file mode 100644 index 0000000..863161d --- /dev/null +++ b/app/client/store.js @@ -0,0 +1,26 @@ +import { compose, createStore, combineReducers, applyMiddleware } from 'redux' +import { routerMiddleware } from 'react-router-redux' +import thunk from 'redux-thunk' +import createHistory from 'history/createBrowserHistory' + +import { routerReducer } from 'react-router-redux' + +// import navReducer from './nav.reducer' +import liveReducer from './live/reducer' + +const appReducer = combineReducers({ + live: liveReducer, + router: routerReducer, +}) + +export const history = createHistory() +export const store = createStore( + appReducer, + compose( + applyMiddleware( + // createLogger(), + thunk, + routerMiddleware(history), + ) + ) +) |
