hi Jeroen,

> Zoom & Pan operations on SVG maps are quite common. Mostly those 
> operations are implemented changing the viewBox attributes. 

the problem is that viewBox manipulations are incompatible with 
currentScale/Translate because on every setting of new viewBox values 
currentScale/Translate gets set to 1,0,0 whatever they may have been set 
before. you should never mix those two methods, unless you know exactly 
what you do (btw i never saw an example doing that and this may be a 
stong enough argument...)


> Is it 
> possible to achieve the same effect using currentScale and 
> currentTranslate? 

yes.

> Not for example on the root svg element, which mostly 
> represents a user interface, but on the svg element which represents the 
> map. 

no, that cannot work because currentScale/Translate always act on (or 
represent the state of) the outermost svg, the root element. the way to 
go is to have your main content zoomed as ever you want and apply 
inverse transformations (for <g>s) or inverse screenCTMs (for inner 
<svg>s) to the parts that are acting as "fixed" interface containers.

> If so, why haven't I seen it yet?
>   

because it is tricky. there are samples out there but these are not easy 
to break down in a 5-lines sample script. all this is explained in book 
coming out feb 2006, but it will be in german first (but you should be 
able to read it, judging based on your last name...) here is a short 
description <http://www.huethig.de/shop/product.html?id=146899&top=1>, 
the companion website will go online jan 2006 at <http://svg.carto.net/> 
(may be offline these times).

in order to not let you here without an answer, i'll try to give short 
hints.

first you need an svg doc with content and interface elements, something 
like this helps you to get an interface that will always be expressed in 
screen coordinates (pixel).

<svg width="100%" height="100%" ...><!--viewBox here -->
<svg id="myMap" width="100%" height="100%"
viewBox="437000 –4788000 146000 226000"/>
...
</svg>
<svg id="myInfoBlock" ... viewBox="0 0 180 520" />
...
</svg>
</svg>



if you want do a zoom from the interface centered on the actual 
position, you call this:


function myDoZoom(val){
var myOldScale = myDocElem.currentScale;
var oldTranslate = {
x : myDocElem.currentTranslate.x,
y : myDocElem.currentTranslate.y
}

myDocElem.currentScale *= val; // RELATIVE FACTOR

myDocElem.currentTranslate.x = myViewportWidth / 2
– (myDocElem.currentScale / myOldScale)
* (myViewportWidth / 2 – oldTranslate.x);
myDocElem.currentTranslate.y = myViewportHeight / 2
– (myDocElem.currentScale / myOldScale)
* (myViewportHeight / 2 – oldTranslate.y);
}


a pan may look like this (here with a fixed jump factor, but a 
zoom-dependent factor would be better


function myDoPan(myX,myY){
var myCurrTransl = myDocElem.currentTranslate;
var myStep = 30;
myX *= myStep;
myY *= myStep;
myCurrTransl.x += myX;
myCurrTransl.y += myY;
}


a reset to the initial view is the easiest one:


function myDoReset(){
myDocElem.currentScale = 1;
myDocElem.currentTranslate.x = 0;
myDocElem.currentTranslate.y = 0;
}


now how to make your inner svg (your interface element) stay in place? 
that's not that hard. the values 0 and 200 being the upper left anchor 
of the container element, it being width="520" and height="180". the 
function needs to be called onzoom on the root element.



function myHandleZoomPan(evt){
var myInfoBlock = document.getElementById('myInfoBlock');
myInfoBlock.setAttributeNS(null,'x',
(200 – myCurrTransl.x) / myDocElem.currentScale);
myInfoBlock.setAttributeNS(null, 'y',
(0 – myCurrTransl.y) / myDocElem.currentScale);
myInfoBlock.setAttributeNS(null,'width',180/myDocElem.currentScale);
myInfoBlock.setAttributeNS(null,'height',520/myDocElem.currentScale);
}


if your interface container is a group, the function looks a bit different:


function myHandleZoomPan(evt){
var myCurrTransl = myDocElem.currentTranslate;
var myTransform = 'scale(' + 1 / myDocElem.currentScale + ') '
+ 'translate(' + (–yCurrTransl.x)
+ ', ' + (–myCurrTransl.y) + ')';
document.getElementById('myInfoBlockGroup')
.setAttributeNS(null, 'transform', myTransform);
myUpdateDisplays();
}


hope this helps for a start, note that this is copy&paste code out of 
the book i mentioned, there may be variables to be defined first. these 
example was tested on FF1.5, ASV3.x and Batik Squiggle 1.6.



-- 
___________________________________________________________________
andre m. winter,
  cartography for internet and multimedia applications
  schiessstand 4/1, a6091 goetzens, tyrol, austria
  tel.: ++43.5234.32732
  email: <[EMAIL PROTECTED]>

<http://www.vectoreal.com/>          SVG consulting and development
<http://www.carto.net/>          online cartography focusing on SVG
<http://www.carto.at/>     print and online touristic map solutions 




------------------------ Yahoo! Groups Sponsor --------------------~--> 
1.2 million kids a year are victims of human trafficking. Stop slavery.
http://us.click.yahoo.com/.QUssC/izNLAA/TtwFAA/1U_rlB/TM
--------------------------------------------------------------------~-> 

-----
To unsubscribe send a message to: [EMAIL PROTECTED]
-or-
visit http://groups.yahoo.com/group/svg-developers and click "edit my 
membership"
---- 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/svg-developers/

<*> To unsubscribe from this group, send an email to:
    [EMAIL PROTECTED]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/
 



Reply via email to