2014-01-21 55 views
1

在我的基於SVG的web應用程序中,用戶可以選擇大量的形狀(甚至800或更多)&在屏幕上移動它們,這可以想象會嚴重影響幀率。在閱讀​​的優點之後,我從昨天開始一直在努力將其納入到我的mousemove函數中,希望通過使用節流&​​的組合,我可以獲得平穩的幀率。如何在mousemove事件中使用requestAnimationFrame?

Here是jsFiddle我在移動600 svg形狀mousemove。現在忽略節流,我如何將​​納入mousemove函數。

http://jsfiddle.net/rehankhalid/5t5pX/

HTML代碼

<svg width="1200" height="800"> 
<symbol> 
    <g id="symbol1"> 
    <path fill="#3ab6d1" d="M27.7,1.1C16-2,3.9,5.1,0.8,16.9s4,23.8,15.7,26.9c11.7,3.1,23.8-4,26.9-15.7C46.6,16.3,39.6,4.2,27.7,1.1z M38.3,26.9C36,35.7,26.9,41,18,38.7C9.1,36.4,3.8,27.3,6.1,18.5C8.4,9.6,17.5,4.3,26.4,6.6C35.3,9,40.6,18,38.3,26.9z"/> 
    <g fill="#d5e1db"> 
    <path d="m25.8,.8c2.5,.4 4.8,1.2 7,2.5l-2.9,4.6c-1.5-.8-3.1-1.4-4.8-1.7l.7-5.4z"/> 
    <path d="m13.9,2.2l1.7,5.1c-1.5,.7-3,1.5-4.3,2.7l-3.8-3.9c.9-.8 1.9-1.5 2.9-2.2 1.2-.7 2.3-1.3 3.5-1.7z"/> 
    </g> 
    <path fill="#196275" d="m26.4,38.5l1.8,5.2c-2.5,.7-4.9,.9-7.4,.8l.6-5.4c1.6,0 3.3-.2 5-.6z"/> 
    <path fill="#42aec2" d="M6.1,18.4C8.4,9.5,17.5,4.2,26.4,6.5S40.7,18,38.4,26.8C36,35.7,26.9,41,18,38.7C9.1,36.3,3.7,27.2,6.1,18.4 z"/> 
    <path fill="#d2dfdd" d="m28.7,25.9l.5-4.9 9.5-1.3c0,.3 .1,.6 .2,.8 .4,2.9 0,5.8-1,8.3l-9.2-2.9z"/> 
    <path fill="#1b6273" d="m19.7,29.3h4.9l2.1,9.4c-.3,.1-.6,.2-.8,.2-2.9,.6-5.7,.5-8.4-.3l2.2-9.3z"/> 
    <path fill="#368098" d="m15.9,25.8l3.6,3.4-4.8,8.3c-.3-.1-.5-.3-.8-.4-2.6-1.5-4.6-3.5-6-5.9l8-5.4z"/> 
    <path fill="#d2dfdd" d="m18.6,16.5l-3,3.9-8.7-4c.1-.3 .2-.5 .3-.8 1.2-2.7 3.1-4.9 5.3-6.5l6.1,7.4z"/> 
    <path fill="#bde2e9" d="m26.4,32.1l-8.4-.5-4.9-6.8 2.3-8 7.7-3.2 7.3,4 1.5,8.2-5.5,6.3z"/> 
    </g> 
</symbol> 
<g id="default"> 
<g id="my-element"> 

</g> 
</g> 


<g id="draggroup"> 

</g> 

</svg> 

的Javascript

document.addEventListener('mousedown', mousedown, false); 


     var element = document.getElementById('my-element'); 
     var defaultg = document.getElementById('default'); 
     var mainsvg = document.getElementsByTagName('svg')[0]; 
     var draggroup = document.getElementById('draggroup'); 
     var svgns = "http://www.w3.org/2000/svg"; 



     var x = 0, y = 0; 
     var scale = '0.25'; 
     for (var i = 0; i < 600; i++) { 
      var useelement = document.createElementNS(svgns, "use"); 
      useelement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#symbol1'); 
      useelement.setAttribute('transform', 'translate(' + x + ',' + y + ') scale(' + scale + ')'); 

      x += 12; 
      if (x === 240) { 
       x = 0; 
       y += 12; 
      } 

      element.appendChild(useelement); 

     } 


     var bbox = element.getBBox(); 
     var selectionRect = document.createElementNS(svgns, "rect"); 
     selectionRect.setAttribute('id', 'selectionrect'); 
     selectionRect.setAttribute('x', bbox.x); 
     selectionRect.setAttribute('y', bbox.y); 
     selectionRect.setAttribute('width', bbox.width); 
     selectionRect.setAttribute('height', bbox.height); 
     selectionRect.setAttribute('fill', 'grey'); 
     selectionRect.setAttribute('opacity', '0.2'); 

     draggroup.appendChild(selectionRect); 


     var dx = 0, dy = 0, mx = 0, my = 0; 
     var rectdx = 0, rectdy = 0; 
     var elementdx = 0, elementdy = 0; 

     function getSvgCordinates(event) { 
      var m = mainsvg.getScreenCTM(); 
      var p = mainsvg.createSVGPoint(); 
      var x, y; 

      x = event.pageX; 
      y = event.pageY; 

      p.x = x; 
      p.y = y; 
      p = p.matrixTransform(m.inverse()); 

      x = p.x; 
      y = p.y; 

      x = parseFloat(x.toFixed(3)); 
      y = parseFloat(y.toFixed(3)); 

      return {x: x, y: y}; 
     } 

     function mousedown(event) { 

      if (event.target.id === 'selectionrect') { 
       var svgXY = getSvgCordinates(event); 
       mx = svgXY.x; // mouse down x 
       my = svgXY.y;// mouse down y 


       draggroup.appendChild(element); 

       document.addEventListener('mousemove', mousemove, false); 
       document.addEventListener('mouseup', mouseup, false); 
      } 
     } 

     function mouseup() { 
      document.removeEventListener('mousemove', mousemove, false); 
      document.removeEventListener('mouseup', mouseup, false); 

      draggroup.setAttribute('transform', 'translate(0,0)'); 

      rectdx += dx; 
      rectdy += dy; 
      elementdx += dx; 
      elementdy += dy; 

      selectionRect.setAttribute('transform', 'translate(' + rectdx + ',' + rectdy + ')'); 
      element.setAttribute('transform', 'translate(' + elementdx + ',' + elementdy + ')'); 

      defaultg.appendChild(element); 

      dx = 0; 
      dy = 0; 
     } 

     function mousemove(event) { 
      var svgXY = getSvgCordinates(event); 
      dx = svgXY.x - mx; 
      dy = svgXY.y - my; 

      draggroup.setAttribute('transform', 'translate(' + dx + ',' + dy + ')'); 

     } 
+0

請參閱:http://www.html5rocks.com/en/tutorials/speed/animations/ –

回答

1

基本上,你需要的draggroup.setAttribute()呼叫轉移到另一個功能。由於您只需在鼠標關閉時進行動畫製作,請添加另一個變量以指示您是否在拖動,並且只有在這種情況下才調用​​。

var isDragging = false; 
function update() { // New function 
    if (isDragging) { 
    requestAnimationFrame(update); // Call self again, if still dragging 
    } 
    draggroup.setAttribute('transform', 'translate(' + dx + ',' + dy + ')'); 
} 
function mousedown(event) { 
    if (event.target.id === 'selectionrect') { 
    isDragging = true; 
    requestAnimationFrame(update); // Start animation loop 
    // existing logic here... 
    } 
} 
function mouseup() { 
    isDragging = false; 
    // existing logic here... 
} 

你已經存儲更新的位置在一個單獨的變量組(dxdy),所以從mousemove()刪除draggroup.setAttribute()電話,並添加上述修改之後,你應該不錯!

相關問題