新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   >>中国XML论坛<<     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论SVG, GML, X3D, VRML, VML, XAML, AVALON, Batik等基于XML的图形技术,以及有关GIS的应用。
    [返回] 中文XML论坛 - 专业的XML技术讨论区XML.ORG.CN讨论区 - 高级XML应用『 SVG/GML/VRML/X3D/XAML 』 → [求助]请大虾们帮我翻译下这个程序的注释,以及程序说明。 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 4746 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: [求助]请大虾们帮我翻译下这个程序的注释,以及程序说明。 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     zhzzhz520 帅哥哟,离线,有人找我吗?
      
      
      等级:大一新生
      文章:3
      积分:63
      门派:XML.ORG.CN
      注册:2006/12/29

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给zhzzhz520发送一个短消息 把zhzzhz520加入好友 查看zhzzhz520的个人资料 搜索zhzzhz520在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 引用回复这个贴子 回复这个贴子 查看zhzzhz520的博客楼主
    发贴心情 [求助]请大虾们帮我翻译下这个程序的注释,以及程序说明。

    程序说明:
    1, 首先,原图被分为几个小块, each block has column and row number, and border path type. Application should in
    charge of the border path setting. For example, neighbours should have same kind of border path.

    2. Regions consist of blocks, it can be merge into other regions by move all its blocks to other one. It is in charge of
    generate path string for image object.

    3. Image object is a SVG group consist of a <image> and a <clipPath> with <path> setting.
       One image object looks like:
     <g id="group" transform="matrix(a,b,c,d,e,f)" display="none">
      <clipPath id="clip"><path id="path" d="M 0 0"/></clipPath>
      <image id="image" width="400" height="400" xlink:href="1.jpg" clip-path="url(#clip)"/>
     </g>
     
    4, Add mouse event to SVG canvas, including mouse down(grab), mouse up(drop) and mouse move(drag).
       Move or rotate will affect group transform string, keep clip-path and image relative fixed.
       Click on image object will "grab" it, keep mouse down and move will "drag" image, release mouse will "drop" image to a
    new position.

    5, In order to improve grap and drag speed, after select one image, swap svg node to bring selected image to then front.
    (append selected one in SVG node proved to be very slowly);

    6, After drop, image object will test it neighbour to determine which one should be merged toghther. Drop object will test
    object borders in other group, if distance less than minimize value, drop object will be added to target group. Pay attention to
    the check distance function, group transform matrix should be consider.
     border : neighbour, according to the blocks region hold
     translate : distance less than mindistance (arrording to translate offset, remember complete picture's all offset is equal, only clip offset is different)
     rotate angle : equal, only regions with same direction can be merge together

     loop1: Search other image objects which meet condition 2 and 3
     loop2: Search whether image object contain border block for each blocks in this region,
      Once got one then break and return,
      otherwise continue loop till finish iteration.
      

    7, If no swap and no merge happen, and move distance less than min rotate distance, image will rotate round mouse point.

    8, If merge group happened and after then target group contains "imageRow * imageCol" images, it indicate all works done, move group to origin
    and show "Game over!".


       收藏   分享  
    顶(0)
      




    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/12/30 14:55:00
     
     zhzzhz520 帅哥哟,离线,有人找我吗?
      
      
      等级:大一新生
      文章:3
      积分:63
      门派:XML.ORG.CN
      注册:2006/12/29

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给zhzzhz520发送一个短消息 把zhzzhz520加入好友 查看zhzzhz520的个人资料 搜索zhzzhz520在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 引用回复这个贴子 回复这个贴子 查看zhzzhz520的博客2
    发贴心情 
    程序:
    <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"
         width="100%" height="100%" shape-rendering="optimizeSpeed" zoomAndPan="enable" onload="init(evt)" onmousedown="grab(evt)" onmousemove="drag(evt)" onmouseup="drop(evt)">
    <title>Puzzle</title>
    <desc>Puzzle</desc>

    <script language="JavaScript" >
    <![CDATA[

        
    var svgNS = "http://www.w3.org/2000/svg";
    var xlinkNS="http://www.w3.org/1999/xlink";

    var svgDocument = null;
    var svgRoot = null;
    var canvas = null;
    var background = null; //to receive mouse event on drag
    var dragImage = null;

    var imageList = new Array();

    var trueCoords = null;
    var grabPoint = null;
    var orgPoint = null;
    var swapFlag = false; //Swap happen or not

    //In order to keep all points is integer, imageWidth will be round to imageCol * 4 and imageHeight round to imageRow * 4
    //For example, if imageCol = 3, 400%(3*4)=4, imageWidth will be round to 400-4=396.
    var imageWidth = 400;  
    var imageHeight = 400;

    var imageRow = 3;   //You can change from Row and column number from 1 to 10
    var imageCol = 3;
    var rowUnit;  //Height of each row
    var colUnit; //Width of each column

    var MIN_MERGE_DISTANCE = 5;  //Merge distance
    var MIN_ROTATE_DISTANCE = 2; //Rotate distance

    var CANVAS_ID = "canvas";
    var BACKGROUND_ID = "background";
    var IMAGE_SOURCE = "1.jpg"; //Source file
    var OUTLINE_ID = "outline";
    var OUTLINE_STROKE = "silver";
    var OUTLINE_STROKE_WIDTH = 2;

    function init(evt)
    {
     svgDocument = evt.target.ownerDocument;
     svgRoot = svgDocument.documentElement;
     
     //Resize image in order to round path point to int;
     roundSize();
     
     trueCoords = svgRoot.createSVGPoint();
     grabPoint = svgRoot.createSVGPoint();
     orgPoint = svgRoot.createSVGPoint();
     
     //Get backgroup and canvas element
     background = svgDocument.getElementById( BACKGROUND_ID );
     canvas = svgDocument.getElementById( CANVAS_ID );
     var blockList = createBlockList();
     
     for(var i = 0; i < imageRow; i++)
     {
      for(var j = 0; j < imageCol; j++)
      {
       var id = "part_" + i + "_" + j;
        
       var region = new Region();
       region.addBlock( blockList[ i*imageCol + j ] );
         
       var image = new ImageObject(id, CANVAS_ID, 0, region);
       image.create();
       image.updatePath();
       imageList[imageList.length] = image;
       
       //Random rotate and spread images
       var cx = Math.random() * innerWidth / 2;
       var cy = Math.random() * innerHeight / 2;
       var rotateFlag = parseInt( Math.random() * 10 ) % 4;
       var rx = j * colUnit + colUnit / 2;
       var ry = i * rowUnit + rowUnit / 2;
       
       image.updateImage(cx, cy, rotateFlag, rx, ry);
       
      }
     }
      
     //Create outline
     createOutline();
    }

    function createBlockList()
    {
     //Edge type current support
     // 0: line; 1: one big circle; 2: one small circle
     var edgeTypeNumber = 2;
     
     //Horizontal edge [col][row+1] vertical [row][col+1]
     //In order to simplize usage, we just use string to hold edge type
     
     var hEdgesStr = "";
     var vEdgesStr = "";
     
     for(var i = 0; i < imageRow + 1; i++)
     {
      for(var j = 0; j < imageCol ; j++)
      {
       if( (i == 0) || ( i== imageRow ) )
        hEdgesStr = hEdgesStr + "0";
       else
        hEdgesStr = hEdgesStr + (( parseInt( Math.random() * 10 ) ) % edgeTypeNumber + 1);
      }
     }
      
     for(var i = 0; i < imageRow; i++)
     {
      for(var j = 0; j < imageCol + 1; j++)
      {
       if( (j == 0) || ( j == imageCol ) )
        vEdgesStr = vEdgesStr + "0";
       else
        vEdgesStr = vEdgesStr + (( parseInt(Math.random() * 10 ) ) % edgeTypeNumber + 1);
      }
     }
     
     //alert( hEdgesStr + "; " + vEdgesStr);

     var blockList = new Array();
     for(var i = 0; i < imageRow; i++)
     {
      for(var j = 0; j < imageCol; j++)
      {
       var block = new Block(i, j);
       block.topEdge = parseInt( hEdgesStr.substr(i*imageCol + j, 1) );
       block.bottomEdge = parseInt( hEdgesStr.substr( (i+1)*imageCol + j, 1) );
       
       block.leftEdge = parseInt( vEdgesStr.substr(i* (imageCol + 1) + j, 1) );
       block.rightEdge = parseInt( vEdgesStr.substr(i* (imageCol + 1) + j + 1, 1) );
       
       //alert(i + " " + j + ": " + block.topEdge + " " + block.rightEdge + " " + block.bottomEdge +  " " + block.leftEdge);
       blockList[blockList.length] = block;
      }
     }
     
     //alert(blockList.length);
     return blockList;
    }

    function createOutline()
    {
     //Outline path
     var groups = svgDocument.getElementById(CANVAS_ID);
     if(groups != null)
     {
      var lastGroup = groups.lastChild;
      var path = svgDocument.createElementNS(svgNS, "path");
      path.setAttributeNS(null, "id", OUTLINE_ID);
      path.setAttributeNS(null, "d", "M 0 0");
      path.setAttributeNS(null, "fill", "none");
      path.setAttributeNS(null, "stroke", OUTLINE_STROKE);
      path.setAttributeNS(null, "stroke-width", OUTLINE_STROKE_WIDTH);
      path.setAttributeNS(null, "point-events", "none");
      lastGroup.appendChild(path);
     }
    }

    function showOutline(pathStr)
    {
     var path = svgDocument.getElementById(OUTLINE_ID);
     if(path != null)
     {
      path.setAttributeNS(null,"d", pathStr);
     }
    }

    function roundSize()
    {
     if( imageRow > 10)
      imageRow = 10;
     if( imageCol > 10 )
      imageCol = 10;
     
     imageWidth = imageWidth - imageWidth % ( imageCol * 4 );
     imageHeight = imageHeight - imageHeight % ( imageRow * 4 );
     
     rowUnit = imageHeight / imageRow;  //Row part unit
     colUnit = imageWidth / imageCol; //Col part unit
    }

    function matrixToStr(matrix)
    {
     var transformStr = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + ","
        + matrix.d + "," + matrix.e + "," + matrix.f + ")";
     return transformStr;
    }

    //Get image object by SVG node id
    function getImageObject(id)
    {
     var index = id.indexOf("_");
     var str = id.substr(index+1);
     index = str.indexOf("_");
     
     var row = parseInt(str.substr(0,index));
     var col = parseInt(str.substr(index+1));
     
     //Search specific block in image object region
     for(var i=0; i<imageList.length; i++)
     {
      if( (imageList[i] != null) && (imageList[i].region.hasBlock(row, col) ))
       return  imageList[i];
     }
     
     return null;
    }

    function getTrueCoords(evt)
    {
     var newScale = svgRoot.currentScale;
     var translation = svgRoot.currentTranslate;
     trueCoords.x = (evt.clientX - translation.x)/newScale;
     trueCoords.y = (evt.clientY - translation.y)/newScale;
    }

    //Swap selected SVG node to last one
    function swapImage(id1, id2)
    {
     var group1, clip1, path1, image1;
     var group2, clip2, path2, image2;
     
     var group1Id = "group" + id1;
     var clip1Id = "clip" + id1;
     var path1Id = "path" + id1;
     var image1Id = "image" + id1;
     
     group1 = svgDocument.getElementById(group1Id);
     clip1 = svgDocument.getElementById(clip1Id);
     path1 = svgDocument.getElementById(path1Id);
     image1 = svgDocument.getElementById(image1Id);
     
     var group2Id = "group" + id2;
     var clip2Id = "clip" + id2;
     var path2Id = "path" + id2;
     var image2Id = "image" + id2;
     
     group2 = svgDocument.getElementById(group2Id);
     clip2 = svgDocument.getElementById(clip2Id);
     path2 = svgDocument.getElementById(path2Id);
     image2 = svgDocument.getElementById(image2Id);
     
     swapNodeAttribute(group1, group2, "id");
     swapNodeAttribute(group1, group2, "transform");
     swapNodeAttribute(clip1, clip2, "id");
     swapNodeAttribute(path1, path2, "id");
     swapNodeAttribute(path1, path2, "d");
     swapNodeAttribute(image1, image2, "id");
     swapNodeAttribute(image1, image2, "clip-path");
     
    }
     
    function swapNodeAttribute(node1, node2, attrName)
    {
     var value1 = node1.getAttributeNS(null, attrName);
     var value2 = node2.getAttributeNS(null, attrName);
     node1.setAttributeNS(null, attrName, value2);
     node2.setAttributeNS(null, attrName, value1);
    }

    //Search neighbours in image list
    function getNeighbourImage()
    {
     for(var i=0; i<imageList.length; i++)
     {
      if( (dragImage == imageList[i]) || (imageList[i] == null) )
       continue;
      
      if(dragImage.checkNeighbour(imageList[i]) == true)
      {
       //Return neighbour and remove it from image list
       var newImage = imageList[i];
       imageList[i] = null;
       return newImage;
      }
     }
     
     return null;
    }

    function gameOver()
    {
     alert("Game Over!");
    }

    ///
    /// Block and Region class
    ///
    function Block(row, col)
    {
     //Data
     this.row = row;
     this.col = col;
     
     this.topEdge = 0;
     this.rightEdge = 0;
     this.bottomEdge = 0;
     this.leftEdge = 0;
    }

    function Region()
    {
     //Data
     this.blocks = new Array();
     
     //Methods
     this.addBlock = addBlock;
     this.hasBlock = hasBlock;  //Test contain one specific block or not
     this.mergeRegion = mergeRegion;
     this.getPathStr = getPathStr;
     this.getOutline = getOutline;
     this.isNeighbour = isNeighbour; //Test other region has neighbour block or not
    }

    function addBlock(block)
    {
     this.blocks[this.blocks.length] = block;
    }

    function hasBlock(row, col)
    {
     for(var i = 0; i<this.blocks.length; i++)
     {
      if( (this.blocks[i].row == row) && (this.blocks[i].col == col) )
       return true;
     }
     
     return false;
    }

    function mergeRegion(newRegion)
    {
     if( (newRegion == null) || (newRegion.blocks == null) )
      return;
      
     //Copy all block from new region
     for(var i = 0; i<newRegion.blocks.length; i++)
     {
      this.blocks[this.blocks.length] = newRegion.blocks[i];
     }
    }

    function isNeighbour(newRegion)
    {
     if(newRegion.blocks == null)
      return false;
     
     var block1, block2;
     for(var i = 0; i<this.blocks.length; i++)
     {
      block1 = this.blocks[i];
      for(var j = 0; j<newRegion.blocks.length; j++)
      {
       block2 = newRegion.blocks[j];
       
       //Same row, previous or next col is neighbour
       if( (block1.row == block2.row) && (Math.abs(block1.col - block2.col) == 1) )
        return true;
       
       //Same col, previous or next row is neighbour
       if( (block1.col == block2.col) && (Math.abs(block1.row - block2.row) == 1) )
        return true;
      }
     }

     return false;
    }

    function getOutline()
    {
     var pathStr = " ";
     var x, y;
     var rowPart = rowUnit / 4;
     var colPart = colUnit / 4;
     
     var topFlag = true;
     var rightFlag = true
     var bottomFlag = true;
     var leftFlag = true;
      
     for(var i = 0; i < this.blocks.length; i++)
     {
      var block = this.blocks[i];
      
      //Set outline edge flag
      if( (block.row > 0) && this.hasBlock(block.row - 1, block.col) )
       topFlag = false;
      if( (block.row < (imageRow - 1)) && this.hasBlock(block.row + 1, block.col) )
       bottomFlag = false;
      if( (block.col > 0) && this.hasBlock(block.row , block.col - 1) )
       leftFlag = false;
      if( (block.col < (imageCol - 1) ) && this.hasBlock(block.row , block.col + 1) )
       rightFlag = false; 
      
      var ox = block.col * colUnit;
      var oy = block.row * rowUnit;
      
      if(topFlag)
      {
       //Move to begin point
       x = ox;
       y = oy;
       pathStr = pathStr + "M " + x + " " + y + " ";
       
       //Top edge, y fixed to oy
       if(block.topEdge == 1)
       {
        x = ox + colPart;
        pathStr = pathStr + " L " + x + " " + y + " a " + colPart / 2 + " " + colPart / 2 + " 0 1 1 " + colPart + " 0 L";
        x = ox + colUnit;
        pathStr = pathStr + x + " " + y + " ";
       }
       else if(block.topEdge == 2)
       {
        x = ox + colPart * 2;
        pathStr = pathStr + " L " + x + " " + y + " a " + colPart / 2 + " " + colPart / 2 + " 0 1 1 " + colPart + " 0 L ";
        x = ox + colUnit;
        pathStr = pathStr + x + " " + y + " ";
       }
       else
       {
        x = ox + colUnit;
        pathStr = pathStr + " L " + x + " " + y + " ";
       }
      }
      
      if(rightFlag)
      {
       //Move to begin point
       x = ox + colUnit;
       y = oy;
       pathStr = pathStr + "M " + x + " " + y + " ";
       
       //Right edge, x fixed to ox + colUnit;
       if(block.rightEdge == 1)
       {
        y = oy + rowPart;
        
        pathStr = pathStr + " L " + x + " " + y + " a " + rowPart / 2 + " " + rowPart / 2 + " 0 1 1 0 " + rowPart + " L ";
        y = oy + rowUnit;
        pathStr = pathStr + x + " " + y + " ";
       }
       else if(block.rightEdge == 2)
       {
        y = oy + rowPart * 2;
        
        pathStr = pathStr + " L " + x + " " + y + " a " + rowPart / 2 + " " + rowPart / 2 + " 0 1 1 0 " + rowPart + " L ";
        y = oy + rowUnit;
        pathStr = pathStr + x + " " + y + " ";
       }
       else
       {
        y = oy + rowUnit;
        pathStr = pathStr + " L " + x + " " + y + " ";
       }
      }
      
      if(bottomFlag)
      {
       //Move to begin point
       x = ox + colUnit;
       y = oy + rowUnit;
       pathStr = pathStr + "M " + x + " " + y + " ";
       
       //Bottom edge, y fixed to oy + rowUnit;
       if(block.bottomEdge == 1)
       {
        x = ox + colUnit - 2 * colPart;
        
        pathStr = pathStr + " L " + x + " " + y + " a " + colPart / 2 + " " + colPart / 2 + " 0 1 0 -" + colPart + " 0 L";
        x = ox;
        pathStr = pathStr + x + " " + y + " ";
       }
       else if(block.bottomEdge == 2)
       {
        x = ox + colUnit - colPart;
        pathStr = pathStr + " L " + x + " " + y + " a " + colPart / 2 + " " + colPart / 2 + " 0 1 0 -" + colPart + " 0 L ";
        x = ox;
        pathStr = pathStr + x + " " + y + " ";
       }
       else
       {
        x = ox;
        pathStr = pathStr + " L " + x + " " + y + " ";
       }
      }
      
      if(leftFlag)
      {
       //Move to begin point
       x = ox;
       y = oy + rowUnit;
       pathStr = pathStr + "M " + x + " " + y + " ";
       
       //Left edge, x fixed to ox
       if(block.leftEdge == 1)
       {
        y = oy + rowUnit - 2 * rowPart;
        
        pathStr = pathStr + " L " + x + " " + y + " a " + rowPart / 2 + " " + rowPart / 2 + " 0 1 0 0 -" + rowPart + " L ";
        y = oy;
        pathStr = pathStr + x + " " + y + " ";
       }
       else if(block.leftEdge == 2)
       {
        y = oy + rowUnit - rowPart;
        
        pathStr = pathStr + " L " + x + " " + y + " a " + rowPart / 2 + " " + rowPart / 2 + " 0 1 0 0 -" + rowPart + " L ";
        y = oy;
        pathStr = pathStr + x + " " + y + " ";
       }
       else
       {
        y = oy;
        pathStr = pathStr + " L " + x + " " + oy + " ";
       }
      }
     }
     
     //alert(pathStr);
     return pathStr;
    }

    function getPathStr()
    {
     var pathStr = " ";
     var x, y;
     var rowPart = rowUnit / 4;
     var colPart = colUnit / 4;
      
     for(var i = 0; i < this.blocks.length; i++)
     {
      var block = this.blocks[i];
        
      pathStr = pathStr + "M ";
       
      var ox = block.col * colUnit;
      var oy = block.row * rowUnit;
      
      //Move to begin point
      pathStr = pathStr + ox + " " + oy + " ";
      
      //Top edge, y fixed to oy
      y = oy;
      if(block.topEdge == 1)
      {
       x = ox + colPart;
       pathStr = pathStr + " L " + x + " " + y + " a " + colPart / 2 + " " + colPart / 2 + " 0 1 1 " + colPart + " 0 L";
       x = ox + colUnit;
       pathStr = pathStr + x + " " + y + " ";
      }
      else if(block.topEdge == 2)
      {
       x = ox + colPart * 2;
       pathStr = pathStr + " L " + x + " " + y + " a " + colPart / 2 + " " + colPart / 2 + " 0 1 1 " + colPart + " 0 L ";
       x = ox + colUnit;
       pathStr = pathStr + x + " " + y + " ";
      }
      else
      {
       x = ox + colUnit;
       pathStr = pathStr + " L " + x + " " + y + " ";
      }
      
      //Right edge, x fixed to ox + colUnit;
      x = ox + colUnit;
      if(block.rightEdge == 1)
      {
       y = oy + rowPart;
       
       pathStr = pathStr + " L " + x + " " + y + " a " + rowPart / 2 + " " + rowPart / 2 + " 0 1 1 0 " + rowPart + " L ";
       y = oy + rowUnit;
       pathStr = pathStr + x + " " + y + " ";
      }
      else if(block.rightEdge == 2)
      {
       y = oy + rowPart * 2;
       
       pathStr = pathStr + " L " + x + " " + y + " a " + rowPart / 2 + " " + rowPart / 2 + " 0 1 1 0 " + rowPart + " L ";
       y = oy + rowUnit;
       pathStr = pathStr + x + " " + y + " ";
      }
      else
      {
       y = oy + rowUnit;
       pathStr = pathStr + " L " + x + " " + y + " ";
      }
      
      //Bottom edge, y fixed to oy + rowUnit;
      y = oy + rowUnit;
      if(block.bottomEdge == 1)
      {
       x = ox + colUnit - 2 * colPart;
       
       pathStr = pathStr + " L " + x + " " + y + " a " + colPart / 2 + " " + colPart / 2 + " 0 1 0 -" + colPart + " 0 L";
       x = ox;
       pathStr = pathStr + x + " " + y + " ";
      }
      else if(block.bottomEdge == 2)
      {
       x = ox + colUnit - colPart;
       pathStr = pathStr + " L " + x + " " + y + " a " + colPart / 2 + " " + colPart / 2 + " 0 1 0 -" + colPart + " 0 L ";
       x = ox;
       pathStr = pathStr + x + " " + y + " ";
      }
      else
      {
       x = ox;
       pathStr = pathStr + " L " + x + " " + y + " ";
      }
      
      //Left edge, x fixed to ox
      x = ox;
      if(block.leftEdge == 1)
      {
       y = oy + rowUnit - 2 * rowPart;
       
       pathStr = pathStr + " L " + x + " " + y + " a " + rowPart / 2 + " " + rowPart / 2 + " 0 1 0 0 -" + rowPart + " L ";
       y = oy;
       pathStr = pathStr + x + " " + y + " ";
      }
      else if(block.leftEdge == 2)
      {
       y = oy + rowUnit - rowPart;
       
       pathStr = pathStr + " L " + x + " " + y + " a " + rowPart / 2 + " " + rowPart / 2 + " 0 1 0 0 -" + rowPart + " L ";
       y = oy;
       pathStr = pathStr + x + " " + y + " ";
      }
      else
      {
       y = oy;
       pathStr = pathStr + " L " + x + " " + oy + " ";
      }
     }
     
     //alert(pathStr);
     return pathStr;
    }

    ///
    /// ImageObject class begin
    ///
    function ImageObject(id, parentId, angle, region)
    {
     //Data
     this.id = id;
     this.parentId = parentId;
     
     this.angle = angle;
     this.region = region;
      
     //Methods 
     this.create = create; //Create SVG node and show
     this.updateImage = updateImage; //Update position and rotate status
     this.updatePath = updatePath; //Update clip path after merge with other images
     this.hide = hide; //Hide svg node
     this.deleteFromCanvas = deleteFromCanvas; //Delete svg node
     this.enableEvent = enableEvent;  //Enable/Disable svg mouse event
     
     this.checkNeighbour = checkNeighbour; //Check image neighbour or not
     this.mergeImage = mergeImage;
     
    }

    function deleteFromCanvas()
    {
     var groupId = "group" + this.id;
     var parentGroup = svgDocument.getElementById(this.parentId);
     var group = svgDocument.getElementById(groupId);
     
     if ((parentGroup != null) && (group != null) )
      parentGroup.removeChild(group);
    }

    function hide()
    {
     var groupId = "group" + this.id;
     var group = svgDocument.getElementById(groupId);
     if(group != null)
     {
      group.setAttributeNS(null, "display", "none");
     }
    }

    function mergeImage(newImage)
    {
     if( (newImage == null) || (newImage.region == null))
      return;
      
     //Merge image clip region
     this.region.mergeRegion(newImage.region);
     newImage.enableEvent(false);
     newImage.hide();
    }

    function create()
    {
     var parentGroup = svgDocument.getElementById(this.parentId);
     var group, clip, path, image;
     
     var groupId = "group" + this.id;
     var clipId = "clip" + this.id;
     var pathId = "path" + this.id;
     var imageId = "image" + this.id;
     
     group = svgDocument.getElementById(groupId);
     
     if(group == null)
     {
      //Create object, including group, clip-path and image
      group = svgDocument.createElementNS(svgNS, "g");
      parentGroup.appendChild(group);
      group.setAttributeNS(null, "id", groupId);
      //group.setAttributeNS(null, "opacity", "0.8");
      
      //Create clip and clip path
      clip = svgDocument.createElementNS(svgNS, "clipPath");
      clip.setAttributeNS(null,"id",clipId);
      path = svgDocument.createElementNS(svgNS, "path");
      path.setAttributeNS(null,"id",pathId);
      //path.setAttributeNS(null,"fill","none");
      //path.setAttributeNS(null,"stroke","none");
      clip.appendChild(path);
      
      //Create image
      image = svgDocument.createElementNS(svgNS, "image");
      image.setAttributeNS(null, "id", imageId);
      image.setAttributeNS(null, "width", imageWidth);
      image.setAttributeNS(null, "height", imageHeight);
      image.setAttributeNS(null, "preserveAspectRatio", "none");
      image.setAttributeNS(xlinkNS, "xlink:href", IMAGE_SOURCE);
      var urlClip = "url(#" + clipId + ")";
      image.setAttributeNS(null, "clip-path", urlClip);
     
      //Add clip and image to group 
      group.appendChild(clip);
      group.appendChild(image);
     }
      
     group.setAttributeNS(null, "display", "inline");
    }

    function updatePath()
    {
     var pathId = "path" + this.id;
     path = svgDocument.getElementById(pathId);
     
     if(path != null)
      path.setAttributeNS(null,"d", this.region.getPathStr());
    }

    function updateImage(cx, cy, rotateFlag, rx, ry)
    {
     var groupId = "group" + this.id;
     
     group = svgDocument.getElementById(groupId);
     
     if(group == null)
      return;
      
     var sin, cos;
     if(rotateFlag == 1) //90
     {
      sin = 1;
      cos = 0;
     }
     else if(rotateFlag == 2) //180
     {
      sin = 0;
      cos = -1;
     }
     else if(rotateFlag == 3) //270
     {
      sin = -1;
      cos = 0;
     }
     else //default 0
     {
      sin = 0;
      cos = 1;
     }
     
     //Update tranform matrix
     var transMatrix = group.getCTM();
     var newMatrix = svgRoot.createSVGMatrix();
     newMatrix.a = transMatrix.a * cos - transMatrix.b * sin;
     newMatrix.b = transMatrix.a * sin + transMatrix.b * cos;
     newMatrix.c = transMatrix.c * cos - transMatrix.d * sin;
     newMatrix.d = transMatrix.c * sin + transMatrix.d * cos;
     newMatrix.e = transMatrix.e * cos - transMatrix.f * sin - rx * cos + ry * sin + rx + cx ;
     newMatrix.f = transMatrix.e * sin + transMatrix.f * cos - rx * sin - ry * cos + ry + cy ;
     
     var transformStr = matrixToStr(newMatrix);
      
     group.setAttributeNS(null, "transform", transformStr);
     group.setAttributeNS(null, "display", "inline");
     
     //Update image object angle value
     this.angle = (this.angle + rotateFlag * 90) % 360;
    }


    function enableEvent(flag)
    {
     //Enable or disable mouse event
     var elem = svgDocument.getElementById("image" + this.id);
     if(elem == null)
      return;
      
     if(flag)
      elem.setAttributeNS(null, "pointer-events", "all");
     else
      elem.setAttributeNS(null, "pointer-events", "none");
    }

    function checkNeighbour(newImage)
    {
     if(newImage == null)
      return;
      
     //Same direction
     if(this.angle != newImage.angle)
     {
      //alert("direction wrong");
      return false;
     }
     
     //Check distance scope 
     var group1Id = "group" + this.id;
     var group1 = svgDocument.getElementById(group1Id);
     var transMatrix1 = group1.getCTM();
     
     var group2Id = "group" + newImage.id;
     var group2 = svgDocument.getElementById(group2Id);
     var transMatrix2 = group2.getCTM();
     
     var cx = transMatrix1.e - transMatrix2.e;
     var cy = transMatrix1.f - transMatrix2.f;
     
     
     if( (cx*cx + cy*cy) > (MIN_MERGE_DISTANCE * MIN_MERGE_DISTANCE) )
     {
      //alert("distance wrong");
      return false;
     }
     
     
     //Have neighbour block
     if( this.region.isNeighbour(newImage.region) == false )
     {
      //alert("blocks wrong");
      return false;
     }
     
     //Really a neighbour
     return true;
    }

    ///
    /// ImageObject class finished
    ///

    //
    //Mouse event handlers
    //

    //Grab by mouse 
    function grab(evt)
    {
     if(evt.button != 0) //Left mouse button
      return;
      
     var targetElement = evt.target;
     if ( background == targetElement )
     {
      //Do nothing about background
      return;
     }
       
     var id = targetElement.getAttributeNS(null, "id");
     //alert(id);
      
     dragImage = getImageObject(id);
     if(dragImage == null)
     {
      //alert("No drag");
      return;
     }
     
     //Swap svg node by id, move target to front(appendChild prove to be very slowly)
     var canvas = svgDocument.getElementById(CANVAS_ID);
     var lastId = canvas.lastChild.getAttributeNS(null, "id");
     
     if( id.substr(5) == lastId.substr(5))
     {
      swapFlag = false; // Front one, do not need swap
     }
     else
     {
      //var lastImage = getImageObject(lastId);
      swapImage(id.substr(5), lastId.substr(5));
      swapFlag = true;
     }
     
     //Set selected flag
     //canvas.lastChild.setAttributeNS(null, "opacity", "1");
      
     //Remember old position
     orgPoint.x = trueCoords.x;    
     orgPoint.y = trueCoords.y;    

     grabPoint.x = trueCoords.x;
     grabPoint.y = trueCoords.y;
     
     dragImage.enableEvent(false);
     showOutline(dragImage.region.getOutline());
    }

    function drag(evt)
    {
     getTrueCoords(evt);
      
     if (dragImage)
     {
      var newX = trueCoords.x - grabPoint.x;
      var newY = trueCoords.y - grabPoint.y;
      
      dragImage.updateImage(newX, newY, 0, 0, 0);
      
      grabPoint.x = trueCoords.x;
      grabPoint.y = trueCoords.y;
     }
    }

    function drop(evt)
    {
     getTrueCoords(evt);
     var mergeFlag = false;
     
     if ( dragImage )
     {
      var newImage = getNeighbourImage();
      if(newImage != null)
      {
       //Merge happened
       dragImage.mergeImage(newImage);
       dragImage.updatePath();
       showOutline(dragImage.region.getOutline());
       
       //Finish or not
       if(dragImage.region.blocks.length == imageRow * imageCol)
       {
        //Congratulations!
        setTimeout("gameOver()", 500);
       }
        
       mergeFlag = true;
       newImage.deleteFromCanvas(); //Delete SVG node
       newImage = null;
      }
       
      if( (!swapFlag) && (!mergeFlag) )
      {
       //Rotate image in case of no swap and no merge
       var cx = trueCoords.x - orgPoint.x;
       var cy = trueCoords.y - orgPoint.y;
       if( (cx*cx + cy*cy) <= (MIN_ROTATE_DISTANCE * MIN_ROTATE_DISTANCE) )
       {
        var newX = trueCoords.x - grabPoint.x;
        var newY = trueCoords.y - grabPoint.y;
        dragImage.updateImage(newX, newY, 1, trueCoords.x, trueCoords.y);
       }
      }
      
      dragImage.enableEvent(true);
      dragImage = null;
      swapFlag = false;
     }
    }

    // ]]>
    </script>

     <defs>
      <menu id="menu1" >
       <header>Menu</header>
      </menu>
     </defs>
     
     <rect id="background" x="0" y="0" width="100%" height="100%" fill="white" pointer-events="all" />
     <g id="canvas" >
     </g>
     
    </svg>

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/12/30 14:58:00
     
     alai7150 帅哥哟,离线,有人找我吗?
      
      
      等级:大一(高数修炼中)
      文章:14
      积分:193
      门派:XML.ORG.CN
      注册:2006/5/6

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给alai7150发送一个短消息 把alai7150加入好友 查看alai7150的个人资料 搜索alai7150在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 引用回复这个贴子 回复这个贴子 查看alai7150的博客3
    发贴心情 
    兄弟 你不能弄短一点的程序啊,看别人 的程序是最头疼的事情,更何况这么长!
    慢慢啃吧。
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/1/6 9:06:00
     
     wwwtiger 帅哥哟,离线,有人找我吗?
      
      
      等级:大三(研究MFC有点眉目了!)
      文章:62
      积分:716
      门派:XML.ORG.CN
      注册:2006/8/3

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给wwwtiger发送一个短消息 把wwwtiger加入好友 查看wwwtiger的个人资料 搜索wwwtiger在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 引用回复这个贴子 回复这个贴子 查看wwwtiger的博客4
    发贴心情 
    Sorry,这是我为了测试SVG的图形处理速度编写的一个拼图小游戏,程序不是很严谨,也没有说明文档,仅仅供测试和参考。当时懒得写中文,于是写了一些英文注释,在http://blog.csdn.net/firefight/archive/2006/11/16/1387356.aspx有一些简短的程序说明,希望有所帮助。
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/1/8 10:29:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 SVG/GML/VRML/X3D/XAML 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/5/11 22:52:27

    本主题贴数4,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    140.625ms