zoom-canvas(n) 1.0 "Canvas with Zoom"

Name

zoom-canvas - a canvas-widget extension

Table Of Contents

Synopsis

Description

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.

zoom-canvas pathName ?option value...?

Coordinate Systems

With a basic canvas, you are used to work with 2 coordinate systems:

(C) Canvas Coord System

The native canvas coord system

(V) Viewport Coord System

The visible portion of canvas

With zoom-canvas you need to base your work on a 3rd coordinate system:

(W) World Coord System

The coord. system of your "world"

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.

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.

Coordinate Systems properties

(V) has origin (0,0) at the top-left corner of the 'visible' canvas-widget.

When you pick mouse-coords(%x,%y), these are expressed in (V)

(C) is the 'native' canvas-widget coord system.

There is a just a (dx,dy) translation between (C) and (V)

(W) is your-world coord system.

- 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)

WIDGET OPTIONS

***

zoom-canvas supports all canvas options with few exceptions: -scrollregion -confine -xscrollcommand -yscrollcommand -xscrollincrement -yscrollincrement

These options are useless since zoom-canvas provides better alternatives.

-userdata

it can be used for storing data

-zoomratio

A coefficient used for relative zoom (see rzoom)

-pointbmp

The default bitmap used for (next) point items. Note that argument should be the name of a predefined bitmap (e.g. a bitmap like "hourglass", "info", "quest_head" ... see Tk_GetBitmap), or the name of a file containing a bitmap, in standard X11 or X10 bitmap format. Filenames must be prefixed by @ (e.g. @/mybmps/start.xbm). The predefined bitmap is @/.../point.xbm, bundled within the package.

WIDGET COMMANDS

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:

pathName subCommand ?arg ...?

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.

pathName cget option

Returns the current value of the configuration option given by option. Option may have any of the values accepted by the zoom-canvas command.

pathName configure ?option? ?value option value ...?

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.

pathName W2C ?x0 y0 ...?
pathName W2C ?coordlist?
pathName C2V ?x0 y0 ...?
pathName C2V ?coordlist?
pathName W2V ?x0 y0 ...?
pathName W2V ?coordlist?
pathName V2C ?x0 y0 ...?
pathName V2C ?coordlist?
pathName C2W ?x0 y0 ...?
pathName C2W ?coordlist?
pathName V2W ?x0 y0 ...?
pathName V2W ?coordlist?

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.

pathName create point x y ?option value...?

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
pathName zoom

Get the current zoom-factor

pathName zoom zf

Set the current zoom-factor

pathName zoom zf ?Wx Wy?

Set zf as thecurrent zoom-factor with (Wx,Wy) as the origin of the zoom (i.e. (Wx,Wy) won't move).

pathName rzoom delta

Multiply-or-divide the zoom-factor by the -zoomration coefficient. If delta is positive, zoom-factor is multiplied, else it's divided

pathName rzoom delta ?Wx Wy?

same as above with (Wx,Wy) as the origin of the zoom

pathName overlap Wx Wy Vx Vy

collimate World-Point (Wx,Wy) with Viewport-Point (Vx,Vy)

pathName scrollviewport dWx dWy

scroll the viewport by dWx,dWy. Note that dWx,dWy are expressed in World-Coords

pathName zoomfit ?mode? ?Wx0 Wy0 Wx1 Wy1?

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).

BINDINGS

zoom-canvas provides built-in bindings for zooming and panning.

Dragging canvas items VS. Dragging the whole canvas

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

examples

 .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

EVENTS

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

Examples

  #  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]" }

Limitations

BUGS, IDEAS, FEEDBACK

Keywords

Snit, widget

Category

widgets