1

I use this code to resize my canvas width and height to the viewport of the browser

function scaleCanvas(){
    c.width = Math.max(document.documentElement.clientWidth,  window.innerWidth || 0); 
    c.height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
    drawMenu();
}

It works really great but now I want to put the Coordinates of my objects text etc in relations to the size of the canvas I tried this

// Canvas grösse
c.width = 1280;
c.height = 720;
// Text Schwer
var schwerx = 890;
var schwery = 52;
var schwerw = 100;
var schwerh = 30;
var schwerf = 22;
// Basis Höhe und Breite
var basex = 1280;
var basey = 720;
// Function Schwer
 function schwer(){
  var rx = schwerx / basex;
  var x = rx * c.width;
  var ry = schwery / basey;
  var y = ry * c.height;
  var rw = schwerw / basex;
  var w = rw * c.width;
  var rh = schwerh / basey;
  var h = rh * c.height;
   ctx.save();
   ctx.rotate(16.3*Math.PI/180);
   ctx.font = getFont();
   ctx.fillStyle = "#feec47";
   ctx.fillText('SCHWER', x, y, w, h);
   ctx.restore();
   function getFont() {
    var ratio = schwerf / basex;   
    var size = c.width * ratio;   
    return (size|0) + 'px Pokemon'; 
    }
}

This works great for the font size and on some Width and Heights of the canvas but not on all scales.

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • I'm not sure I understand, but shouldn't you be using `basey` in the font ratio? ( `var ratio = schwerf / basex;` ) since font size is based on font height, not width. – DBS Mar 28 '16 at 20:41
  • thats actually true thanks for that I wrote that at 4 am last night I wonder why that actually still works but position not – Michael Schramm Mar 28 '16 at 20:44
  • Fonts occupy a rectangle, and a string would return a rectangle of the dimensions it consumes. Perhaps both a var ratio = schwerf / basex; and var ratio = schwerf / basey; solution are needed, if you want to use extremes of canvas size. –  Mar 28 '16 at 21:23
  • so any one knows a solution how to calculate the coordinates in relation to canvas size ? – Michael Schramm Mar 29 '16 at 17:46

1 Answers1

1

You need to start with a base size which is used for calculations, say 1280x720 as in your code.

From there you need two factors, one for horizontal scaling and one for vertical.

Normalize current size using your base size - this will be the scale factors you use to scale the two dimensions:

var factorX = newWidth / baseWidth;
var factorY = newHeight / baseHeight;

You can now scale using one of two approaches: either scale transforming the scale of the context:

ctx.setTransform(factorX, 0, 0, factorY, 0, 0);

or generate new temporary points of the existing points:

var schwerx = 890;
var schwery = 52;
var nSchwerx *= factorX;
var nSchwery *= factorY;
etc...

If can be convenient to store these coordinates in an object or array so they can be processed using a for-loop.

In the case of fonts you will probably use transformation - it's possible to approximate the size without - here is one method which can be used with a bounding box to define the area the text should fit (predefined using the base size and the text/base font. A method to get the height of the font is shown in the same link).

Pros and cons

There are pros and cons with both: transformation matrix makes it easy to scale to any size without doing much with existing coordinates. However, it will also interpolate/resample the graphics so with large factors things will start to look blurry, text may look squeezed etc.

Scaling coordinates (path) will obtain full quality but requires a few more steps as well as being to maintain the original coordinates. It's also more complicated to get text to fit as its size is based on height and width will follow. Width may also be non-linear relative to height depending on the typeface and how it is optimized at the height it's being used, and will therefor require special treatment.

Community
  • 1
  • 1