From 134bfdbd4f5693a0d7695d44037ca6cfa91b4c86 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Sat, 26 Oct 2019 11:58:23 -0700 Subject: [PATCH] Add sidebar to view pixel colors on hover. --- package.json | 2 + public/index.html | 2 +- src/App.css | 15 +++-- src/App.js | 138 ++++++++++++++++++++++++++++++++++------------ src/index.css | 11 ++++ src/index.js | 1 + yarn.lock | 35 ++++++++---- 7 files changed, 152 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index 06eecbd..2c7043e 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,9 @@ "version": "0.1.0", "private": true, "dependencies": { + "babel-loader": "8.0.6", "react": "^16.10.2", + "react-bulma-components": "3.1.3", "react-dom": "^16.10.2", "react-scripts": "3.2.0" }, diff --git a/public/index.html b/public/index.html index c240d2c..41c0a6e 100644 --- a/public/index.html +++ b/public/index.html @@ -24,7 +24,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + Tracer Debug App diff --git a/src/App.css b/src/App.css index 4bf7260..c906927 100644 --- a/src/App.css +++ b/src/App.css @@ -1,9 +1,3 @@ -html, body, #root { - background-color: #000; - color: #fff; - height: 100%; -} - .App { text-align: center; } @@ -14,3 +8,12 @@ html, body, #root { text-shadow: 0 0 4px #000, 0 0 8px #000 ; cursor: crosshair; } + +.title { + color: #fff; +} + +.value { + text-align: center; + border: 1px solid #888; +} diff --git a/src/App.js b/src/App.js index e94d21c..6587254 100644 --- a/src/App.js +++ b/src/App.js @@ -1,8 +1,69 @@ import React from 'react'; import './App.css'; +import { + Columns, + Heading, + Media, +} from 'react-bulma-components'; + const ROOT = process.env.PUBLIC_URL + '/tracer/'; const DATA_URL = ROOT + 'data.json'; +const MAX_ZOOM_FACTOR = 32; + +const Sidebar = (props) => { + let {binary, imageMetadata, zoomFactor, x, y, onZoom} = props; + let samples = imageMetadata.map((md) => { + let pix = binary[md.name]; + if (pix === undefined) { return

Loading...

; } + let [w, h] = md.size; + let xOff = Math.min(w, Math.max(0, Math.round(x*w))); + let yOff = Math.min(h, Math.max(0, Math.round(y*h))); + let v = pix[xOff+yOff*w]; + if (v === undefined) { + console.log(`${x} ${y} ${w} ${h} ${xOff} ${yOff} ${v} ${pix.length}`); + return

Loading...

; + } + let rgb = ""; + let value = ""; + if (md.format === "RGB01") { + let r = Math.round(v[0]*255); + let g = Math.round(v[1]*255); + let b = Math.round(v[2]*255); + rgb = `rgb(${r}, ${g}, ${b})`; + value = rgb; + } else { + rgb = `rgb(${v}, ${v}, ${v})`; + value = v; + } + return
+

{md.name}

+

{value}

+
+ }); + return ; +} class App extends React.Component { constructor(props) { @@ -13,7 +74,7 @@ class App extends React.Component { isFetching: false, isFrozen: false, isZoomed: false, - zoomFactor: 16, + zoomFactor: 4, x: 0, y: 0, }; @@ -34,15 +95,15 @@ class App extends React.Component { if ((data === null) || (data.timestamp !== result.timestamp)) { this.setState({data: result, isFetching: false}); - result.image_metadatum.forEach((md) => { - let binary_url = ROOT + md.binary; - fetch(binary_url) + result.imageMetadata.forEach((md) => { + let binaryUrl = ROOT + md.binary; + fetch(binaryUrl) .then(response => response.json()) .then(result => { - let cur_binary = this.state.binary; + let curBinary = this.state.binary; this.setState({binary: { [md.name]: result, - ...cur_binary + ...curBinary }}); }) .catch(e => console.log(e)); @@ -54,9 +115,9 @@ class App extends React.Component { .catch(e => console.log(e)); } render() { - console.log(this.state.binary); - let imgs = []; + let images = []; let { + binary, data, isFrozen, isZoomed, @@ -64,9 +125,10 @@ class App extends React.Component { y, zoomFactor, } = this.state; - let appContent =

Loading

; + let mainContent =

Loading

; + let sidebarContent =

Loading

; if (data !== null) { - let {timestamp, image_metadatum} = data; + let {timestamp, imageMetadata} = data; const mouseClick = (e) => { console.log('isFrozen', isFrozen, 'this.state.isFrozen', this.state.isFrozen); this.setState({isFrozen: !this.state.isFrozen}); @@ -81,7 +143,9 @@ class App extends React.Component { let delta = parseFloat(-e.deltaY/100.0); let zoomFactor = delta + this.state.zoomFactor; if (zoomFactor < 1) { zoomFactor = 1; } - if (zoomFactor > 24) { zoomFactor = 24; } + if (zoomFactor > MAX_ZOOM_FACTOR) { + zoomFactor = MAX_ZOOM_FACTOR; + } this.setState({ zoomFactor: zoomFactor, isZoomed: true @@ -93,9 +157,13 @@ class App extends React.Component { } this.setState({isZoomed: false}); }; - imgs = image_metadatum.map((metadata) => { + const onZoom = (e) => this.setState({ + zoomFactor: Number(e.target.value) + }); + + images = imageMetadata.map((metadata) => { let {name, size, ratio, image} = metadata; - let width = 512; + let width = 256; let height = (ratio * width).toFixed(); let url = ROOT + image + '?t=' + timestamp; const mouseMove = (e) => { @@ -111,7 +179,7 @@ class App extends React.Component { width: width + 'px', height: height + 'px', imageRendering: isZoomed ? 'pixelated' : 'auto', - backgroundSize: isZoomed ? zoomFactor * size[0] + 'px ' + zoomFactor * size[1] + 'px' : 'contain', + backgroundSize: isZoomed ? zoomFactor * width + 'px ' + zoomFactor * height + 'px' : 'contain', backgroundPosition: isZoomed ? 100*x + '% ' + 100*y + '%' : 'center center', }; return ( @@ -126,29 +194,29 @@ class App extends React.Component {

{name}

) }); - appContent =

Run @ {new Date(timestamp * 1000).toLocaleString()}

{imgs}
; + mainContent =
+ + Run @ {new Date(timestamp * 1000).toLocaleString()} + + {images} +
; + + sidebarContent = ; } return ( -
-
- - {zoomFactor} -
-
- {appContent} -
-
+ + + {sidebarContent} + + + {mainContent} + + ); } } diff --git a/src/index.css b/src/index.css index 4a1df4d..80693ed 100644 --- a/src/index.css +++ b/src/index.css @@ -11,3 +11,14 @@ code { font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace; } + +html { + background-color: #000; +} + +html, body, #root { + background-color: #000; + color: #fff; + height: 100%; +} + diff --git a/src/index.js b/src/index.js index 87d1be5..d8331bb 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; +import 'react-bulma-components/dist/react-bulma-components.min.css'; import './index.css'; import App from './App'; import * as serviceWorker from './serviceWorker'; diff --git a/yarn.lock b/yarn.lock index 73c8e37..7e407c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1974,6 +1974,10 @@ builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" +bulma@0.7.5: + version "0.7.5" + resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.7.5.tgz#35066c37f82c088b68f94450be758fc00a967208" + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -2170,6 +2174,10 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +classnames@2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + clean-css@4.2.x: version "4.2.1" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" @@ -7012,6 +7020,13 @@ react-app-polyfill@^1.0.4: regenerator-runtime "0.13.3" whatwg-fetch "3.0.0" +react-bulma-components@3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/react-bulma-components/-/react-bulma-components-3.1.3.tgz#8dee9697d66f5ead92244fac6ef6b2fe3d1c8b71" + dependencies: + bulma "0.7.5" + classnames "2.2.6" + react-dev-utils@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-9.1.0.tgz#3ad2bb8848a32319d760d0a84c56c14bdaae5e81" @@ -7042,14 +7057,14 @@ react-dev-utils@^9.1.0: strip-ansi "5.2.0" text-table "0.2.0" -react-dom@16.10.2: - version "16.10.2" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.10.2.tgz#4840bce5409176bc3a1f2bd8cb10b92db452fda6" +react-dom@^16.10.2: + version "16.11.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.11.0.tgz#7e7c4a5a85a569d565c2462f5d345da2dd849af5" dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.16.2" + scheduler "^0.17.0" react-error-overlay@^6.0.3: version "6.0.3" @@ -7119,9 +7134,9 @@ react-scripts@3.2.0: optionalDependencies: fsevents "2.0.7" -react@16.10.2: - version "16.10.2" - resolved "https://registry.yarnpkg.com/react/-/react-16.10.2.tgz#a5ede5cdd5c536f745173c8da47bda64797a4cf0" +react@^16.10.2: + version "16.11.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.11.0.tgz#d294545fe62299ccee83363599bf904e4a07fdbb" dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -7516,9 +7531,9 @@ saxes@^3.1.9: dependencies: xmlchars "^2.1.1" -scheduler@^0.16.2: - version "0.16.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.16.2.tgz#f74cd9d33eff6fc554edfb79864868e4819132c1" +scheduler@^0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.17.0.tgz#7c9c673e4ec781fac853927916d1c426b6f3ddfe" dependencies: loose-envify "^1.1.0" object-assign "^4.1.1"