├── .gitignore ├── LICENSE.md ├── README.md ├── assets ├── demo.gif └── screen.png ├── config ├── env.js ├── paths.js ├── polyfills.js ├── webpack.config.dev.js └── webpack.config.prod.js ├── package.json ├── public └── index.html ├── scripts ├── build.js └── start.js ├── src ├── actions │ └── index.js ├── code-transform │ └── index.js ├── components │ ├── code-preview │ │ ├── index.css │ │ └── index.js │ ├── header │ │ ├── index.css │ │ └── index.js │ ├── info │ │ ├── index.css │ │ └── index.js │ ├── intro │ │ ├── index.css │ │ └── index.js │ ├── modal │ │ ├── index.css │ │ └── index.js │ ├── population │ │ ├── index.css │ │ └── index.js │ └── renderer │ │ ├── index.css │ │ └── index.js ├── constants.js ├── genetic │ ├── evolution.worker.js │ ├── genotype.js │ └── population.js ├── index.css ├── index.js ├── reducers │ └── index.js └── utils.js ├── tests ├── code-transform-electron-tests │ ├── README.md │ ├── index.js │ └── test-code-transform-electron.sh └── code-transform-test │ ├── color-smoke.js │ ├── complex-control.js │ ├── detection-01.js │ ├── detection-02.js │ ├── distortion-tests.js │ ├── flow-field.js │ ├── lorenz.js │ ├── neon-waves.js │ ├── p5-l-system.js │ ├── p5-noise-wave.js │ ├── p5-particle-sys.js │ ├── p5-sine-wave.js │ ├── shiffman-supershapes.js │ └── simple-drawing.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | .DS_Store 3 | 4 | # Node.js 5 | node_modules/ 6 | 7 | # VIM session 8 | session.vim 9 | 10 | # logs 11 | *.log 12 | 13 | # production build 14 | build/ 15 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Szymon Kaliski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Parametrium 2 | 3 | ## Interactive parameter space explorer for P5.js 4 | 5 |

screenshot

6 | 7 | Live: [http://szymonkaliski.github.io/parametrium](http://szymonkaliski.github.io/parametrium) 8 | 9 | Made with [recast](https://github.com/benjamn/recast), [react](https://facebook.github.io/react/), [redux](https://github.com/reactjs/redux) and [immutable](https://facebook.github.io/immutable-js/). 10 | 11 | Features AST-walker with number detection, and evolutionary algorithm adapted from [WallGen](http://szymonkaliski.github.io/wallgen). 12 | 13 | ## Run 14 | 15 | 1. clone this repo 16 | 2. `yarn` or `npm install` 17 | 3. `yarn run start` or `npm start` 18 | 19 | ## Build 20 | 21 | 1. `yarn run build` or `npm run build` 22 | 23 | -------------------------------------------------------------------------------- /assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szymonkaliski/parametrium/a37db6c0c15ee6b7d6e48af1c67daa28369ed098/assets/demo.gif -------------------------------------------------------------------------------- /assets/screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/szymonkaliski/parametrium/a37db6c0c15ee6b7d6e48af1c67daa28369ed098/assets/screen.png -------------------------------------------------------------------------------- /config/env.js: -------------------------------------------------------------------------------- 1 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be 2 | // injected into the application via DefinePlugin in Webpack configuration. 3 | 4 | var REACT_APP = /^REACT_APP_/i; 5 | 6 | function getClientEnvironment(publicUrl) { 7 | var processEnv = Object 8 | .keys(process.env) 9 | .filter(key => REACT_APP.test(key)) 10 | .reduce((env, key) => { 11 | env[key] = JSON.stringify(process.env[key]); 12 | return env; 13 | }, { 14 | // Useful for determining whether we’re running in production mode. 15 | // Most importantly, it switches React into the correct mode. 16 | 'NODE_ENV': JSON.stringify( 17 | process.env.NODE_ENV || 'development' 18 | ), 19 | // Useful for resolving the correct path to static assets in `public`. 20 | // For example, . 21 | // This should only be used as an escape hatch. Normally you would put 22 | // images into the `src` and `import` them in code to get their paths. 23 | 'PUBLIC_URL': JSON.stringify(publicUrl) 24 | }); 25 | return {'process.env': processEnv}; 26 | } 27 | 28 | module.exports = getClientEnvironment; 29 | -------------------------------------------------------------------------------- /config/paths.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var fs = require('fs'); 3 | 4 | // Make sure any symlinks in the project folder are resolved: 5 | // https://github.com/facebookincubator/create-react-app/issues/637 6 | var appDirectory = fs.realpathSync(process.cwd()); 7 | function resolveApp(relativePath) { 8 | return path.resolve(appDirectory, relativePath); 9 | } 10 | 11 | // We support resolving modules according to `NODE_PATH`. 12 | // This lets you use absolute paths in imports inside large monorepos: 13 | // https://github.com/facebookincubator/create-react-app/issues/253. 14 | 15 | // It works similar to `NODE_PATH` in Node itself: 16 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders 17 | 18 | // We will export `nodePaths` as an array of absolute paths. 19 | // It will then be used by Webpack configs. 20 | // Jest doesn’t need this because it already handles `NODE_PATH` out of the box. 21 | 22 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored. 23 | // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims. 24 | // https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421 25 | 26 | var nodePaths = (process.env.NODE_PATH || '') 27 | .split(process.platform === 'win32' ? ';' : ':') 28 | .filter(Boolean) 29 | .filter(folder => !path.isAbsolute(folder)) 30 | .map(resolveApp); 31 | 32 | // config after eject: we're in ./config/ 33 | module.exports = { 34 | appBuild: resolveApp('build'), 35 | appPublic: resolveApp('public'), 36 | appHtml: resolveApp('public/index.html'), 37 | appIndexJs: resolveApp('src/index.js'), 38 | appPackageJson: resolveApp('package.json'), 39 | appSrc: resolveApp('src'), 40 | yarnLockFile: resolveApp('yarn.lock'), 41 | testsSetup: resolveApp('src/setupTests.js'), 42 | appNodeModules: resolveApp('node_modules'), 43 | ownNodeModules: resolveApp('node_modules'), 44 | nodePaths: nodePaths 45 | }; 46 | -------------------------------------------------------------------------------- /config/polyfills.js: -------------------------------------------------------------------------------- 1 | if (typeof Promise === 'undefined') { 2 | // Rejection tracking prevents a common issue where React gets into an 3 | // inconsistent state due to an error, but it gets swallowed by a Promise, 4 | // and the user has no idea what causes React's erratic future behavior. 5 | require('promise/lib/rejection-tracking').enable(); 6 | window.Promise = require('promise/lib/es6-extensions.js'); 7 | } 8 | 9 | // fetch() polyfill for making API calls. 10 | require('whatwg-fetch'); 11 | 12 | // Object.assign() is commonly used with React. 13 | // It will use the native implementation if it's present and isn't buggy. 14 | Object.assign = require('object-assign'); 15 | -------------------------------------------------------------------------------- /config/webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | var autoprefixer = require('autoprefixer'); 2 | var webpack = require('webpack'); 3 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); 5 | var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); 6 | var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); 7 | var getClientEnvironment = require('./env'); 8 | var paths = require('./paths'); 9 | 10 | 11 | 12 | // Webpack uses `publicPath` to determine where the app is being served from. 13 | // In development, we always serve from the root. This makes config easier. 14 | var publicPath = '/'; 15 | // `publicUrl` is just like `publicPath`, but we will provide it to our app 16 | // as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript. 17 | // Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz. 18 | var publicUrl = ''; 19 | // Get environment variables to inject into our app. 20 | var env = getClientEnvironment(publicUrl); 21 | 22 | // This is the development configuration. 23 | // It is focused on developer experience and fast rebuilds. 24 | // The production configuration is different and lives in a separate file. 25 | module.exports = { 26 | // You may want 'eval' instead if you prefer to see the compiled output in DevTools. 27 | // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343. 28 | devtool: 'cheap-module-source-map', 29 | // These are the "entry points" to our application. 30 | // This means they will be the "root" imports that are included in JS bundle. 31 | // The first two entry points enable "hot" CSS and auto-refreshes for JS. 32 | entry: [ 33 | // Include an alternative client for WebpackDevServer. A client's job is to 34 | // connect to WebpackDevServer by a socket and get notified about changes. 35 | // When you save a file, the client will either apply hot updates (in case 36 | // of CSS changes), or refresh the page (in case of JS changes). When you 37 | // make a syntax error, this client will display a syntax error overlay. 38 | // Note: instead of the default WebpackDevServer client, we use a custom one 39 | // to bring better experience for Create React App users. You can replace 40 | // the line below with these two lines if you prefer the stock client: 41 | // require.resolve('webpack-dev-server/client') + '?/', 42 | // require.resolve('webpack/hot/dev-server'), 43 | require.resolve('react-dev-utils/webpackHotDevClient'), 44 | // We ship a few polyfills by default: 45 | require.resolve('./polyfills'), 46 | // Finally, this is your app's code: 47 | paths.appIndexJs 48 | // We include the app code last so that if there is a runtime error during 49 | // initialization, it doesn't blow up the WebpackDevServer client, and 50 | // changing JS code would still trigger a refresh. 51 | ], 52 | output: { 53 | // Next line is not used in dev but WebpackDevServer crashes without it: 54 | path: paths.appBuild, 55 | // Add /* filename */ comments to generated require()s in the output. 56 | pathinfo: true, 57 | // This does not produce a real file. It's just the virtual path that is 58 | // served by WebpackDevServer in development. This is the JS bundle 59 | // containing code from all our entry points, and the Webpack runtime. 60 | filename: 'static/js/bundle.js', 61 | // This is the URL that app is served from. We use "/" in development. 62 | publicPath: publicPath 63 | }, 64 | resolve: { 65 | // This allows you to set a fallback for where Webpack should look for modules. 66 | // We read `NODE_PATH` environment variable in `paths.js` and pass paths here. 67 | // We use `fallback` instead of `root` because we want `node_modules` to "win" 68 | // if there any conflicts. This matches Node resolution mechanism. 69 | // https://github.com/facebookincubator/create-react-app/issues/253 70 | fallback: paths.nodePaths, 71 | // These are the reasonable defaults supported by the Node ecosystem. 72 | // We also include JSX as a common component filename extension to support 73 | // some tools, although we do not recommend using it, see: 74 | // https://github.com/facebookincubator/create-react-app/issues/290 75 | extensions: ['.js', '.json', '.jsx', ''], 76 | alias: { 77 | // Support React Native Web 78 | // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ 79 | 'react-native': 'react-native-web' 80 | } 81 | }, 82 | 83 | module: { 84 | // First, run the linter. 85 | // It's important to do this before Babel processes the JS. 86 | preLoaders: [ 87 | { 88 | test: /\.(js|jsx)$/, 89 | loader: 'eslint', 90 | include: paths.appSrc, 91 | } 92 | ], 93 | loaders: [ 94 | // Default loader: load all assets that are not handled 95 | // by other loaders with the url loader. 96 | // Note: This list needs to be updated with every change of extensions 97 | // the other loaders match. 98 | // E.g., when adding a loader for a new supported file extension, 99 | // we need to add the supported extension to this loader too. 100 | // Add one new line in `exclude` for each loader. 101 | // 102 | // "file" loader makes sure those assets get served by WebpackDevServer. 103 | // When you `import` an asset, you get its (virtual) filename. 104 | // In production, they would get copied to the `build` folder. 105 | // "url" loader works like "file" loader except that it embeds assets 106 | // smaller than specified limit in bytes as data URLs to avoid requests. 107 | // A missing `test` is equivalent to a match. 108 | { 109 | exclude: [ 110 | /\.html$/, 111 | /\.(js|jsx)$/, 112 | /\.css$/, 113 | /\.json$/, 114 | /\.svg$/ 115 | ], 116 | loader: 'url', 117 | query: { 118 | limit: 10000, 119 | name: 'static/media/[name].[hash:8].[ext]' 120 | } 121 | }, 122 | // Process JS with Babel. 123 | { 124 | test: /\.(js|jsx)$/, 125 | include: paths.appSrc, 126 | loader: 'babel', 127 | query: { 128 | // This is a feature of `babel-loader` for webpack (not Babel itself). 129 | // It enables caching results in ./node_modules/.cache/babel-loader/ 130 | // directory for faster rebuilds. 131 | cacheDirectory: true 132 | } 133 | }, 134 | // Process webworker with Babel. 135 | { 136 | test: /\.worker\.js$/, 137 | loader: 'worker!babel?presets[]=es2015' 138 | }, 139 | // "postcss" loader applies autoprefixer to our CSS. 140 | // "css" loader resolves paths in CSS and adds assets as dependencies. 141 | // "style" loader turns CSS into JS modules that inject 13 | 14 | 15 | 16 | `; 19 | }; 20 | 21 | class Renderer extends Component { 22 | constructor() { 23 | super(); 24 | 25 | autobind(this); 26 | } 27 | 28 | componentDidUpdate(prevProps) { 29 | if (prevProps.width !== this.props.width || prevProps.height !== this.props.height) { 30 | // reload ref iframe srcdoc to get new window size in the code (if it uses window.innerWidth/Height to set canvas) 31 | if (prevProps.code === this.props.code) { 32 | this.refIframe.srcdoc = generateHTML(this.props.code); 33 | } 34 | } 35 | } 36 | 37 | onRef(ref) { 38 | this.refIframe = ref; 39 | } 40 | 41 | render() { 42 | const { width, height, code } = this.props; 43 | 44 | if (!code) { 45 | return null; 46 | } 47 | 48 | return ( 49 |