Hi Tom,

I found two different ways to do panoramas in svg.
Here is the first one : it uses some trigonometric functions in js, which I 
borrowed from M. Lane, University of Virginia's College at Wise.
As I'm not a mathematician nor a programmer, I tried to do the simplest code as 
possible (but it's rather long and messy, sorry).
The trick is simply to put the panoramic pictures twice, and to make the 
x-position of those pictures varry, so they are "following" each others.

Let me know what you think about this...

Cheers

Dom

Here is the code : 

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"  
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
<!-- thanks to David Lane Dept of Mathematics University of Virginia's College 
at Wise updated 19 Aug 06 -->
<svg xmlns="http://www.w3.org/2000/svg";
    xmlns:xlink="http://www.w3.org/1999/xlink"; 
xmlns:ev="http://www.w3.org/2001/xml-events";
    onload="Init( evt ); start(evt);" >
<script type="text/ecmascript">
//<![CDATA[

//this code is adapted from David Lane's js code  
//http://www.maa.org/joma/Volume7/Lane/Gallery.html
//thanks a lot !

var svgXLink = "http://www.w3.org/1999/xlink";;
var svgNS = "http://www.w3.org/2000/svg";;
var svgRoot;
var mouseP, newP, circP;
var bmousedown=0;
var radline;
var degtext;

function Init(){
    svgRoot  = document.documentElement;
    mouseP = svgRoot.createSVGPoint();
    newP = svgRoot.createSVGPoint();
    circP = svgRoot.createSVGPoint();
    radline  = document.getElementById("radline");
    circpoint  = document.getElementById("circpoint");
    mvm  = document.getElementById("mvm");
    mvm2  = document.getElementById("mvm2");
    mvm3  = document.getElementById("mvm3");
    mvm4  = document.getElementById("mvm4");
    compass  = document.getElementById("compass");
}

/* 
* Returns the mouse coordinates as an SVGPoint
*/
function getMouse(evt){
    var position = svgRoot.createSVGPoint();
    position.x = evt.clientX;
    position.y = evt.clientY;
    return position;
}
/* 
* Converts a mouse point to svg "user coordinates".
*/
function getUserCoordinates(p1){
    var p1;
    var p2 = svgRoot.createSVGPoint();
    p2.x = p1.x - 140;
    p2.y = 140 -p1.y;
    return p2;
}

/*
* Mouse functions for the "canvas" event listeners
*/

function onMouseDown(evt){
    bmousedown=1;
    mouseP=getMouse(evt);
    newP=getUserCoordinates(mouseP);
    doUpdate();
}
function onMouseMove(evt){
    if(bmousedown){
        mouseP=getMouse(evt);
        newP=getUserCoordinates(mouseP);
        doUpdate();
    }
}
function onMouseUp(evt){
    bmousedown=0;
}
<!-- je mets ici la version snap -->
function doUpdate(){
    var d = Math.sqrt(Math.pow(newP.x,2)+Math.pow(newP.y,2));
    var x,y,angle;
    var angled = Math.round(18000*getAngle(newP)/Math.PI)/100;
        angled = Math.round(angled/5)*5;
        angle = angled*Math.PI/180;
        circP.x = 100*Math.cos(angle);
        circP.y = 100*Math.sin(angle);
        x = Math.round(100000*Math.cos(angle))/100000;
        y = Math.round(100000*Math.sin(angle))/100000;
        angle = Math.round(100000*angle)/100000;
    circpoint.setAttributeNS(null, "cx", circP.x );
    circpoint.setAttributeNS(null, "cy", circP.y );
    radline.setAttributeNS(null, "x2", circP.x );
    radline.setAttributeNS(null, "y2", circP.y ); 
    var rotang = 1800*getAngle(newP)/Math.PI;
    mvm.setAttributeNS(null, "x", -900 + rotang);
    mvm2.setAttributeNS(null, "x",-900 + rotang);
    mvm3.setAttributeNS(null, "x", 180 -(rotang)/5);
    mvm4.setAttributeNS(null, "x", 180 -(rotang)/5);
    rotatestring="rotate("+-(180*getAngle(newP)/Math.PI)+")";
    compass.setAttributeNS(null, "transform", rotatestring);
    var number 
    if (angled <= 90){number = 90-(parseInt(angled))};
    if (angled > 90){number = 450-(parseInt(angled))};
    document.getElementById("tx_frame").firstChild.nodeValue="degrés : 
"+number+"°";
    if(number > 330 || number < 30) 
  {setPage('p01');}
  else if(number == 90) 
 {setPage('p02');}
   else if(number > 150 && number < 210)
   {setPage('p03');}
  else if(number > 240 && number < 300)
   {setPage('p04');}
   else
   {setPage('p05');}
}
function getAngle(p){
    var p, a;
    a=Math.atan2(p.y, p.x);
    if(a<=0){a=a+2*Math.PI;}
    return a;
}

// les fonctions pour changer de page
    var curPage = null; 
    function start(evt) {
        if ( window.svgDocument == null )
            svgDocument = evt.target.ownerDocument;
        curPage = svgDocument.getElementById("p01");
    }
    function setPage (page) {
        cible = svgDocument.getElementById(page);
        cible.setAttribute("display", "inline");
        if ((curPage != null)&&(curPage !== cible)) {
            curPage.setAttribute("display", "none");
        }
        curPage = cible;
    }

]]></script>
<defs>
      <path id="trgl"
         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 
fill="white" stroke="grey" />
      <path id="trglinv"
         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " 
fill="white" stroke="grey" transform="rotate(180)" />       
</defs>
<svg width="100%" height="100%" viewBox="0 0 960 475"> 
<!-- fond blanc -->
<rect width="100%" height="100%" fill="white" />
<clipPath id="view">

<rect width="960" height="345" />
</clipPath>
<g clip-path="url(#view)">
<!-- this pictures is borrowed from 
http://abraracourcix.rivallain.fr/~pampryl/tools/panorama/example.html. Please 
put your own to use this code -->
<image id="mvm" 
xlink:href="http://abraracourcix.rivallain.fr/~pampryl/tools/panorama/panorama-trestignel.jpg";
 width="3600" height="345" transform = "translate(-3599, 0)" />
<image id="mvm2" 
xlink:href="http://abraracourcix.rivallain.fr/~pampryl/tools/panorama/panorama-trestignel.jpg";
 width="3600" height="345" />
</g>
<clipPath id="miniview">
<rect width="720" height="72" />
</clipPath>
<svg x="50%" overflow="visible">
<g transform="translate(-360,375)" clip-path="url(#miniview)">
<image id="mvm2" 
xlink:href="http://abraracourcix.rivallain.fr/~pampryl/tools/panorama/panorama-trestignel.jpg";
 y="1" width="720" height="70" />
<rect id="mvm3" y="1" width="192" height="70" fill="none" stroke="lightblue" 
stroke-width="2" />
<rect id="mvm4" y="1" width="192" height="70" fill="none" stroke="lightblue" 
stroke-width="2" transform="translate(720,0)" />
</g>
</svg>

<text id="tx_frame" x="5" y="360">

degrés : 0°
</text>
<!-- les pages -->
<g transform="translate(800,60)">
    <g id="p01">
            <image y="-40" width="90" height="60" 
xlink:href="http://www.ethnographiques.org/IMG/jpg/aaa001.jpg";  />
            <text x="150" y="100" text-anchor="end">Commentaire 1</text>
      </g>
    <g id="p02"  display="none">

            <image y="-40" width="90" height="60" 
xlink:href="http://www.ethnographiques.org/IMG/jpg/aaa002.jpg";  />

            <circle cx="-400" cy="140" r="40" fill="none" stroke="salmon" 
stroke-width="2" stroke-dasharray="6,6" />
            <text x="150" y="100" text-anchor="end">Commentaire 2</text>
      </g>
     <g id="p03"  display="none">
            <image y="-40" width="90" height="60" 
xlink:href="http://www.ethnographiques.org/IMG/jpg/aaa003.jpg";  />
            <text x="150" y="100" text-anchor="end">Centre de gravité !</text>

                <circle cx="-150" cy="50" r="30" fill="none" stroke="salmon" 
stroke-width="2" stroke-dasharray="4,4" />
                <line x1="-150" y1="100" x2="-40" y2="300" stroke="lightblue" 
stroke-width="2" stroke-dasharray="2,3,4,5" />

      </g>

    <g id="p04"  display="none">
            <image y="-40" width="90" height="60" 
xlink:href="http://www.ethnographiques.org/IMG/jpg/aaa004.jpg";  />

            <text x="150" y="100" text-anchor="end">Technique de 
réception</text>
            <rect x="-200" y="150" width="60" height="60" fill="none" 
stroke="lightgrey" />

      </g>
    <g id="p05"  display="none">

            <!-- vide -->
      </g>
</g>
</svg>
<!-- éléments à taille fixe -->
<!-- boussole -->
<rect x="140" y="115" width="150" height="50" fill="lightgrey" />
    <g transform="translate(140,140)">
    <circle fill="none" stroke="lightgrey" stroke-dasharray="8.72,8.72" 
stroke-dashoffset="4.36" cx="0" cy="0" r="100"/>

    <g id="compass" transform="rotate(-90)"> 
    <g id="trgls" opacity="0.3">
    <use xlink:href="#trgl" y="100" transform="rotate(-70)" />

    <use xlink:href="#trglinv" y="100" transform="rotate(-110)" />
    </g>
    <circle cx="0" cy="0" r="40" fill="white" />
    <line x1="0" y1="-25" x2="0" y2="25" stroke="black" />
    <line x1="-25" y1="0" x2="0" y2="0" stroke="black" />
      <text x="45" y="-5" fill="white">Ouest</text>

      <text x="45" y="-5" fill="white" transform="rotate(90)">Nord</text>
      <text x="45" y="-5" fill="white" transform="rotate(180)">Est</text>

      <text x="45" y="-5" fill="white" transform="rotate(270)">Sud</text>
    </g>
    </g>
<!-- controls -->
<g transform="matrix(1, 0, 0, -1, 140, 140)">
        <line x1="-110" y1="0" x2="110" y2="0" stroke="grey" />

        <line x1="0" y1="-110" x2="0" y2="110" stroke="grey" />
    <line id="radline" stroke="black" stroke-width="1" x1="0" y1="0" x2="0" 
y2="100" />
    <circle id="circpoint" stroke="black" stroke-width="1" fill="white" cx="0" 
cy="100" r="10" />

    <circle stroke="black" stroke-width="1" fill="white" cx="0" cy="0" r="5"/>
    <circle id="canvas" fill="none" stroke="#0088dd" stroke-width="70" 
stroke-opacity="0" cx="0" cy="0" r="100"   
        pointer-events="visible"
        
onmouseover="document.getElementById('trgls').setAttribute('opacity','0.9')"
        
onmouseout="document.getElementById('trgls').setAttribute('opacity','0.3')"
        onmousedown="onMouseDown(evt)"
        onmousemove="onMouseMove(evt)"
        onmouseup="onMouseUp(evt)"/>
    </g>
</svg>


--- In [email protected], Tom Sparks <tom_a_spa...@...> wrote:
>
> --- On Tue, 9/3/10, ddailey <ddai...@...> wrote:
> 
> From: ddailey <ddai...@...>
> Subject: Re: [svg-developers] panorama viewer using SVG
> To: [email protected]
> Received: Tuesday, 9 March, 2010, 5:35 AM
> 
> 
> >I am just wondering if a panorama viewer like this[1] can be done in SVG? 
> 
> > [1] http://www.krpano. com/krpano. html?pano= panos/kirche/ kirche.xml
> 
> 
> 
> >I can confess to having wondered the same thing, as I am not quite sure >how 
> >those 360 degree rotation things work (nor the data structure of the 
> >>underlying images  -- I gather there are spherical file formats, but 
> >>neither HTML5 nor SVG has provisions for reading them, let alone dealing 
> >>with them.
> 
> >I haven't had a chance to look under the hood of any of those 3D thingies 
> >>(most of which seem to be Java-applets) but if you can do it in an applet 
> >>then you can probably do it in SVG+JavaScript.
> 
> a lot of panorama are in the Equirectangular or cubic 
> ( http://wiki.panotools.org/Panorama_formats )
> 
> Equirectangular can be viewed by using shpere mapping ( 
> http://en.wikipedia.org/wiki/Sphere_mapping )
> 
> cubic can be viewed by using cube mapping  ( 
> http://en.wikipedia.org/wiki/Cube_mapping )
> >cheers
> 
> >David
>




------------------------------------

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

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/svg-developers/join
    (Yahoo! ID required)

<*> To change settings via email:
    [email protected] 
    [email protected]

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