2013-02-10 2 views
0

저는 KineticJS 초심자이고 교차로에서 특정 색상으로 바뀌는 두 개의 드래그 가능한 웨지를 만들고 싶습니다. 나는이 포럼에서 자르기 자습서와 모양 교차 질문에 대한 모양을 보았습니다. 일반적인 전술은 드래그 이벤트를 잡아 내고 KineticJS 도형을 다시 그리는 것이며 해당 도형의 drawFunc 내에서 context.rect/context.arc를 사용하여 그 모양을 복제하고 클립하는 것입니다.KineticJS 웨지와 교차하는 부분에있는 클립

내 문제는 KineticJS 쐐기를 시뮬레이션하기위한 편리한 context.wedge가 없다는 것입니다. 따라서 웨지 사용을 중지하거나 복잡한 계산을 수행하여 컨텍스트와 웨지를 시뮬레이션하거나 더 나은 방법을 찾습니다. 누구든지 더 좋은 방법을 알고 있습니까?

감사합니다,

JSFiddle에 코드 : http://jsfiddle.net/kdRjP/5/이 (. 작동하지 않습니다, 단지 사방에 중복 웨지하게, 심지어 사람을 클리핑하지 않음)

코드 :

<!DOCTYPE html> 
<html> 
<head> 
    <script type="text/javascript" charset="utf-8" src="js/kinetic-v4.3.1.min.js"></script> 
</head> 



<body> 
    <div id="container"></div> 

    <script type="text/javascript"> 

     drawWedges(); 


     function drawWedges() { 
      var stage = new Kinetic.Stage({ 
       container: "container", 
       width: 400, 
       height: 400 
      }); 
      window.console.log("Wedges: 1"); 

      var wedgeLayer = new Kinetic.Layer(); 


      var wedgeGroup = new Kinetic.Group({ 
       x: stage.getWidth()/2, 
       y: stage.getWidth()/2 
      }); 


      var wedge_1 = new Kinetic.Wedge({ 
       x: -100, 
       y: 0, 
       radius: 80, 
       angleDeg: 40, 
       opacity: 0.7, 
       fill: 'red', 
       stroke: 'black', 
       strokeWidth: 2, 
       draggable: true, 
       rotationDeg: 0 
      }); 


      var wedge_2 = new Kinetic.Wedge({ 
       x: 100, 
       y: 0, 
       radius: 80, 
       angleDeg: 40, 
       opacity: 0.7, 
       fill: 'cyan', 
       stroke: 'black', 
       strokeWidth: 2, 
       draggable: true, 
       rotationDeg: 0 
      });    



      function makeShapeClip(clipShape, compositeShape) { 
       clipShape.attrs.drawFunc_bak = clipShape.attrs.drawFunc; 
       clipShape.attrs.drawFunc = function() { 
        var context = this.getContext(); 
        context.save(); 
        context.beginPath(); 
        this.attrs.drawFunc_bak.call(this, context); 
        context.clip(); 
        context.beginPath(); 
        compositeShape.attrs.drawFunc.call(this, context); 
        context.fill(); 
        context.closePath(); 
        context.restore(); 
       }; 

       return compositeShape; 
      }; 


      wedge_1.on("dragend", function(evt) { 
       var mousePos = stage.getMousePosition(); 

       var stageIntersections = stage.getIntersections({"x": mousePos.x, "y": mousePos.y}); 
       if (stageIntersections.length > 0) { 
        // Want to draw a piece of wedge_1 clipped around wedge_2. 
        // Since can't turn wedge_2 into a clip path after it's been drawn, 
        // draw a duplicate of wedge_2 superimposed on top of wedge_2, 
        // turn that duplicate into a clip path, 
        // and then try to draw a duplicate of wedge_1 into it. 


        // Start by creating the wedge_1 duplicate in proper "intersection area color" 
        var wedgeComposite = new Kinetic.Wedge({ 
         x: wedge_1.getX(), 
         y: wedge_1.getY(), 
         radius: wedge_1.getRadius(), 
         angleDeg: wedge_1.getAngleDeg(), 
         opacity: 0.5, 
         fill: 'yellow', 
         stroke: 'blue', 
         strokeWidth: 2, 
         draggable: true, 
         rotationDeg: wedge_1.getRotationDeg() 
        }); 


        // Now pass that wedge_1 duplicate into a special function that 
        // creates wedge_2 duplicate and makes it into a clip path. 
        var wedgeClip = makeShapeClip(new Kinetic.Wedge({ 
         x: stageIntersections[0].getX(), 
         y: stageIntersections[0].getY(), 
         radius: stageIntersections[0].getRadius(), 
         angleDeg: stageIntersections[0].getAngleDeg(), 
         opacity: 0.5, 
         fill: '#999999', 
         stroke: 'red', 
         strokeWidth: 2, 
         draggable: true, 
         rotationDeg: stageIntersections[0].getRotationDeg() 
        }), wedgeComposite); 


        wedgeGroup.add(wedgeClip); 
       } 

       wedgeLayer.draw(); 
      }); 




      wedgeGroup.add(wedge_1); 
      wedgeGroup.add(wedge_2); 
      wedgeLayer.add(wedgeGroup); 
      stage.add(wedgeLayer); 
     } 
    </script> 


</body> 
</html> 
+0

btw 인 KineticJS는 다음 달에 클리핑 지원 계획을 세우고 있습니다. 머무르다. –

+0

정말요? 멋지다! 문서화에 관해서 ... 동위 원소의 단 하나의 강론자가 나를 위해 그것을하지 않습니다. 내가 알아 낸 것만 큼 내가 알아 낸 비트를위한 메서드 헤더를 작성하고 싶습니다. 어떻게 저것을 공헌 할 것입니까? 그리고 더 나은 아직, 나는 그들이 미래의 개발 중에 업데이트 될지 모른다면 나는 텍스트 블록을 쓰고 싶지 않다. 그들은 종교적으로 업데이트 될 것입니다, 맞죠?:) – Mae

+0

네, KineticJS 문서가 꽤 희박하다는 것을 알고 있습니다. 그것은 더 나아질거야 :) –

답변

0

다음은 해결책입니다.

canv 두 개의 KineticJs 웨지 (빨간색과 청록색)로 1 위를 차지했습니다. 사용자가 드래그를 완료

:

  1. 가 현재 위치/회전에서 단지 빨간색 쐐기로 새로운 캔버스 # 2 (캔버스 # 1과 같은 크기)를 만듭니다. 캔버스 # 2 (가시성 : 숨김)를 표시하지 않습니다.

  2. 새 캔버스 # 3 (캔버스 # 1과 동일한 크기)을 현재 위치/회전으로 청록색 쐐기로 만듭니다. 캔버스 # 3을 표시하지 않습니다 (가시성 : 숨김).

  3. 캔버스 # 2와 캔버스 # 3의 왼쪽 위 픽셀부터 캔버스 # 2와 캔버스 # 3의 모든 해당 픽셀을 반복합니다.

  4. # 2와 # 3의 해당 픽셀이 모두 "색상"인 경우 쐐기가 해당 픽셀에서 교차합니다. 당신이 (당신의 지정된 색으로 픽셀을 변경 같은) 교차 픽셀에서 캔버스 # 1에 원하는 STEP4에있는 "히트", 그릴

성능을 향상시키기 위해, 당신은을 계산할 수 있습니다에 대한

  • 두 개의 쐐기에 대한 경계 상자를 표시하고 교차하는지 확인합니다.

    쐐기가 전혀 교차하지 않으면 픽셀 히트 테스트가 필요하지 않습니다.

    교차하는 경우 결합 된 웨지의 경계 상자를 픽셀 히트 테스트하십시오.

  • +0

    감사 마크. 귀하의 솔루션은 견고하며 작동합니다. 나는 또한 일하는 내 자신의 솔루션 (http://jsfiddle.net/4fT3p/)을 생각해 내었다. 두 솔루션 모두 "나는 KineticJS를 사용하여 셰이프를 관리합니다"모델에서 벗어나 똑바로 세운 캔버스를 사용하기 때문에 다시는 마음에 들지 않습니다. 재미있는 일을하려면 KineticJS 사용을 중단해야하며 KineticJS는 성숙해야 할 일이 많습니다. Otoh, 나는 뭔가를 놓칠 수 있습니다. – Mae