mattdesl / canvas-sketch

[beta] A framework for making generative artwork in JavaScript and the browser.
MIT License
4.97k stars 393 forks source link

Rendering issue when using physical unit mm #159

Open Jlowzow opened 2 years ago

Jlowzow commented 2 years ago

When using mm as the unit for my sketch, I'm getting a rendering issue when drawing a line with lineWidth < 2. This looks similar to when drawing a line that is smaller than 2 pixels, even though a mm is a much bigger unit than the pixel.

Will I have to use px as the unit, and manually scale to prepare for a print?

Jlowzow commented 2 years ago

It seems the issue stems from drawing on a secondary canvas, and then using context.drawImage(), to place it on the canvas.

mattdesl commented 1 year ago

If you have a second canvas, you will probably want to set the size and scale to be the same. Example:

const canvasSketch = require('canvas-sketch');

const settings = {
  dimensions: [ 5, 5 ],
  units: 'cm',
  pixelsPerInch: 300,
  scaleToView: true
};

const sketch = () => {
  const offCanvas = document.createElement('canvas')
  const offContext = offCanvas.getContext('2d');

  return ({ context, width, height, canvasWidth, canvasHeight, scaleX, scaleY }) => {
    offCanvas.width = canvasWidth;
    offCanvas.height = canvasHeight;
    offContext.save();
    offContext.scale(scaleX, scaleY);

    // Now use the context as you'd render your sketch typically
    const grad = offContext.createLinearGradient(0, 0, width, height);
    grad.addColorStop(0, 'tomato')
    grad.addColorStop(1, 'palegreen')
    offContext.strokeStyle = grad;
    offContext.beginPath();
    offContext.lineTo(2, 2)
    offContext.lineTo(width-2, height-2)
    offContext.lineWidth = 2;
    offContext.lineCap = 'round';
    offContext.stroke();

    offContext.restore();

    context.fillStyle = 'white';
    context.fillRect(0, 0, width, height);

    context.drawImage(offCanvas, 0, 0, width, height);
    context.globalCompositeOperation = 'multiply';
    context.drawImage(offCanvas, width/4, width/4, width/2, height/2);
    context.globalCompositeOperation = 'source-over';
  };
};

canvasSketch(sketch, settings);

Let me know if that fixes things.