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/

