diff --git a/bootstrap.js b/bootstrap.js index 37bc760e2d6dfb5a0de93d03912d50535f4bd7ac..37a1596b74dc31b4c955170e7a2bd6ff1cea4edd 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -35,7 +35,7 @@ function bootloop() { // js u wyldin ! (this is probably slow) try { nrol.loop() - // this *is* definitely slow, we should probably run it on a second timer, but that can come + // this *is* definitely slow, we should probably run it on a second timer, but that can come if (scope) scope.check() } catch (err) { console.error('ERR @ top of loop:', err) @@ -75,6 +75,7 @@ window.onload = () => { console.log("VW completes refresh") // now we're ready to rumble: scope = new Scope($("#wrapper").get(0), tlv) + window.check = true // placement isn't here *just yet* // but should read these in when it does tlv.defs[0].position = { x: 250, y: 25 } diff --git a/core/scope.js b/core/scope.js index 5797bee3a37030a81af2eb2491379d25acd20f3f..875bb0e5efe2ff3089fdfadf3e54b5d2fa48e785 100644 --- a/core/scope.js +++ b/core/scope.js @@ -36,6 +36,9 @@ export default function Scope(wrapper, tlv) { dt.writeTransform(plane, dft) dt.writeBackgroundTransform(wrapper, dft) + // existence, but no checks yes, + window.check = false + /* --------------------------- ---------------------------- */ /* --------------------- USER LISTENERS ---------------------- */ /* --------------------------- ---------------------------- */ @@ -285,7 +288,7 @@ export default function Scope(wrapper, tlv) { // new plane every time! // handle to our context's container (the link) let ldef = context.exterior() - // this can happen, when i.e. upstairs is resetting / refreshing ... ? + // this can happen, when i.e. upstairs is resetting / refreshing ... ? if (!ldef) return //throw new Error("no apparent link container for this context") // things should now be redrawn, blocks.redrawDef(ldef) @@ -313,32 +316,35 @@ export default function Scope(wrapper, tlv) { } this.check = () => { - try { - // check levels recursively, - let recursor = (context) => { - checkView(context) - for (let def of context.defs) { - if (def.type == 'link') { - let interior = def.interior() - if (interior) { - let visible = $.contains(document, interior.plane) - if (interior.open && !visible) { - open(interior) - } - if (!interior.open && visible) { - close(interior) - } - if ($.contains(document, interior.plane)) { // have to check again, - recursor(interior) + if(window.check){ + try { + // check levels recursively, + let recursor = (context) => { + checkView(context) + for (let def of context.defs) { + if (def.type == 'link') { + let interior = def.interior() + if (interior) { + let visible = $.contains(document, interior.plane) + if (interior.open && !visible) { + open(interior) + } + if (!interior.open && visible) { + close(interior) + } + if ($.contains(document, interior.plane)) { // have to check again, + recursor(interior) + } } } } } + recursor(tlv) + window.check = false + } catch (err) { + console.error(err) + window.halt() } - recursor(tlv) - } catch (err) { - console.error(err) - window.halt() } } } diff --git a/hunks/image/readPNG.js b/hunks/image/readPNG.js index 590f0e9e011fe18bc2c5480be40e7d38f22dc209..49013c36fa1a3513be939c867e46e646dcad683f 100644 --- a/hunks/image/readPNG.js +++ b/hunks/image/readPNG.js @@ -1,7 +1,7 @@ /* hunks/image/readpng.js -gather PNG image from the aether +gather PNG image from the aether Jake Read at the Center for Bits and Atoms with Neil Gershenfeld and Leo McElroy (c) Massachusetts Institute of Technology 2019 @@ -11,9 +11,7 @@ displayed for any purpose, but must acknowledge the squidworks and cuttlefish pr Copyright is retained and must be preserved. The work is provided as is; no warranty is provided, and users accept all liability. */ -/* hunk template */ -// these are ES6 modules import { Hunkify, Input, Output, State } from "../hunks.js"; import { html, svg, render } from "https://unpkg.com/lit-html?module"; @@ -22,94 +20,63 @@ export default function UploadPNG() { // this fn attaches handles to our function-object, Hunkify(this); - // keeping these local globals, - let idealWidth = 395; // (want to pull width out of some API for this.dom - element width .. have resize..) - let localImageInfo = null; - let imageUpdated = false; - let localDpi = null - let dpiUpdated = false - - // it looks like 'RGBA' types are actually ImageData objects, - // https://developer.mozilla.org/en-US/docs/Web/API/ImageData - // since we will be using these in canvas-contexts, makes sense to just use these types - let imageOut = this.output("ImageData", "image") + let imgOut = this.output('ImageData', 'image') let dpiOut = this.output('number', 'dpi') - // as a hack, we can use boolean state variables as a button: they have handy callbacks... - const trig = new State("boolean", "release", false); - this.states.push(trig); + let trig = this.state('boolean', 'release', false) trig.onChange = (value) => { - // I'll set this flag so that we will release image info on the next loop - // if any is available, imageUpdated = true dpiUpdated = true - }; + trig.set(false) + } - // names for elements, - let canvasUid, inputItemUid; - - this.init = () => { - this.dom = $("<div>").get(0); - canvasUid = `${this.name}_canvas_dom`; - inputItemUid = `${this.name}_input`; - }; + let dom = this.document() + let canvas = $('<canvas>').get(0) // to draw, scaled-down, + let vcanvas = $('<canvas>').get(0) // to store / manipulate off screen and full size + let vcontext = vcanvas.getContext('2d') + // local datas, + let imageData = null + let imageUpdated = false + let idealWidth = 395 + // and dpi, + let imgDpi = 72 + let dpiUpdated = false - //import - const png_read_handler = e => { - const imageReader = new FileReader(); - const files = e.target.files; - const file = files[0]; - const img = new Image(); - img.file = file; - const imageLoader = aImg => e => { - // binary: - let raw = e.target.result - // useful: - aImg.src = raw; - aImg.onload = () => { - // OK: sometimes this image is *way too big* to dump into the DOM, - // so we write it into a new and virtual canvas that we won't render: - let virtualCanvas = $("<canvas>").get(0); - virtualCanvas.width = aImg.width; - virtualCanvas.height = aImg.height; - let vContext = virtualCanvas.getContext("2d"); - vContext.drawImage(aImg, 0, 0); - // great, now we can use this to pull normalized ImageData information, this is what we pass around: - localImageInfo = vContext.getImageData(0, 0, aImg.width, aImg.height); - imageUpdated = true; - // now we can draw something: - const canvas = document.getElementById(`${canvasUid}`); - // we'll want to shrink the whole thing ... or enlarge, - let scale = idealWidth / aImg.width; - // the height and width of the actual image, - canvas.width = aImg.width * scale; - canvas.height = aImg.height * scale; - // and then we draw into it, - const ctx = canvas.getContext("2d"); - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.scale(scale, scale); - ctx.drawImage(aImg, 0, 0); - }; - }; - imageReader.onload = imageLoader(img); - imageReader.readAsDataURL(file); - // and ah data version... - const headerLoader = (event) => { - console.log('e', event.target.result) - // https://gitlab.cba.mit.edu/pub/mods/blob/master/modules/read/png - // - // get DPI - // - // 8 header - // 4 len, 4 type, data, 4 crc - // pHYs 4 ppx, 4 ppy, 1 unit: 0 ?, 1 meter - // IEND - // + // write some startup DOM elements, + let button = $('<input type="file" accept="image/png">').on('input', (evt) => { + let file = evt.originalEvent.target.files[0] + if (!file) return + let imageReader = new FileReader() + imageReader.onload = (load) => { + let img = new Image() + img.src = load.target.result + img.onload = () => { + vcanvas.width = img.width + vcanvas.height = img.height + vcontext.drawImage(img, 0, 0) + // we can pull the nicely-formatted 'imageData' type from the context, + imageData = vcontext.getImageData(0, 0, img.width, img.height) + imageUpdated = true + // *and* we can draw at our ideal width, + let scale = idealWidth / img.width + canvas.width = img.width * scale + canvas.height = img.height * scale + let context = canvas.getContext('2d') + context.clearRect(0, 0, canvas.width, canvas.height) + context.scale(scale, scale) + context.drawImage(img, 0, 0) + $(dom).append(canvas) + } + } + imageReader.readAsDataURL(file) + // we also want to read PNG headers, this is more painful. + let rawReader = new FileReader() + rawReader.onload = (bin) => { + // s/o to Neil for this walker, var units = 0 var ppx = 0 var ppy = 0 - var dpi = 0 - var buf = event.target.result + var buf = bin.target.result var view = new DataView(buf) var ptr = 8 if (!((view.getUint8(1) == 80) && (view.getUint8(2) == 78) && (view.getUint8(3) == 71))) { @@ -136,60 +103,29 @@ export default function UploadPNG() { console.warn("no PNG units not found, assuming 72 DPI") ppx = 72 * 1000 / 25.4 } - localDpi = ppx * 25.4 / 1000 + imgDpi = ppx * 25.4 / 1000 dpiUpdated = true - if(localImageInfo){ - let width = localImageInfo.width * ((dpi*1000) / 25.4) - let height = localImageInfo.height * ((dpi*1000) / 25.4) + if (imageData) { + console.log(imageData) + let width = imageData.width * (imgDpi / 1000) / 25.4 + let height = imageData.height * (imgDpi / 1000) / 25.4 console.warn(`size in mm is w: ${width.toFixed(3)}, h: ${height.toFixed(3)}`) } - console.log('dpi', localDpi) + console.log('dpi', imgDpi) } - let headerReader = new FileReader() - headerReader.onload = headerLoader - headerReader.readAsArrayBuffer(file) - }; + rawReader.readAsArrayBuffer(file) + }) - this.onload = () => { - const target = $("<div>").get(0); - $(this.dom).append(target); - // to name unique DOM elements, if we want to access them later using 'get element' methods, - // we can prepend the hunk's name (which is unique) - const view = html ` - <style> - #${inputItemUid} { - margin: 5px; - } - #${canvasUid} { - border: 0px solid black; - margin: 5px; - } - </style> - <input - id=${inputItemUid} - type="file" - accept="image/png" - @input=${e => png_read_handler(e)}> - </input> - <canvas - id=${canvasUid} - width=100 - height=100> - </canvas> - `; - render(view, target); - }; + $(dom).append(button) this.loop = () => { - // we release data if we have any, if it's been updated, and if the output is clear: - if (localImageInfo && imageUpdated && !imageOut.io()) { - //console.log(`${this.name} puts:`, localImageInfo); - imageUpdated = false; - imageOut.put(localImageInfo); + if (imageData && imageUpdated && !imgOut.io()) { + imageUpdated = false + imgOut.put(imageData) } - if(localDpi && dpiUpdated && !dpiOut.io()){ + if(imgDpi && dpiUpdated && !dpiOut.io()){ dpiUpdated = false - dpiOut.put(localDpi) + dpiOut.put(imgDpi) } - }; + } } diff --git a/hunks/view.js b/hunks/view.js index 7802136c284ec00cb952c30b5f87b79f85ed008d..2bee4c445b6dd83f4ddbdb6124c117acaf006daa 100644 --- a/hunks/view.js +++ b/hunks/view.js @@ -124,6 +124,7 @@ export default function View() { // mostly, this is useful for any deleted hunks, or the refresh this.hasCompleteRedraw = false this.setCompleteRedraw = () => { + window.check = true this.hasCompleteRedraw = true } @@ -131,6 +132,7 @@ export default function View() { // atm, this wipes and redraws all connectivity in the context this.hasConnectivityChange = false let setConnectivityChange = (output) => { + window.check = true this.hasConnectivityChange = true } @@ -140,6 +142,7 @@ export default function View() { // callbacks - this is inconsistent, but change can come later this.hasDefUpdate = false let setDefUpdate = (index) => { + window.check = true // we have one, this.hasDefUpdate = true // it's this one @@ -153,6 +156,7 @@ export default function View() { // an oddity, we occasionally change positions, this.hasDefPositionUpdate = false let setDefReposition = (index) => { + window.check = true this.hasDefPositionUpdate = true if (defs[index]) { defs[index].hasPositionUpdate = true diff --git a/typeset.js b/typeset.js index 516a48efb254238e1bda42fe4840b61aea47b0d0..3f5bf75989763417d7e13fdabc9589b232a7d1d2 100644 --- a/typeset.js +++ b/typeset.js @@ -136,7 +136,7 @@ const TSET = [ } }, reference: function(bool){ - return bool + return bool } } }, { // booleanArray: 33, diff --git a/view/blocks.js b/view/blocks.js index 8e7cc0559fadfe68b64dae86c36005cff30befad..dc828ec8cb121b6039908c2a5f16bf5af98b4db2 100644 --- a/view/blocks.js +++ b/view/blocks.js @@ -144,6 +144,7 @@ let makeLink = (ldef, titleblock) => { $(ldef.squid).html('<i class="em em-shell"></i> collapse link') $(ldef.squid).one('click', (evt) => { context.open = false + window.check = true }) // redrawing here, so redraw them: context.setCompleteRedraw() @@ -170,6 +171,7 @@ let makeLink = (ldef, titleblock) => { $(ldef.squid).html('<i class="em em-squid"></i> open link') $(ldef.squid).one('click', (evt) => { context.open = true + window.check = true }) } } else if (ldef.upstream()){ @@ -205,6 +207,7 @@ let makeLink = (ldef, titleblock) => { $(ldef.squid).one('click', (evt) => { ldef.context.buildLinkContext(ldef).then((context) => { context.open = true + window.check = true }) }) }