如何在SVG中使用对话框

 
如何在SVG中使用对话框与用户交互是SVG开发中常见的一个问题,SVG的窗口对象只提供了alert,confirm,prompt窗口方法,如何在SVG中创建和使用其它复杂对话框呢?解决的方法有几种:
 
1, 使用传统的HTML,其中嵌入SVG对象,使用HTML的窗口对象弹出网页对话框。例如在a.html中:
 
< html >< head >< title > SVG事件 </ title >
< body  >
< script language = " JavaScript "   >

function  changeColor()
{
        
var SvgMainMapDoc=id1.getSVGDocument();
              
        
var obj = new Object();
        obj.name
="51js";
        
var ret = window.showModalDialog("c.html",obj,"dialogWidth=300px;dialogHeight=300px");
        
//alert(ret);
        
        
var text1=SvgMainMapDoc.getElementById("text1");
        text1.setAttribute(
"stroke",ret);

}

</ script >
< embed name = " id1 "  pluginspage = " http://www.adobe.com/svg/viewer/install/ "  align = " top "  src = " 1.svg "  height = " 200px "  width = " 400px "  type = " image/svg+xml " >
< input type = " button "  value = " selectColor "  name = " color "  onclick = " changeColor() " >
</ body >
</ html >
 
c.html为要显示的网页对话框,其中也嵌入了SVG对象,这样就可以使用SVG创建对话框界面。在c.html中
< html >< head >< title > 查询SVG属性 </ title >
< body  >
< script language = " JavaScript "   >
    
// var obj = window.dialogArguments;
    
// alert("您传递的参数为:" + obj.name);
     
    
// var svgns = " http://www.w3.org/2000/svg ";
    var ret  =   " yellow " // Default
    window.returnValue = ret;
    
    function setColor(evt)
    
{
        var targetshape 
= evt.getTarget();
        ret 
= targetshape.getAttributeNS(null,"fill");
        
//alert(ret);
        window.returnValue=ret;
        
        var SvgMainMapDoc
=id1.getSVGDocument();
        
        var id
="text1";
        
        
if(SvgMainMapDoc.getElementById( id ).hasChildNodes() == true)
            SvgMainMapDoc.getElementById( id ).getFirstChild().setData( ret );
        
else
        
{
            NewItem 
= SvgMainMapDoc.createTextNode( ret )
            SvgMainMapDoc.getElementById( id ).appendChild(NewItem);
        }

        
        self.close()
    }

</ script >
< embed name = " id1 "  pluginspage = " http://www.adobe.com/svg/viewer/install/ "  align = " top "  src = " 3.svg "  height = " 200px "  width = " 400px "  type = " image/svg+xml " >
</ body >
</ html >
 
两个页面都嵌入了SVG,而且SVG可以调用这些Script,并传递和返回参数。
效果如下:
按下按钮后显示选择颜色对话框
在选择颜色关闭颜色对话框后,文字颜色变化为选择的颜色:
 
2, 使用SVG中的超级链接到另外一个SVG页面,但数据交互比较麻烦,一个可行的选择是通过剪贴板传递数据。该方法无法模拟使用模式对话框的情况,用户感觉也比较差,所以不推荐使用。
<a xlink:href="b.svg">
       <rect fill="black" pointer-events="all" x="60" y="930" width="280" height="40"/>
       <text x="70" y="965" font-size="36" stroke="none" fill="white" text-decoration="underline">Back to my blog</text>
       </a>
 
3, 使用SVG创建一个模拟的窗口,这种方法需要一些工作量。模拟窗口风格应当与常用的窗口风格相似,包括标题,标题栏,按钮,状态栏。窗口可以移动,包括一些控件。如果更进一步的化,窗口应当可以改变大小,最大化和最小化,以及一些窗口风格。
下面是一个最简单的对话框的窗口,可以移动和关闭,并放置一些按钮等。
代码如下:
< svg width = " 100% "  height = " 100% "  xmlns = " http://www.w3.org/2000/svg "  onload = " Init(evt) "  onmousedown = " Grab(evt) "   onmousemove = " Drag(evt) "   onmouseup = " Drop(evt) " >
   
< title > Dialog </ title >
   
< desc >
      Model dialog simulation.
   
</ desc >
   
< script type = " text/javascript " ><! [CDATA[
   
      var SVGDocument 
=   null ;
      var SVGRoot 
=   null ;
      var TrueCoords 
=   null ;
      var GrabPoint 
=   null ;
      var caption 
=   null ;
      var diaglog 
=   null ;
      var DragTarget 
=   null ;
      
      var test 
=   null ;
      var modelDialog 
=   false ;
      
   function Init(evt)
      
{
         SVGDocument 
= evt.target.ownerDocument;
         SVGRoot 
= SVGDocument.documentElement;

         
// these svg points hold x and y values...
         
//    very handy, but they do not display on the screen (just so you know)
         TrueCoords = SVGRoot.createSVGPoint();
         GrabPoint 
= SVGRoot.createSVGPoint();

    
//Get elements we need
         caption = SVGDocument.getElementById('winCap');
         dialog 
= SVGDocument.getElementById('dialog');
         modal 
= SVGDocument.getElementById('modal');
       }

   
   
   function Grab(evt)
   
{
       
// find out which element we moused down on
         var targetElement = evt.target;

         
// Drag on caption
         if ( caption == targetElement )
         
{
            DragTarget 
= dialog;//We want drag whole dialog;

            DragTarget.parentNode.appendChild( DragTarget ); 
//Show dialog

            DragTarget.setAttributeNS(
null'pointer-events''none');

            var transMatrix 
= DragTarget.getCTM();
            GrabPoint.x 
= TrueCoords.x - Number(transMatrix.e);
            GrabPoint.y 
= TrueCoords.y - Number(transMatrix.f);

         }

      }



      function Drag(evt)
      
{
         
// account for zooming and panning
         GetTrueCoords(evt);

         
// if we don't currently have an element in tow, don't do anything
         if (DragTarget)
         
{
            
// account for the offset between the element's origin and the
            
//    exact place we grabbed it... this way, the drag will look more natural
            var newX = TrueCoords.x - GrabPoint.x;
            var newY 
= TrueCoords.y - GrabPoint.y;

            
// apply a new tranform translation to the dragged element, to display
            
//    it in its new location
            DragTarget.setAttributeNS(null'transform''translate(' + newX + ',' + newY + ')');
         }

      }



      function Drop(evt)
      
{
    
         
if ( DragTarget )
         
{
           
            var targetElement 
= evt.target;

            
// turn the pointer-events back on, so we can grab this item later
            DragTarget.setAttributeNS(null'pointer-events''all');
    
            
// set the global variable to null, so nothing will be dragged until we
            
//    grab the next element
            DragTarget = null;
         }

      }



      function GetTrueCoords(evt)
      
{
         
// find the current zoom level and pan setting, and adjust the reported
         
//    mouse position accordingly
         var newScale = SVGRoot.currentScale;
         var translation 
= SVGRoot.currentTranslate;
         TrueCoords.x 
= (evt.clientX - translation.x)/newScale;
         TrueCoords.y 
= (evt.clientY - translation.y)/newScale;
      }

      
      function closeDialog(evt)
      
{
    dialog.setAttributeNS(
null'display''none');
    modelDialog 
= false;
      }

      
      
      function showDialog(evt)
      
{
          
if!modelDialog)
          
{    
              modal.setAttributeNS(
null'transform''translate(-200,-200)');
              modal.setAttributeNS(
null'fill-opacity''0.5');
              
               dialog.setAttributeNS(
null'transform''translate(200,200)');
              dialog.setAttributeNS(
null'display''inline');
              
              SVGRoot.appendChild( dialog );
              
modelDialog = true;
              
              
//alert("ok");
          }

      }

      
    ]]
></ script >
   
   
< def >
   
   
< linearGradient id = " linear1 " >
        
< stop offset = " 0% "  stop - color = " navy " />
        
< stop offset = " 100% "  stop - color = " blue " />
     
</ linearGradient >
        
   
</ def >
  
  
  
< rect id = ' BackDrop '  x = ' -10% '  y = ' -10% '  width = ' 110% '  height = ' 110% '  fill = ' none '  pointer - events = ' all '   />
   
   
< g id = " dialog "  x = " 100 "  y = " 100 "  display = " none " >
        
< rect id = " modal "   width = " 110% "  height = ' 110% '  fill = " white "  fill - opacity = " 0 " />     
        
< rect id = " winBody "   width = " 200 "  height = ' 150 '  stroke - width = " 2 "  stroke = " gray "  fill = " white " />     
         
         
< g >
             
< rect id = " winCap "  width = " 200 "  height = " 14 "  stroke - width = " 2 "  stroke = " gray "  fill = " url(#linear1) " />
            
< text pointer - events = " none "  transform = " translate(0,10) "  stroke = " white " > dialog </ text >    
        
</ g >  
        
        
< g id = " close "  onclick = " closeDialog(evt) " >
            
< a >
               
< rect  transform = " translate(189,1) "  width = " 10 "  height = ' 10 '  stroke = " white "  fill = " red " />
               
               
< g transform = " translate(191,2) " >
                  
< line  x1 = " 0 "  y1 = " 0 "  x2 = " 7 "  y2 = " 7 "  stroke - width = " 2 "  stroke = " white " />
                  
< line x1 = " 0 "  y1 = " 7 "  x2 = " 7 "  y2 = " 0 "  stroke - width = " 2 "  stroke = " white " />
              
</ g >
              
</ a >
          
</ g >
    
</ g >
   
   
      
< rect id = " button "  onclick = " showDialog(evt) "  x = " 100 "  y = " 100 "  width = " 60 "  height = ' 30 '  stroke - width = " 2 "  stroke = " black "  fill = " gray " />     
         
< circle cx = " 250 "  cy = " 250 "  r = " 1 "   >
    
< animate attributeName = " r "  from = " 1 "  to = " 50 "  dur = " 5s "  
                  repeatCount
= " indefinite "   />
  
</ circle >     
</ svg >
4, 使用SVG窗口类
http://www.carto.net 提供了一个交互窗口的脚本,可以生成SVG模拟窗口,我们只需要引入几个必要的脚本,就可以使用该窗口了,窗口除了提供上面描述的界面,还支持窗口消息回调函数,以建立复杂的基于SVG的WEB应用程序。具体的描述和下载地址为 http://www.carto.net/papers/svg/gui/Window/。此外该网站还有很多SVG的控件脚本,例如按钮,列表框等,很多有用的资源。下面是一个使用该窗口脚本的最简单的例子。
<? xml version = " 1.0 "  standalone = " no " ?>
<! DOCTYPE svg PUBLIC  " -//W3C//DTD SVG 1.1//EN "
  
" http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd " >
<? AdobeSVGViewer save = " snapshot " ?>
< svg width = " 100% "  height = " 100% "  viewBox = " 0 0 1024 700 "  onload = " init(evt) "  
xmlns:batik
= " http://xml.apache.org/batik/ext "  
xmlns:attrib
= " http://www.carto.net/attrib "  
xmlns:xlink
= " http://www.w3.org/1999/xlink "  
xmlns
= " http://www.w3.org/2000/svg "  
preserveAspectRatio
= " xMidYMid meet "  
zoomAndPan
= " magnify " >

        
< script type = " text/ecmascript "  xlink:href = " helper_functions.js " />
        
< script type = " text/ecmascript "  xlink:href = " mapApp.js " />
    
< script type = " text/ecmascript "  xlink:href = " timer.js " />
       
< script type = " text/ecmascript "  xlink:href = " Window.js " />
        
        
< script type = " text/ecmascript " ><! [CDATA[
        
           
// global variables for map application and navigation
           var myMapApp  =   new  mapApp();
           
        function init(evt) 
{
        
         
            
//start a new window array in myMapApp
            myMapApp.Windows = new Array();
            
            
//first a few styles
            var winPlaceholderStyles = {"fill":"none","stroke":"dimgray","stroke-width":1.5};
            var windowStyles 
= {"fill":"aliceblue","stroke":"dimgray","stroke-width":1};
            var titlebarStyles 
= {"fill":"gainsboro","stroke":"dimgray","stroke-width":1};
            var statusbarStyles 
= {"fill":"aliceblue","stroke":"dimgray","stroke-width":1};
            var titletextStyles 
= {"font-family":"Arial,Helvetica","font-size":14,"fill":"dimgray"};
            var statustextStyles 
= {"font-family":"Arial,Helvetica","font-size":10,"fill":"dimgray"};
            var buttonStyles 
= {"fill":"none","stroke":"dimgray","stroke-width":1};
            var titlebarHeight 
= 25;
            var statusbarHeight 
= 13;
            
            
//create new window instance and add it to the Windows array with the windowId as a key
            myMapApp.Windows["bigWindow"= new Window("bigWindow","Windows",
                
700,500,50,150,true,0,80,1024,700,true,
                winPlaceholderStyles,windowStyles,
3,true,true,
                
"Big Window","This is a big movable window",true,true,true,
                titlebarStyles,titlebarHeight,statusbarStyles,statusbarHeight,
                titletextStyles,statustextStyles,buttonStyles,undefined);
            myMapApp.Windows[
"smallWindow"= new Window("smallWindow","bigWindow",
                
200,180,350,300,true,0,17,700,487,true,
                winPlaceholderStyles,windowStyles,
3,true,true,
                
"Small Window","Callback function is active",true,false,false,
                titlebarStyles,titlebarHeight,statusbarStyles,statusbarHeight,
                titletextStyles,statustextStyles,buttonStyles,windowEvents);
                
            myMapApp.Windows[
"bigWindow"].appendContent("button",true);
            myMapApp.Windows[
"smallWindow"].appendContent("animate",true);
        }


        
        function windowEvents(id,evtType)
        
{
            }

            
        function openCloseWindow(id) 
{
            
if (myMapApp.Windows[id].closed) {
                myMapApp.Windows[id].open(
true);
            }

            
else {
                myMapApp.Windows[id].close(
true);
            }

        }

        
        
    ]]
></ script >

    
< rect id = " button "  onclick = " openCloseWindow('smallWindow') "  x = " 100 "  y = " 100 "  width = " 60 "  height = ' 30 '  stroke - width = " 2 "  stroke = " black "  fill = " gray " />     
    
< circle id = " animate "  cx = " 40 "  cy = " 40 "  r = " 1 "   >
        
< animate attributeName = " r "  from = " 1 "  to = " 30 "  dur = " 5s "  repeatCount = " indefinite "   />
    
</ circle >     
</ svg >

效果如下:

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值