diff --git a/src/visualizers/FactorFence.ts b/src/visualizers/FactorFence.ts index 894dd33c..21780d98 100644 --- a/src/visualizers/FactorFence.ts +++ b/src/visualizers/FactorFence.ts @@ -359,9 +359,6 @@ class FactorFence extends P5Visualizer(paramDesc) { // no stroke (rectangles without borders) this.sketch.strokeWeight(0) this.sketch.frameRate(30) - - // Only need a couple of frames to start with: - this.stop(tryFrames) } /** md @@ -372,6 +369,29 @@ term that the mouse is above. Clicking a prime will set it as the persistent highlight value. You can drag the chart in any direction to pan the view. **/ + // Implementation notes: control events (keypresses and mouse gestures) are + // handled in this code in a slightly roundabout way: every draw() call + // checks whether a keypress is in effect and/or whether any mouse + // gestures are occurring, and handles them accordingly. But since the + // graph doesn't change except as a result of these actions (or the cache + // filling), the draw loop can generally stop. So the interaction checkers + // have to extend the draw loop if they fire. And then finally, since + // the draw loop tends to stop, pretty much all that the actual + // event-handling functions (mousePressed() etc, well below here in this + // file) have to do is restart the draw loop, and then the interaction + // checkers in draw() will actually implement the behaviors that should + // be invoked by those events. + // It might be more natural-seeming to implement the behaviors directly + // in the event-handling functions. That simpler scheme would likely work + // for the mouse events. However, it is unclear how, in that scheme, one + // could implement the behavior that the graph continues to zoom (or + // stretch or whatever) as you hold the corresponding key down. That's + // because you can only rely on a single keyPressed() event and a single + // keyReleased() event, no matter how long you hold a key down. + // So something has to run in the meantime and check if the key is still + // down, and it seems as though that has to be the draw() call. And + // as long as the draw() call is implementing the key controls, it seems + // that for consistency, it might as well do all the controls. mouseCheckDrag() { const movement = new p5.Vector(this.sketch.mouseX, this.sketch.mouseY) movement.sub(this.dragStart) @@ -381,6 +401,7 @@ highlight value. You can drag the chart in any direction to pan the view. this.dragging = true movement.mult(1 / this.scaleFactor) this.graphCorner = this.graphCornerStart.copy().add(movement) + this.extendLoop() } } @@ -404,37 +425,36 @@ In addition, several keypress commands are recognized: : 0.97 this.scaleFactor *= keyScale this.graphCorner.y = this.graphCorner.y / keyScale - } - /** md + } else if (this.sketch.keyIsDown(this.sketch.UP_ARROW)) { + /** md - up and down arrow: stretch the bars vertically - **/ - if (this.sketch.keyIsDown(this.sketch.UP_ARROW)) { + **/ // stretch up UP this.heightScale *= 1.03 - } - if (this.sketch.keyIsDown(this.sketch.DOWN_ARROW)) { + } else if (this.sketch.keyIsDown(this.sketch.DOWN_ARROW)) { // contract down DOWN this.heightScale *= 0.97 - } - /** md + } else if (this.sketch.keyIsDown(74)) { + /** md - J/I/K/L: pan the chart left/up/down/right - **/ - if (this.sketch.keyIsDown(74)) { + **/ // pan left J this.graphCorner.x -= 10 / this.scaleFactor - } - if (this.sketch.keyIsDown(76)) { + } else if (this.sketch.keyIsDown(76)) { // pan right L this.graphCorner.x += 10 / this.scaleFactor - } - if (this.sketch.keyIsDown(73)) { + } else if (this.sketch.keyIsDown(73)) { // pan up I this.graphCorner.y -= 10 / this.scaleFactor - } - if (this.sketch.keyIsDown(75)) { + } else if (this.sketch.keyIsDown(75)) { // pan down K this.graphCorner.y += 10 / this.scaleFactor + } else { + // no key we care about + return } + // Make sure that if we keep the key down, the drawing keeps adjusting: + this.extendLoop() } draw() { @@ -516,6 +536,8 @@ In addition, several keypress commands are recognized: // If we are waiting on elements or factorizations, extend lifetime if (this.collectFailed || this.firstFailure < barsInfo.maxBars) { this.extendLoop() + } else { + this.stop(tryFrames) } } @@ -677,12 +699,17 @@ In addition, several keypress commands are recognized: this.extendLoop() } + mouseDragged(event: MouseEvent) { + this.mouseLast = event + this.extendLoop() + } + mousePressed() { if (!this.mouseOnSketch()) return this.mouseDown = true this.dragStart = new p5.Vector(this.sketch.mouseX, this.sketch.mouseY) this.graphCornerStart = this.graphCorner.copy() - this.continue() + this.extendLoop() } mouseReleased() { diff --git a/src/visualizers/P5Visualizer.ts b/src/visualizers/P5Visualizer.ts index 4eedccc5..0180f04f 100644 --- a/src/visualizers/P5Visualizer.ts +++ b/src/visualizers/P5Visualizer.ts @@ -191,7 +191,11 @@ export function P5Visualizer(desc: PD) { ) { sketch[method] = (event: KeyboardEvent) => { const active = document.activeElement - if (active && active.tagName === 'INPUT') { + if ( + active + && (active.tagName === 'INPUT' + || active.tagName === 'TEXTAREA') + ) { return true } return this[method](event)