I have some code in the p5.js editor that is not responding to keyTyped()
or keyPressed()
events. A slider interface element is also not responding. Possibly it’s an issue with the browser, but other interface elements do respond, and the focus seems to be on the canvas and its frame. Here’s the URL: SignalToImage.
A short test example works without a problem: keyTyped test.
Here’s the code:
// keyTyped function is not responding
// slider (created in initUI function) is also not responding
// they work in other, simpler, examples: https://editor.p5js.org/Ignotus_Mago/sketches/CvGN07-Hr
var img = []; // array of color values in bitmap row major order
var sig = []; // array of color values in Hilbert curve order
var hilbDepth = 5; // maximum value of 6, to draw curve clearly
var hilbCount; // number of rows or columns in the grid
// for hilbDepth of 2, sigLUT should be [0,1,5,4,8,12,13,9,10,14,15,11,7,6,2,3]
var sigLUT = []; // look up table for index numbers into the img array
var imgLUT = []; // look up table for index numbers into the sig array
var w = 512;
var h = 512;
var loadSignal = true;
var showPath = false;
var bitmapBtn;
var hilbertBtn;
var canv;
function setup() {
canv = createCanvas(w, h);
frameRate(30);
var hilb = new HilbGen(hilbDepth);
hilbCount = hilb.d; // number of rows or columns in the grid
if (hilbCount > w/16) console.log("hilbDepth should not exceed 6.");
imgLUT = hilb.indexMap;
for (let i = 0; i < imgLUT.length; i++) {
sigLUT[imgLUT[i]] = i;
}
console.log("sigLUT: ", sigLUT);
console.log("imgLUT: ", imgLUT);
console.log("hilb.indexMap: ", hilb.indexMap);
gridW = w/hilbCount; // width of grid elements
gridH = h/hilbCount; // height of grid elements
gridHalf = gridW/2; // half the width of an element
initSignal();
initUI();
}
function draw() {
if (frameCount % 30 == 1) rotateData();
if (showPath) drawSignalPath();
}
function initSignal() {
let steps = sigLUT.length;
let ang = 45;
let inc = 360/steps;
colorMode(HSL, 360, 100, 100);
if (loadSignal) {
for (let i = 0; i < sigLUT.length; i++) {
let c = color((ang + round(i * inc)) % 360, 60, 50); // generate color spectrum
sig[i] = c; // assign current color to sig
img[sigLUT[i]] = c; // map the same color to img
}
}
else {
for (let i = 0; i < sigLUT.length; i++) {
let c = color((ang + round(i * inc)) % 360, 60, 50); // generate color spectrum
img[i] = c; // assign current color to img
sig[imgLUT[i]] = c; // map the same color to sig
// console.log("image index", imgLUT[i], hue(c));
}
}
fillSquares();
}
function initUI() {
let txt1 = createDiv('Click on the canvas to flip a color.');
txt1.position(12, 524);
let txt2 = createDiv('Animate: ');
txt2.position(12, 548);
hilbertBtn = createButton("Hilbert");
hilbertBtn.id('hilbert');
hilbertBtn.position(80, 548);
hilbertBtn.mousePressed(animateHilbert);
if (loadSignal) hilbertBtn.hide();
bitmapBtn = createButton("Bitmap");
bitmapBtn.id('bitmap');
bitmapBtn.position(80, 548);
bitmapBtn.mousePressed(animateBitmap);
if (!loadSignal) bitmapBtn.hide();
let resetBtn = createButton("Reset");
resetBtn.id('reset');
resetBtn.mousePressed(() => {
loadSignal = true; initSignal(); bitmapBtn.show(); hilbertBtn.hide()});
resetBtn.position(12, 572);
let pathCheckbox = createCheckbox(" Draw Path", showPath);
pathCheckbox.id('path');
let xPos = 12 + resetBtn.width + 32;
pathCheckbox.position(xPos, 572);
pathCheckbox.mouseReleased(() => {showPath = !showPath;});
let txt3 = createDiv("FPS");
txt3.id('fps');
xPos += 200;
txt3.position(xPos, 572);
// SLIDER is not working
let animSlider = createSlider(1, 120, 10);
animSlider.id('anim');
animSlider.size(120);
xPos += 40;
animSlider.position(xPos, 572);
}
function rotateData() {
// to rotate array the other direction: sig.push(sig.shift());
if (loadSignal) {
sig.unshift(sig.pop()); // rotate sig array
mapSigToImg();
}
else {
img.unshift(img.pop()); // rotate img array
mapImgToSig();
}
push();
fillSquares();
pop();
}
function drawSignalPath() {
push();
stroke(255);
noFill();
strokeWeight(1);
beginShape();
for (let i = 0; i < sigLUT.length; i++) {
let p = sigLUT[i];
let x = p % hilbCount * gridW + gridHalf;
let y = floor(p/hilbCount) * gridH + gridHalf;
vertex(x,y);
}
endShape();
pop();
}
function fillSquares() {
for (let i = 0; i < sigLUT.length; i++) {
// get the index number stored at sigLUT[i]
let p = sigLUT[i];
// convert the index to coordinates
let x = p % hilbCount * gridW;
let y = floor(p/hilbCount) * gridH;
// get the color value from sig[i]
fill(sig[i]);
noStroke();
square(x, y, gridW);
}
}
function mousePressed() {
if (pointInCanvas(mouseX, mouseY)) {
// get x and y coordinates, scale to the grid
let x = floor(mouseX/gridW);
let y = floor(mouseY/gridH);
// console.log(mouseX, mouseY, x, y);
// convert the coordinates into index value p for imgLUT
let p = x + y * hilbCount;
// retrieve the index value i for sigLUT from imgLUT
let i = imgLUT[p];
// get the color from sig[i]
let c = sig[i];
// console.log("----->>> p = "+ p +", i = "+ i +", c = "+ c);
colorMode(HSL, 360, 100, 100);
let h = Math.floor(hue(c));
console.log("--->> new hue:", h);
c = color((h + 180) % 360, 90, 80);
sig[i] = c;
img[sigLUT[i]] = c;
fillSquares();
}
return false;
}
// NOT responding
function keyTyped() {
console.log("--->> key "+ key);
return false;
}
function pointInCanvas(x, y) {
return (x >= 0 && x <= width && y >= 0 && y <= height);
}
function animateHilbert() {
if (!loadSignal) writeImgToSig();
loadSignal = true;
bitmapBtn.show();
hilbertBtn.hide();
}
function animateBitmap() {
if (loadSignal) writeSigToImg();
loadSignal = false;
hilbertBtn.show();
bitmapBtn.hide();
}
function mapImgToSig() {
for (let i = 0; i < img.length; i++) {
sig[imgLUT[i]] = img[i];
}
}
function mapSigToImg() {
for (let i = 0; i < sig.length; i++) {
img[sigLUT[i]] = sig[i];
}
}
function writeImgToSig() {
for (let i = 0; i < img.length; i++) {
sig[i] = img[i];
}
}
function writeSigToImg() {
for (let i = 0; i < sig.length; i++) {
img[i] = sig[i];
}
}
// LUT generator class creates the lookup table for Hilbert curve
class HilbGen {
constructor(depth) {
this.depth = depth;
this.d = round(pow(2, depth));
this.n = this.d * this.d;
console.log("--->> HilbGen: ", this.depth, this.d, this.n);
this.bertX = 0;
this.bertY = 0;
this.indexMap = [this.n];
this.doXYSwap = (depth % 2 == 1);
this.generateMap();
}
generateMap() {
let index = 0;
for (let i = 0; i < this.n; i++) {
this.d2xy(this.n, i);
index = this.bertX + this.d * this.bertY;
// console.log(i, "index "+ index +", bertX "+ this.bertX +", bertY "+ this.bertY);
this.indexMap[index] = i;
}
}
d2xy(pts, pos) {
let rx = 0;
let ry = 0;
let t = pos;
let s = 0;
this.bertX = 0;
this.bertY = 0;
for (let s = 1; s < pts; s *= 2) {
rx = 1 & (floor(t/2));
ry = 1 & (floor(t ^ rx));
this.rot(s, rx, ry);
this.bertX += s * rx;
this.bertY += s * ry;
t = floor(t/4);
}
if (this.doXYSwap) {
this.swapXY();
}
}
swapXY() {
let temp = this.bertY;
this.bertY = this.bertX
this.bertX = temp;
}
rot(s, rx, ry) {
if (ry == 0) {
if (rx == 1) {
this.bertX = s - 1 - this.bertX;
this.bertY = s - 1 - this.bertY;
}
// swap bertX and bertY
this.swapXY()
}
}
}
And the short example:
var canv;
function setup() {
canv = createCanvas(400, 400);
makeSlider();
}
function draw() {
background(220);
}
function keyTyped() {
console.log("keyTyped function: key", key);
}
function makeSlider() {
let animSlider = createSlider(1, 120, 10);
animSlider.id('anim');
animSlider.size(120);
animSlider.position(12, 428);
}
I’ve tried such strategies as HTMLElement.focus(animSlider)
, for the slider, only to throw an error. Focus may not be the problem, anyhow. Commenting out my drawing code also failed to let me detect key presses – this is really odd, but seems to mean that the animation is probably not blocking events.
Any hints on how to proceed are most welcome. If I can solve it in the p5.js Editor, that would be great. It makes it easy to share code. But perhaps the editor is part of the problem – though other code to detect key presses seems to run just fine.
ciao,
Paul