├── now.json ├── .babelrc ├── babel-preset.js ├── static └── sounds │ ├── claves.wav │ ├── cowbell.wav │ ├── cymbal.wav │ ├── hi_tom.wav │ ├── low_tom.wav │ ├── maracas.wav │ ├── mid_tom.wav │ ├── bass_drum.wav │ ├── cl_hi_hat.wav │ ├── hand_clap.wav │ ├── hi_conga.wav │ ├── low_conga.wav │ ├── mid_conga.wav │ ├── o_hi_hat.wav │ ├── rim_shot.wav │ └── snare_drum.wav ├── .gitignore ├── lib ├── hydrate.js └── theme.js ├── pages ├── index.js └── _document.js ├── readme.md ├── next.config.js ├── components ├── box │ └── index.js └── DrumMachine.js └── package.json /now.json: -------------------------------------------------------------------------------- 1 | { 2 | "alias": "tuile", 3 | "forwardNpm": true 4 | } 5 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "next/babel", 4 | "./babel-preset.js" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /babel-preset.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [[require('babel-plugin-emotion')]] 3 | } 4 | -------------------------------------------------------------------------------- /static/sounds/claves.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/claves.wav -------------------------------------------------------------------------------- /static/sounds/cowbell.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/cowbell.wav -------------------------------------------------------------------------------- /static/sounds/cymbal.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/cymbal.wav -------------------------------------------------------------------------------- /static/sounds/hi_tom.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/hi_tom.wav -------------------------------------------------------------------------------- /static/sounds/low_tom.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/low_tom.wav -------------------------------------------------------------------------------- /static/sounds/maracas.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/maracas.wav -------------------------------------------------------------------------------- /static/sounds/mid_tom.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/mid_tom.wav -------------------------------------------------------------------------------- /static/sounds/bass_drum.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/bass_drum.wav -------------------------------------------------------------------------------- /static/sounds/cl_hi_hat.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/cl_hi_hat.wav -------------------------------------------------------------------------------- /static/sounds/hand_clap.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/hand_clap.wav -------------------------------------------------------------------------------- /static/sounds/hi_conga.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/hi_conga.wav -------------------------------------------------------------------------------- /static/sounds/low_conga.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/low_conga.wav -------------------------------------------------------------------------------- /static/sounds/mid_conga.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/mid_conga.wav -------------------------------------------------------------------------------- /static/sounds/o_hi_hat.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/o_hi_hat.wav -------------------------------------------------------------------------------- /static/sounds/rim_shot.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/rim_shot.wav -------------------------------------------------------------------------------- /static/sounds/snare_drum.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkh44/emotion-beats/master/static/sounds/snare_drum.wav -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # build output 7 | .next 8 | package-lock.json 9 | -------------------------------------------------------------------------------- /lib/hydrate.js: -------------------------------------------------------------------------------- 1 | import { hydrate } from 'emotion' 2 | 3 | // Adds server generated styles to emotion cache. 4 | // Has to run before any `style()` calls 5 | // '__NEXT_DATA__.ids' is set in '_document.js' 6 | if (typeof window !== 'undefined') { 7 | hydrate(window.__NEXT_DATA__.ids) 8 | } 9 | -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | import '../lib/hydrate' 2 | import dynamic from 'next/dynamic' 3 | 4 | const DrumMachine = dynamic(import('../components/DrumMachine'), { 5 | ssr: false // don't want to deal with "window" problems when loading the audio api 6 | }) 7 | 8 | export default () => 9 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 2 | # Emotion Beats 3 | 4 | Example for [emotion](https://github.com/emotion-js/emotion) with [next](https://github.com/zeit/next.js) and [React](https://github.com/facebook/react) 5 | 6 | #### Installation 7 | ```bash 8 | $ npm install 9 | ``` 10 | 11 | #### Development 12 | ```bash 13 | $ npm run dev 14 | ``` 15 | 16 | #### Production 17 | ```bash 18 | $ npm run build && npm run start 19 | ``` 20 | 21 | 22 | 23 | **inspired by https://github.com/siggy/beatboxer** 24 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | webpack: (config, { dev }) => { 3 | config.devtool = 'eval' 4 | config.module.rules.push( 5 | { 6 | test: /\.(css|scss)/, 7 | loader: 'emit-file-loader', 8 | options: { 9 | name: 'dist/[path][name].[ext]' 10 | } 11 | }, 12 | { 13 | test: /\.css$/, 14 | use: ['babel-loader', 'raw-loader', 'style-loader', 'css-loader'] 15 | } 16 | ) 17 | return config 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /components/box/index.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'react-emotion' 2 | import { space, width, fontSize, color, responsiveStyle } from 'styled-system' 3 | 4 | 5 | export const display = responsiveStyle('display') 6 | export const flex = responsiveStyle('flex') 7 | export const order = responsiveStyle('order') 8 | const wrap = responsiveStyle('flex-wrap', 'wrap', 'wrap') 9 | const direction = responsiveStyle('flexDirection', 'direction') 10 | const align = responsiveStyle('alignItems', 'align') 11 | const justify = responsiveStyle('justifyContent', 'justify') 12 | const column = props => props.column ? css`flex-direction:column;` : null 13 | 14 | const Box = styled('div')` 15 | ${display}; 16 | ${space}; 17 | ${width}; 18 | ${fontSize}; 19 | ${color}; 20 | ${flex}; 21 | ${order}; 22 | ${wrap}; 23 | ${column}; 24 | ${direction}; 25 | ${align}; 26 | ${justify}; 27 | ` 28 | 29 | export default Box 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pivot", 3 | "private": true, 4 | "dependencies": { 5 | "babel-plugin-emotion": "^8.0.2-7", 6 | "data-driven-motion": "^0.0.11", 7 | "emotion": "^8.0.2-9", 8 | "emotion-server": "^8.0.2-9", 9 | "next": "^3.0.6", 10 | "open-color": "^1.5.1", 11 | "react": "^15.6.1", 12 | "react-dom": "^15.6.1", 13 | "react-emotion": "^8.0.2-9", 14 | "simple-listen": "^1.1.2", 15 | "styled-system": "^1.0.0-13", 16 | "whatwg-fetch": "^2.0.3" 17 | }, 18 | "devDependencies": { 19 | "babel-eslint": "^7.2.3", 20 | "css-loader": "^0.28.5", 21 | "json-server": "^0.12.0", 22 | "postcss-loader": "^2.0.6", 23 | "raw-loader": "^0.5.1", 24 | "standard": "^10.0.3", 25 | "style-loader": "^0.18.2" 26 | }, 27 | "scripts": { 28 | "dev": "next", 29 | "build": "next build", 30 | "start": "NODE_ENV=production next start", 31 | "lint": "standard" 32 | }, 33 | "eslintConfig": { 34 | "extends": "standard", 35 | "parser": "babel-eslint", 36 | "rules": { 37 | "jsx-quotes": [ 38 | "error", 39 | "prefer-single" 40 | ] 41 | } 42 | }, 43 | "standard": { 44 | "parser": "babel-eslint", 45 | "ignore": [ 46 | "/dist/" 47 | ] 48 | }, 49 | "browserslist": [ 50 | "last 1 Chrome version" 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /lib/theme.js: -------------------------------------------------------------------------------- 1 | import { css, fontFace } from 'emotion' 2 | import colors from 'open-color' 3 | import { constants } from 'styled-system' 4 | 5 | const { breakpoints, space, fontSizes } = constants 6 | 7 | fontFace` 8 | font-family: 'Montserrat'; 9 | font-style: normal; 10 | font-weight: 400; 11 | src: local('Montserrat Regular'), local('Montserrat-Regular'), url(https://fonts.gstatic.com/s/montserrat/v10/zhcz-_WihjSQC0oHJ9TCYAzyDMXhdD8sAj6OAJTFsBI.woff2) format('woff2'); 12 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; 13 | ` 14 | fontFace` 15 | font-family: 'Montserrat'; 16 | font-style: normal; 17 | font-weight: 300; 18 | src: local('Montserrat Light'), local('Montserrat-Light'), url(https://fonts.gstatic.com/s/montserrat/v10/IVeH6A3MiFyaSEiudUMXEweOulFbQKHxPa89BaxZzA0.woff2) format('woff2'); 19 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; 20 | ` 21 | 22 | const utils = { 23 | aspectRatio: (width, height) => css` 24 | position: relative; 25 | &:before { 26 | display: block; 27 | content: ""; 28 | width: 100%; 29 | padding-top: ${height / width * 100}%; 30 | } 31 | & > .aspect-ratio-content { 32 | position: absolute; 33 | top: 0; 34 | left: 0; 35 | right: 0; 36 | bottom: 0; 37 | } 38 | `, 39 | hoverStyles: css` 40 | cursor: pointer; 41 | &:hover { 42 | color: ${colors.green[5]}; 43 | } 44 | ` 45 | } 46 | 47 | export default { 48 | bp: breakpoints, 49 | colors, 50 | fontSizes, 51 | space, 52 | utils 53 | } 54 | -------------------------------------------------------------------------------- /pages/_document.js: -------------------------------------------------------------------------------- 1 | import Document, { Head, Main, NextScript } from 'next/document' 2 | import { extractCritical } from 'emotion-server' 3 | import { injectGlobal } from 'emotion' 4 | 5 | import theme from '../lib/theme' 6 | 7 | injectGlobal` 8 | html, body { 9 | font-family: 'Montserrat', 10 | -apple-system, 11 | BlinkMacSystemFont, 12 | "Segoe UI", 13 | "Roboto", 14 | "Roboto Light", 15 | "Oxygen", 16 | "Ubuntu", 17 | "Cantarell", 18 | "Fira Sans", 19 | "Droid Sans", 20 | "Helvetica Neue", 21 | sans-serif, 22 | "Apple Color Emoji", 23 | "Segoe UI Emoji", 24 | "Segoe UI Symbol"; 25 | color: ${theme.colors.gray[8]}; 26 | width: 100%; 27 | height: 100%; 28 | padding: 0; 29 | margin: 0; 30 | overflow: hidden; 31 | -webkit-font-smoothing: antialiased; 32 | -moz-osx-font-smoothing: grayscale; 33 | } 34 | 35 | body > div:first-of-type, 36 | #app, 37 | #__next, 38 | #__next > div { 39 | display: flex; 40 | flex: 1; 41 | height: 100%; 42 | } 43 | 44 | * { 45 | box-sizing: border-box; 46 | } 47 | 48 | button { 49 | text-decoration: none; 50 | text-align: center; 51 | cursor: pointer; 52 | user-select: none; 53 | border: none; 54 | background: none; 55 | font-size: ${theme.fontSizes[1]}; 56 | margin: 0; 57 | padding: 0; 58 | 59 | &:hover, 60 | &:active { 61 | outline: none; 62 | } 63 | } 64 | 65 | a { 66 | color: ${theme.colors.grape[5]}; 67 | text-decoration: none; 68 | cursor: pointer; 69 | &:hover { 70 | color: ${theme.colors.grape[8]}; 71 | } 72 | } 73 | ` 74 | 75 | export default class MyDocument extends Document { 76 | static getInitialProps ({ renderPage }) { 77 | const page = renderPage() 78 | const styles = extractCritical(page.html) 79 | return { ...page, ...styles } 80 | } 81 | 82 | constructor (props) { 83 | super(props) 84 | const { __NEXT_DATA__, ids } = props 85 | if (ids) { 86 | __NEXT_DATA__.ids = this.props.ids 87 | } 88 | } 89 | 90 | render () { 91 | return ( 92 | 93 | 94 | Beats with emotion 95 | 96 |