I am using canvas to draw a letter "A" and the character is supposed to be filled with the glyph that user chooses from the panel. It can be a '*', '-', or '.'
Right now I have '*' as default but it doesn't update when the input changes.
This is how it looks in the browser
This is what I am trying but not sure how to write the logic inside the createPane function or how to complete the getGlyph() function. Any ideas?
These are the two solutions I am trying:
Solution 1
const canvasSketch = require('canvas-sketch');
const { Pane } = require('tweakpane')
const settings = {
dimensions: [ 1080, 1080 ]
};
const params = {
glyph: '*'
};
let manager;
let text = 'A';
let fontSize = 1200;
let fontFamily = 'serif';
const typeCanvas = document.createElement('canvas');
const typeContext = typeCanvas.getContext('2d');
const sketch = ({ context, width, height }) => {
const cell = 20;
const cols = Math.floor(width / cell);
const rows = Math.floor(height / cell);
const numCells = cols * rows;
typeCanvas.width = cols;
typeCanvas.height = rows;
return ({ context, width, height }) => {
typeContext.fillStyle = 'black';
typeContext.fillRect(0, 0, cols, rows);
fontSize = cols;
typeContext.fillStyle = 'white';
typeContext.font = `${fontSize}px ${fontFamily}`;
typeContext.textBaseline = 'top';
const metrics = typeContext.measureText(text);
const mx = metrics.actualBoundingBoxLeft * -1;
const my = metrics.actualBoundingBoxAscent * -1;
const mw = metrics.actualBoundingBoxLeft + metrics.actualBoundingBoxRight;
const mh = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent;
const tx = (cols - mw) * 0.5 - mx;
const ty = (rows - mh) * 0.5 - my;
typeContext.save();
typeContext.translate(tx, ty);
typeContext.beginPath();
typeContext.rect(mx, my, mw, mh);
typeContext.stroke();
typeContext.fillText(text, 0, 0);
typeContext.restore();
const typeData = typeContext.getImageData(0,0, cols, rows).data;
console.log(typeData);
context.fillStyle = 'black';
context.fillRect(0, 0, width, height);
context.textBaseline = 'middle';
context.textAlign = 'center';
context.drawImage(typeCanvas, 0, 0);
for(let i = 0; i < numCells; i++) {
const col = i % cols;
const row = Math.floor(i / cols);
const x = col * cell;
const y = row * cell;
const r = typeData[ i * 4 + 0];
const g = typeData[ i * 4 + 1];
const b = typeData[ i * 4 + 2];
const a = typeData[ i * 4 + 3];
const glyph = getGlyph(r, params);
context.font = `${cell * 2}px ${fontFamily}`;
context.fillStyle = 'white';
context.save();
context.translate(x,y);
context.translate(cell * 0.5, cell * 0.5);
context.fillText(glyph, 0, 0);
context.restore();
}
};
};
const getGlyph = (v, params) => {
if(v < 50) return '';
// Check the selected glyph from the params object
const selectedGlyph = params.glyph;
// Return the corresponding glyph based on the user selection
if (selectedGlyph === '*') {
return '*';
} else if (selectedGlyph === '-') {
return '-';
} else if (selectedGlyph === '.') {
return '.';
}
// Return a default glyph if none of the options match
return '';
}
const createPane = () => {
const pane = new Pane();
let folder;
folder = pane.addFolder({ title: 'Choose glyph' });
folder.addInput(params, 'glyph', { options: { '*': '*', '-': '-', '.': '.' } });
}
createPane();
const onKeyUp = (e) => {
text = e.key.toUpperCase();
manager.render();
}
document.addEventListener('keyup', onKeyUp);
const start = async () => {
manager = await canvasSketch(sketch, settings);
}
start();
Solution 2:
const createPane = () => {
const pane = new Pane();
const folder = pane.addFolder({ title: 'Choose glyph' });
folder.addInput(params.glyph, 'star').on('change', () => {
manager.render();
});
folder.addInput(params.glyph, 'dash').on('change', () => {
manager.render();
});
folder.addInput(params.glyph, 'dot').on('change', () => {
manager.render();
});
};