Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit b8cf2980d4b67a897e401e00d5a05d00fe4b3a41 @javierbyte committed May 12, 2016
Showing with 422 additions and 0 deletions.
  1. +8 −0 .babelrc
  2. +2 −0 .gitignore
  3. +17 −0 README.md
  4. +8 −0 dist/bundle.js
  5. +1 −0 dist/bundle.js.map
  6. +26 −0 index.html
  7. +41 −0 package.json
  8. +124 −0 src/App.js
  9. +5 −0 src/index.js
  10. +97 −0 styles/style.css
  11. +29 −0 webpack/devServer.js
  12. +27 −0 webpack/webpack.config.dev.js
  13. +37 −0 webpack/webpack.config.prod.js
@@ -0,0 +1,8 @@
+{
+ "presets": ["react", "es2015"],
+ "env": {
+ "development": {
+ "presets": ["react-hmre"]
+ }
+ }
+}
@@ -0,0 +1,2 @@
+node_modules
+*.log
@@ -0,0 +1,17 @@
+# React Minimal Starter
+
+* React.
+* React-Transform (hot reload).
+* Uglify.
+
+## Getting started.
+
+### Development.
+```
+npm start
+```
+
+### Production.
+```
+npm run build
+```
Oops, something went wrong.
Oops, something went wrong.
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
+
+ <title>DONTFORGETTOSETUPTHIS</title>
+ <meta property="og:title" content="DONTFORGETTOSETUPTHIS">
+
+ <meta name="description" content="DONTFORGETTOSETUPTHIS">
+ <meta property="og:description" content="DONTFORGETTOSETUPTHIS">
+
+ <link rel="canonical" href="DONTFORGETTOSETUPTHIS">
+ <meta property="og:url" content="DONTFORGETTOSETUPTHIS">
+
+ <meta property="og:image" content="DONTFORGETTOSETUPTHIS">
+
+ <link rel="stylesheet" href="styles/style.css">
+ </head>
+ <body>
+ <div id="root"></div>
+ <script src="dist/bundle.js"></script>
+ </body>
+</html>
@@ -0,0 +1,41 @@
+{
+ "name": "visual-center",
+ "version": "0.1.0",
+ "description": "",
+ "scripts": {
+ "clean": "rimraf dist",
+ "build:webpack": "cross-env NODE_ENV=production webpack --config webpack/webpack.config.prod.js",
+ "build": "npm run clean && npm run build:webpack",
+ "start": "node webpack/devServer.js",
+ "lint": "eslint src"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/javierbyte/visual-center"
+ },
+ "keywords": [],
+ "author": "Javier Bórquez <hi@javier.xyz> (http://github.com/javierbyte)",
+ "license": "CC0-1.0",
+ "homepage": "https://github.com/javierbyte/visual-center",
+ "devDependencies": {
+ "babel-core": "^6.6.5",
+ "babel-loader": "^6.2.4",
+ "babel-preset-es2015": "^6.3.13",
+ "babel-preset-react": "^6.3.13",
+ "babel-preset-react-hmre": "^1.1.1",
+ "cross-env": "^1.0.7",
+ "eventsource-polyfill": "^0.9.6",
+ "express": "^4.13.3",
+ "rimraf": "^2.4.3",
+ "webpack": "^1.12.9",
+ "webpack-dev-middleware": "^1.4.0",
+ "webpack-hot-middleware": "^2.9.1"
+ },
+ "dependencies": {
+ "base64-image-utils": "^0.1.1",
+ "lodash": "^4.12.0",
+ "react": "^15.0.2",
+ "react-dom": "^15.0.2",
+ "react-dropzone": "^3.4.0"
+ }
+}
@@ -0,0 +1,124 @@
+const React = require('react')
+const Dropzone = require('react-dropzone');
+const _ = require('lodash')
+
+const base64ImageUtils = require('base64-image-utils')
+const {base64ImageToRGBMatrix} = base64ImageUtils
+
+const App = React.createClass({
+
+ getInitialState() {
+ return {
+ image64: null
+ }
+ },
+
+ onDrop(fileArray) {
+ var file = fileArray[0]
+ var reader = new FileReader();
+
+ reader.addEventListener('load', data => {
+ this.processBase64(data.currentTarget.result);
+ }, false);
+
+ if (file) {
+ reader.readAsDataURL(file);
+ }
+ },
+
+ processBase64(base64) {
+ var bgColor = {
+ r: 255,
+ g: 255,
+ b: 255
+ }
+
+ base64ImageToRGBMatrix(base64, (err, rgbMatrix) => {
+ let height = rgbMatrix.length
+ let width = rgbMatrix[0].length
+
+ var rowWeight = []
+ var colWeight = []
+
+ let totalDiff = _.reduce(rgbMatrix, (resRow, rgbRow, rgbRowIdx) => {
+ var rowDiff = _.reduce(rgbRow, (resCol, rgbCol, rgbColIdx) => {
+ let colDiff = rgbDiff(bgColor, rgbCol)
+ colWeight[rgbColIdx] = colWeight[rgbColIdx] ? colWeight[rgbColIdx] + colDiff : colDiff
+ return resCol + colDiff
+ }, 0)
+
+ rowWeight[rgbRowIdx] = rowDiff
+ return resRow + rowDiff
+ }, 0)
+
+ let mediumRow = (() => {
+ let accumulated = 0
+ return _.findKey(rowWeight, (rowVal) => {
+ accumulated = accumulated + rowVal
+ return accumulated * 2 > totalDiff
+ })
+ })()
+
+ let mediumCol = (() => {
+ let accumulated = 0
+ return _.findKey(colWeight, (colVal) => {
+ accumulated = accumulated + colVal
+ return accumulated * 2 > totalDiff
+ })
+ })()
+
+ console.warn({totalDiff, mediumCol, mediumRow}, mediumCol / width, mediumRow / height)
+
+ this.setState({
+ base64: base64,
+ visualTop: mediumRow / height,
+ visualLeft: mediumCol / width
+ })
+ });
+ },
+
+ render() {
+ const {base64, visualTop, visualLeft} = this.state
+
+ return <div>
+ <div className='padding-2'>
+ <Dropzone onDrop={this.onDrop} className='dropzone'>
+ <div>Try drop or click to upload.</div>
+ </Dropzone>
+ </div>
+
+ <div className='demo-image-comparison'>
+ <div className='demo-image-container'>
+ <div className='demo-image-container-circle' />
+ <div className='demo-image-container-title'>
+ Element Center
+ </div>
+ <img src={base64} className='demo-image' style={{transform: 'translatey(-50%) translatex(-50%)'}}/>
+ </div>
+
+ <div className='demo-image-container'>
+ <div className='demo-image-container-circle' />
+ <div className='demo-image-container-title'>
+ Visual Center
+ </div>
+ <img src={base64} className='demo-image' style={{transform: `translatey(-${visualTop * 50 + 25}%) translatex(-${visualLeft * 50 + 25}%)`}}/>
+ </div>
+ </div>
+
+ <center className='padding-2'>
+ {base64 && `Visual center is at ${toPercent(visualLeft)}% - ${toPercent(visualTop)}%`}
+ </center>
+
+ </div>
+ }
+})
+
+function rgbDiff(baseColor, testColor) {
+ return (Math.abs(baseColor.r - testColor.r) + Math.abs(baseColor.g - testColor.g) + Math.abs(baseColor.b - testColor.b)) * testColor.a
+}
+
+function toPercent(number) {
+ return Math.round(number * 100000) / 1000
+}
+
+module.exports = App
@@ -0,0 +1,5 @@
+const React = require('react');
+const ReactDOM = require('react-dom');
+const App = require('./App');
+
+ReactDOM.render(<App />, document.getElementById('root'));
@@ -0,0 +1,97 @@
+* {
+ margin: 0;
+ padding: 0;
+ position: relative;
+}
+
+body {
+ font-family: 'Proxima Nova';
+ font-size: 1em;
+ line-height: 1.618;
+}
+
+.dropzone {
+ outline: 2px dashed #ccc;
+ padding: 2rem;
+}
+
+.padding-2 {
+ padding: 2rem;
+}
+
+.demo-image-comparison {
+ text-align: center;
+}
+.demo-image-container {
+ width: 39vmin;
+ height: 39vmin;
+ border: 1px solid #000;
+ margin: 5vmin 5vmin 0;
+ position: relative;
+ display: inline-block;
+}
+.demo-image-container-circle {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border-radius: 100%;
+ z-index: 10;
+ border:1px solid rgba(0,0,0,.1);
+}
+.demo-image-container-circle::after {
+ content: '';
+ display: block;
+ position: absolute;
+ top: 25%;
+ left: 25%;
+ width: 50%;
+ height: 50%;
+ border-radius: 100%;
+ z-index: 10;
+ border:1px solid rgba(0,0,0,.03);
+}
+.demo-image-container-title {
+ position: absolute;
+ top: -2rem;
+ left: 0;
+ width: 100%;
+ text-align: center;
+ z-index: 1;
+}
+.demo-image-container::before {
+ content: '';
+ display: block;
+ width: 100%;
+ height: 0;
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05);
+ position: absolute;
+ z-index: 3;
+ top: 50%;
+ left: 0;
+}
+.demo-image-container::after {
+ content: '';
+ display: block;
+ width: 0;
+ height: 100%;
+ border-right: 1px solid rgba(0, 0, 0, 0.05);
+ position: absolute;
+ z-index: 3;
+ top: 0;
+ left: 50%;
+}
+
+.demo-image {
+ max-width: 30vmin;
+ height: auto;
+ z-index: 2;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+}
+
+.demo-image:hover {
+ outline: 1px solid #f00;
+}
@@ -0,0 +1,29 @@
+var path = require('path');
+var express = require('express');
+var webpack = require('webpack');
+var config = require('./webpack.config.dev');
+
+var app = express();
+var compiler = webpack(config);
+
+app.use(require('webpack-dev-middleware')(compiler, {
+ noInfo: true,
+ publicPath: config.output.publicPath
+}));
+
+app.use(require('webpack-hot-middleware')(compiler));
+
+app.use('/styles', express.static('./styles'));
+
+app.get('*', function(req, res) {
+ res.sendFile(path.join(__dirname, '../index.html'));
+});
+
+app.listen(3000, function(err) {
+ if (err) {
+ console.log(err);
+ return;
+ }
+
+ console.log('Listening at http://localhost:3000');
+});
@@ -0,0 +1,27 @@
+var path = require('path');
+var webpack = require('webpack');
+
+module.exports = {
+ devtool: 'cheap-module-eval-source-map',
+ entry: [
+ 'eventsource-polyfill',
+ 'webpack-hot-middleware/client',
+ './src/index.js'
+ ],
+ output: {
+ path: path.join(__dirname, '../dist'),
+ filename: 'bundle.js',
+ publicPath: '/dist/'
+ },
+ plugins: [
+ new webpack.HotModuleReplacementPlugin(),
+ new webpack.NoErrorsPlugin()
+ ],
+ module: {
+ loaders: [{
+ test: /\.js$/,
+ loaders: ['babel'],
+ include: path.join(__dirname, '../src')
+ }]
+ }
+};
Oops, something went wrong.

0 comments on commit b8cf298

Please sign in to comment.