I'm trying to learn how to build an interactive canvas from scratch, but I'm having trouble trying to draw things outside the canvas' viewport (things that exceed canvas.width and canvas.height). The goal is to have something like an infinite canvas where you can scroll and zoom and put things anywhere I want.
I figured out how to properly calculate the right insertion point when we zoomed out, the algorithm works like this:
see if the component should be added off the limits of the canvas;
if so, transform the offset (x, y) adding the distance between the point and the edge of the canvas.
I noticed that the event.pageX and event.pageY values are always given to me based on the width and height of the canvas, so if I'm zoomed out these values are, then, smaller than it should be (since I'm viewing more pixels). The transform algorithm work as follows in JS:
// pageX is 430, pageY is 480
// canvas has width=600 height=600
// scale is 0.6, meaning the canvas actually has size 360x360
var currentSize = canvas.width * scale; // 360
pageX = canvas.width + (pageX - currentSize);
pageY = canvas.width + (pageY - currentSize);
Drawing on paper this logic seem to work, but the problem is I (apparently) can't draw outside canvas limits, so I'm unable to see the result. Questions are:
The complete example I'm using to learn can be found on this fiddle.
I had another idea to solve the problem: instead of drawing things outside the canvas, I simply translate my points to fit inside the canvas' limits proportionally and then apply scale to zoom in/out. Something like this:
// canvas is 500x500
var points = [
{text: 'Foo', x: 10, y: 10},
{text: 'Bar', x: 854, y: 552}, // does not fit inside
{text: 'Baz', x: 352, y: 440}
];
// The canvas can't show all these points, the ideal
// would be having a canvas of at least size 900x600,
// so I can use a rule of three to convert all points
// from this imaginary canvas to fit inside my 500x500
// in 900px, x=10
// in 500px, x=?
// hence, the formulas are `newX=x * 500 / 900` and `newY = y * 500 / 600`
var converted_points = [
{text: 'Foo', x: 5.55, y: 8.33},
{text: 'Bar', x: 474.44, y: 460},
{text: 'Baz', x: 195.55, y: 366.66}
];
After that I suppose I would just need to scale/transform the canvas to do zooming. Is that logic ok?
You can use the library called TiledCanvas
It provides interfaces to zoom and move.
And draw in an infinite space using all the canvas apis.
It does require that you tell where you are drawing.
https://github.com/Squarific/TiledCanvas
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With