0

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();
  });
};

0 Answers0