I have two JSVGCanvas, one on top of the other. The
bottom JSVGCanvas is used for displaying an SVG document. The upper is used as
an overlay for drawing. They are both transparent.
The ultimate goal is to turn the user drawing into
an SVG, but I won't do that until the user asks, so basically I have a buch of
Shape objects hanging around in memory. No problem so far. The SVG drawing is
just sitting there, in the bottom canvas, with a bunch of shapes drawn on the
Things get nasty when the user tries to interact
with the SVG canvas. Following some ideas discussed with Thomas a while ago, I
overwrite setRenderingTransform() and setPaintingTransform() in the SVG canvas
and propagate the current transform to the overlay canvas. Since the overlay
canvas just has a bunch of Shapes all I have to do is apply the same transform
to its graphics context to make the Shapes move or zoom with the SVG canvas.
Below is the paint() method of the overlay canvas.
public void paint(Graphics g)
Graphics2D g2d = (Graphics2D)g;
AffineTransform at =
getPaintingTransform(); // Get the transform applied in the
SVG canvas (user is interacting with it)
if (at != null)
g2d.transform(at); // Applies the transform to the
overlay graphics context
drawShapes(g2d); // Redraws all shapes using the
However, the final result does not look good:
it always looks like the overlay canvas is a few milliseconds behind, as if it
was waiting for the SVG canvas to render before redrawing. So, when you pan, it
looks like the overlay is trying to catch up with the SVG.
Is there a better form of synchronizing the
overlay? I'd like to reach the same effect as the SelectionOverlay in
Many thanks for any