From 69bbae861aea23a5bd5b0c0411af12c84357ba64 Mon Sep 17 00:00:00 2001 From: Andreas Fried Date: Sat, 22 Jun 2019 15:19:51 +0200 Subject: [PATCH 1/4] Cleanup whitespace. --- src/App.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/App.js b/src/App.js index e0f1a9d..7837142 100644 --- a/src/App.js +++ b/src/App.js @@ -19,7 +19,7 @@ export default class App extends Component { } } -class Machine extends Component { +class Machine extends Component { constructor(props) { super(props); this.interpreter = new Interpreter(300); @@ -65,7 +65,7 @@ class Machine extends Component { } ) } - + random() { const wasRunning = this.state.running; this.reset() @@ -163,7 +163,7 @@ class Machine extends Component { ins_pointer: new_state.ins_pointer, mem_pointer: new_state.mem_pointer }); - + } From 4a1697ea6cce913490d7ab7d59a776cf362c1a94 Mon Sep 17 00:00:00 2001 From: Andreas Fried Date: Sat, 22 Jun 2019 15:21:50 +0200 Subject: [PATCH 2/4] Use a canvas for the pixels instead of generating divs. In order to make this look good, we need the browser to scale the canvas without interpolation. The CSS at least works for current Firefox, not at all sure about other browsers. --- src/App.js | 49 +++++++++++++++++++++---------------------------- src/index.css | 8 ++------ 2 files changed, 23 insertions(+), 34 deletions(-) diff --git a/src/App.js b/src/App.js index 7837142..61ea184 100644 --- a/src/App.js +++ b/src/App.js @@ -294,40 +294,33 @@ class SourceBox extends Component { } class Bitmap extends Component { - render() { + componentDidMount() { + this.updateCanvas(); + } + + componentDidUpdate() { + this.updateCanvas(); + } + + updateCanvas() { const mem = this.props.memory; + const ctx = this.refs.canvas.getContext("2d"); - // var pixels = Array(Math.floor(mem.length / 3)) - const pixels = mem.map((v, i, l) => i % 3 == 0 ? : null).filter(v => v); - -// for (var i=0; i -// ) -// } - return ( -
- {pixels} -
- ) + for (var y = 0; y < 10; y++) { + for (var x = 0; x < 10; x++) { + var r = mem[30 * y + 3 * x + 0]; + var g = mem[30 * y + 3 * x + 1]; + var b = mem[30 * y + 3 * x + 2]; + + ctx.fillStyle = "rgb("+r+","+g+","+b+")"; + ctx.fillRect(x, y, 1, 1); + } + } } -} -class Pixel extends Component { render() { - const {r, g, b} = this.props; - const style = { - backgroundColor: `rgb(${r}, ${g}, ${b})`, - } return ( -
+ ) } } diff --git a/src/index.css b/src/index.css index 189009c..61394b8 100644 --- a/src/index.css +++ b/src/index.css @@ -117,12 +117,8 @@ body { .bitmap { width: 100%; line-height: 0; -} - -.pixel { - display: inline-block; - width: 10%; - padding-bottom: 10%; + image-rendering: pixelated; + image-rendering: -moz-crisp-edges; } .pointer { From 6f1e517befd735bd6144b63dd8eb383985c211ee Mon Sep 17 00:00:00 2001 From: Andreas Fried Date: Sat, 22 Jun 2019 17:21:34 +0200 Subject: [PATCH 3/4] Add waterfall display mode. It's alright but here are some issues to consider for the future: - The DOM is stateful in waterfall mode (we store the previous states only in the canvas pixels). - Moving the speed slider causes spurious updates. - The patterns look very different depending on the amount of steps skipped per line. --- src/App.js | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/src/App.js b/src/App.js index 61ea184..b21779f 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,6 @@ import React, { Component } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faPause, faPlay, faRandom, faStop, faStepForward, faTachometerAlt, faRuler } from '@fortawesome/free-solid-svg-icons'; +import { faPause, faPlay, faRandom, faStop, faStepForward, faTachometerAlt, faRuler, faTh, faAngleDoubleDown } from '@fortawesome/free-solid-svg-icons'; import Interpreter from './brainfuckInterpreter'; @@ -30,6 +30,7 @@ class Machine extends Component { speed: 300, running: false, locked: false, + isWaterfall: false, memory: machine_state.memory, ins_pointer: machine_state.ins_pointer, mem_pointer: machine_state.mem_pointer @@ -166,6 +167,12 @@ class Machine extends Component { } + setWaterfallMode(mode) { + this.setState({ + isWaterfall: mode + }); + } + render() { let box; @@ -184,12 +191,17 @@ class Machine extends Component {
+ { this.state.isWaterfall + ? this.setWaterfallMode(false)} icon={faTh}>Switch to Grid Mode + : this.setWaterfallMode(true)} icon={faAngleDoubleDown}>Switch to Waterfall Mode + } this.random()} icon={faRandom}>New Sample this.reset()} icon={faStop}/> { ! this.state.running @@ -303,6 +315,14 @@ class Bitmap extends Component { } updateCanvas() { + if (this.props.waterfall) { + this.updateCanvasWaterfall(); + } else { + this.updateCanvasGrid(); + } + } + + updateCanvasGrid() { const mem = this.props.memory; const ctx = this.refs.canvas.getContext("2d"); @@ -318,9 +338,32 @@ class Bitmap extends Component { } } + updateCanvasWaterfall() { + const mem = this.props.memory; + const ctx = this.refs.canvas.getContext("2d"); + + const image = ctx.getImageData(0, 1, ctx.canvas.width, ctx.canvas.height-1); + ctx.putImageData(image, 0, 0); + + for (var x = 0; x < 100; x++) { + var r = mem[3 * x + 0]; + var g = mem[3 * x + 1]; + var b = mem[3 * x + 2]; + + ctx.fillStyle = "rgb("+r+","+g+","+b+")"; + ctx.fillRect(x, 99, 1, 1); + } + } + render() { - return ( - - ) + if (this.props.waterfall) { + return ( + + ) + } else { + return ( + + ) + } } } From 1bd626f2bd825642bfbbae63f2a993809454324b Mon Sep 17 00:00:00 2001 From: Andreas Fried Date: Fri, 9 Aug 2019 22:51:19 +0200 Subject: [PATCH 4/4] Shorten button text. --- src/App.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/App.js b/src/App.js index b21779f..ef21efb 100644 --- a/src/App.js +++ b/src/App.js @@ -199,8 +199,8 @@ class Machine extends Component {
{ this.state.isWaterfall - ? this.setWaterfallMode(false)} icon={faTh}>Switch to Grid Mode - : this.setWaterfallMode(true)} icon={faAngleDoubleDown}>Switch to Waterfall Mode + ? this.setWaterfallMode(false)} icon={faTh}>Grid + : this.setWaterfallMode(true)} icon={faAngleDoubleDown}>Waterfall } this.random()} icon={faRandom}>New Sample this.reset()} icon={faStop}/>