zoom-canvas - a canvas-widget extension
zoom-canvas is an extension of the canvas-widget aimed to make more easy to display and operate on large canvas. It provides a builtin interactive zoom&panning.
With zoom-canvas, you are no more forced to resize your scene (world-model) when it's larger than the canvas viewport; You only need to adjust the zoom factor and the viewport will display a scaled portion of the scene.
That's all about it. Zoom and Pan !
The zoom-canvas command creates the pathName widget and returns a new Tcl command whose name is pathName.
With a basic canvas, you are used to work with 2 coordinate systems:
With zoom-canvas you need to base your work on a 3rd coordinate system:
There's one simple rule:
You should always think in terms of World-Coords, but remember to operate in terms of Canvas-Coords.
There're new methods for converting between (W) (C) (V), you should use when drawing or moving items.
W2C - from (W) to (C)
C2V - from (C) to (V)
W2V - from (W) to (V)
and the inverse
V2C - from (V) to (C)
C2W - from (C) to (W)
V2W - from (V) to (W)
A preliminary example: Draw a small circle with radius 1 micron (1E-6 meters)
.c create oval [.c W2C -1E-6 -1E-6 1E-6 1E-6]
Note this is independent of the current zoom-factor; you can change the zoom-factor and then draw another identical circle with the same command.
When you pick mouse-coords(%x,%y), these are expressed in (V)
There is a just a (dx,dy) translation between (C) and (V)
- It is mapped onto (C) with a scale tranformation (f,-f).
- Note that Y axis is upward oriented (whilst in (C) and (V) is downward oriented).
- You can change the zoom-factor both interactively (mousewheel) and by program.
- You can also 'pan' the viewport both interactively (drag) and by program
* Some more properties *
Note: arguments of W2C, W2V ... are 2d-points -
W2C {0,0} = {0,0}
W2C( {ax,ay} + {bx,by} ) = W2C {ax,ay} + W2C {bx,by}
W2C(a*{ax,ay}) = a*W2C {ax,ay}
- W2C is a linear transformation
C2V({ax,ay} + {bx,by}) = {ax,ay} + C2V {bx,by}
therefore
C2V {ax,ay} = C2V({ax,ay}+{0,0}) = {ax,ay} + C2V {0,0}
W2V(A) = C2V(W2C(A)) = W2C(A) + C2V(0)
The zoom-canvas command creates a widget and a new Tcl command whose name is pathName. This command may be used to invoke various operations on the widget. It has the following general form:
The following subCommands are possible for zoom-canvas widgets:
All canvas commands are supported with few exceptions canvasx, canvasy, xview, yview
These options are useless since zoom-canvas provides better alternatives.
Returns the current value of the configuration option given by option. Option may have any of the values accepted by the zoom-canvas command.
Query or modify the configuration options of the widget. If no option is specified, returns a list describing all of the available options for pathName (see Tk_ConfigureInfo for information on the format of this list). If option is specified with no value, then the command returns a list describing the one named option (this list will be identical to the corresponding sublist of the value returned if no option is specified). If one or more option-value pairs are specified, then the command modifies the given widget option(s) to have the given value(s); in this case the command returns an empty string. Option may have any of the values accepted by the zoom-canvas command.
Conversion between coord-systems. Note that parameters may be specified either as a sequence of coord-pairs, either as a list of coord-pairs. Result is a list of coord-pairs.
Create a point (actually a small bitmap) located at canvas-coord (x,y) Options are those of canvas-bitmap-item-type. If you omit the -bitmap option, the default-bitmap is used (see -pointbmp option).
# create a point at WorldCoord (11,22) .c create point [.c W2C 11 22] # create a point with a new bitmap .c create point [.c W2C 100 200] -bitmap @/mybmps/special.xbm # create a RED point (with default bmp) and then change it to yellow set id [.c create point [.c W2C 200 200] -foreground red] .c itemconfigure $id -foreground yellow
Get the current zoom-factor
Set the current zoom-factor
Set zf as thecurrent zoom-factor with (Wx,Wy) as the origin of the zoom (i.e. (Wx,Wy) won't move).
Multiply-or-divide the zoom-factor by the -zoomration coefficient. If delta is positive, zoom-factor is multiplied, else it's divided
same as above with (Wx,Wy) as the origin of the zoom
collimate World-Point (Wx,Wy) with Viewport-Point (Vx,Vy)
scroll the viewport by dWx,dWy. Note that dWx,dWy are expressed in World-Coords
find the best zoom so that all the canvas-items (or those enclosed by Wx0 Wy0 Wx1 Wy1) will be visible. mode can be x (best-width) y (best-height) xy (best fit).
zoom-canvas provides built-in bindings for zooming and panning.
zooming Rotate the Mouse-wheel. Note that the zoom coefficient may by adjusted with the -zoomratio configuration option.
panning Press Left-Button and drag
Since "pressing mouse button-1 and dragging" is the builtin mechanism used for moving the whole canvas (panning), if you want to use this same "natural" mechanism for moving single canvas-items, you should observe the following conventions:
add the special tag draggable to every item that can be moved.
bind <B1-Motion> to some draggable items ...
$zoomCvs bind draggable <B1-Motion> { ... move item ...} ; # OK
.zc bind all <B1-Motion> { ... move item ...} ; # WRONG !
.zc bind Dog <B1-Motion> { ... move item ...} ; # ... maybe WRONG; see the next
.zc bind draggable&&Dog <B1-Motion> { ... move item ...} ; # OK
.zc bind 333 <B1-Motion> { ... move item ...} ; # KO if item 333 is not draggable.
If you won't follow these simple rules, you'll get a *combined* item-move with a canvas move (panning) . That's caos.
If you follow these rules, then
when you drag over a draggable item, you move the item
when you drag over a not-draggable item, or over "nothing", you move the canvas.
If you don't like these conventions, you should use different kry-events for dragging items and dragging canvas, e.g <B1> for panning <B2> for moving items
Event <<Zoom>> is generated when zoom changes. This virtual-event carries some data that may be caught in binding script by the %d substitution keyword. Parameter %d holds the new zoom factor
# create and display
pack [zoom-canvas .c -background orange] -fill both -expand true
# set the zoom-factor to 0.3x (centered on (0,0))
.c zoom 0.3
#
### Draw a polyline (0,0) (1000,1000) (-2000,-1000)
# Since the above coords are world-coords, you should transform them with W2C
.c create line [.c W2C (0,0) (1000,1000) (-2000,-1000)]
#
### Move all items having tag "RED" by (500,200) (in world coords)
# Since the above coords are world-coords, you should transform them with W2C
.c move RED [.c W2C 500 200]
#
### When you pick a point (x,y) on the visible canvas (V), you should convert it to (W)
#
.c bind <Button-1> { puts "You picked [%W V2W %x %y]" }
item-text, item-images and item-window won't zoom !
line's width (thickness) won't zoom.
rotate ? that'impossible until ovals and rectangles won't change
Snit, widget
widgets
Copyright © 2013, by A.Buratti