2013-12-08 7 views
0

나는 앵커가 회전하는 데 도움이 필요합니다. 지금은 5 개의 앵커가 있으며 회전하는 것을 제외하고는 모두 제거하는 방법을 알지 못합니다. 사용자가 이미지 여기Kineticjs - 자유로운 회전 이미지

가리킬 때 나는 또한 단지 앵커처럼 보여 것이 나의 코드입니다

<html> 
<head> 
<style> 
body { 
margin: 0px; 
padding: 0px; 
} 
</style> 
</head> 
<body> 
<body onmousedown="return false;"> 
<div id="container"></div> 
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.4.min.js">  
</script> 
<script> 

function update(activeAnchor) { 
var group = activeAnchor.getParent(); 

var topLeft = group.get('.topLeft')[0]; 
var topRight = group.get('.topRight')[0]; 
var bottomRight = group.get('.bottomRight')[0]; 
var bottomLeft = group.get('.bottomLeft')[0]; 

var rotateAnchor = group.get('.rotateAnchor')[0]; 
var image = group.get('Image')[0]; 

var anchorX = activeAnchor.getX(); 
var anchorY = activeAnchor.getY(); 
var imageWidth = image.getWidth(); 
var imageHeight = image.getHeight(); 

var offsetX = Math.abs((topLeft.getX() + bottomRight.getX() + 10)/2); 
var offsetY = Math.abs((topLeft.getY() + bottomRight.getY() + 10)/2); 

// update anchor positions 
switch (activeAnchor.getName()) { 
    case 'rotateAnchor': 
     group.setOffset(offsetX, offsetY); 
     break; 
    case 'topLeft': 
     topRight.setY(anchorY); 
     bottomLeft.setX(anchorX); 
     break; 
    case 'topRight': 
     topLeft.setY(anchorY); 
     bottomRight.setX(anchorX); 
     break; 
    case 'bottomRight': 
     topRight.setX(anchorX); 
     bottomLeft.setY(anchorY); 
     break; 
    case 'bottomLeft': 
     topLeft.setX(anchorX); 
     bottomRight.setY(anchorY); 
     break; 
} 
rotateAnchor.setX(topRight.getX() + 5); 
rotateAnchor.setY(topRight.getY() + 20); 

image.setPosition((topLeft.getPosition().x + 20), (topLeft.getPosition().y + 20)); 
var width = topRight.getX() - topLeft.getX() - 30; 
var height = bottomLeft.getY() - topLeft.getY() - 30; 
if (width && height) { 
    image.setSize(width, height); 
} 
} 
function addAnchor(group, x, y, name, dragBound) { 
var stage = group.getStage(); 
var layer = group.getLayer(); 

var anchor = new Kinetic.Circle({ 
           x: x, 
           y: y, 
           stroke: '#666', 
           fill: '#ddd', 
           strokeWidth: 2, 
           radius: 8, 
           name: name, 
           draggable: true, 
           dragOnTop: false 
           }); 

if (dragBound == 'rotate') { 
    anchor.setAttrs({ 
        dragBoundFunc: function (pos) { 
        return getRotatingAnchorBounds(pos, group); 
        } 
        }); 
} 

anchor.on('dragmove', function() { 
      update(this); 
      layer.draw(); 
      }); 
anchor.on('mousedown touchstart', function() { 
      group.setDraggable(false); 
      this.moveToTop(); 
      }); 
anchor.on('dragend', function() { 
      group.setDraggable(true); 
      layer.draw(); 
      }); 
// add hover styling 
anchor.on('mouseover', function() { 
      var layer = this.getLayer(); 
      document.body.style.cursor = 'pointer'; 
      this.setStrokeWidth(4); 
      layer.draw(); 
      }); 
anchor.on('mouseout', function() { 
      var layer = this.getLayer(); 
      document.body.style.cursor = 'default'; 
      this.setStrokeWidth(2); 
      layer.draw(); 
      }); 

group.add(anchor); 
} 
function loadImages(sources, callback) { 
var images = {}; 
var loadedImages = 0; 
var numImages = 0; 
for(var src in sources) { 
    numImages++; 
} 
for(var src in sources) { 
    images[src] = new Image(); 
    images[src].onload = function() { 
     if(++loadedImages >= numImages) { 
      callback(images); 
     } 
    }; 
    images[src].src = sources[src]; 
} 
} 
function getRotatingAnchorBounds(pos, group) { 
var topLeft = group.get('.topLeft')[0]; 
var bottomRight = group.get('.bottomRight')[0]; 
var topRight = group.get('.topRight')[0]; 

var absCenterX = Math.abs((topLeft.getAbsolutePosition().x + 5 +  bottomRight.getAbsolutePosition().x + 5)/2); 
var absCenterY = Math.abs((topLeft.getAbsolutePosition().y + 5 + bottomRight.getAbsolutePosition().y + 5)/2); 

var relCenterX = Math.abs((topLeft.getX() + bottomRight.getX())/2); 
var relCenterY = Math.abs((topLeft.getY() + bottomRight.getY())/2); 

var radius = distance(relCenterX, relCenterY, topRight.getX() + 5, topRight.getY() + 20); 

var scale = radius/distance(pos.x, pos.y, absCenterX, absCenterY); 

var realRotation = Math.round(degrees(angle(relCenterX, relCenterY, topRight.getX() + 5, topRight.getY() + 20))); 
var rotation = Math.round(degrees(angle(absCenterX, absCenterY, pos.x, pos.y))); 
rotation -= realRotation; 

group.setRotationDeg(rotation); 

return { 
y: Math.round((pos.y - absCenterY) * scale + absCenterY), 
x: Math.round((pos.x - absCenterX) * scale + absCenterX) 
}; 
} 
function radians(degrees) { return degrees * (Math.PI/180); } 
function degrees(radians) { return radians * (180/Math.PI); } 

// Calculate the angle between two points. 
function angle(cx, cy, px, py) { 
var x = cx - px; 
var y = cy - py; 
return Math.atan2(-y, -x); 
} 

// Calculate the distance between two points. 
function distance(p1x, p1y, p2x, p2y) { 
return Math.sqrt(Math.pow((p2x - p1x), 2) + Math.pow((p2y - p1y), 2)); 
} 

function initStage(images) { 
var stage = new Kinetic.Stage({ 
           container: 'container', 
           width: 578, 
           height: 400 
           }); 
var darthVaderGroup = new Kinetic.Group({ 
             x: 270, 
             y: 100, 
             draggable: true 
             }); 
var yodaGroup = new Kinetic.Group({ 
            x: 100, 
            y: 110, 
            draggable: true 
            }); 
var layer = new Kinetic.Layer(); 

/* 
* go ahead and add the groups 
* to the layer and the layer to the 
* stage so that the groups have knowledge 
* of its layer and stage 
*/ 
layer.add(darthVaderGroup); 
layer.add(yodaGroup); 
stage.add(layer); 

// darth vader 
var darthVaderImg = new Kinetic.Image({ 
             x: 0, 
             y: 0, 
             image: images.darthVader, 
             width: 200, 
             height: 138, 
             name: 'image' 
             }); 

darthVaderGroup.add(darthVaderImg); 
addAnchor(darthVaderGroup, -20, -20, 'topLeft', 'none'); 
addAnchor(darthVaderGroup, 220, -20, 'topRight', 'none'); 
addAnchor(darthVaderGroup, 220, 158, 'bottomRight', 'none'); 
addAnchor(darthVaderGroup, -20, 158, 'bottomLeft','none'); 
addAnchor(darthVaderGroup, 225, 0, 'rotateAnchor','rotate'); 

darthVaderGroup.on('dragstart', function() { 
        this.moveToTop(); 
        }); 
stage.draw(); 
} 

var sources = { 
darthVader: 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg' 
}; 
loadImages(sources, initStage); 

</script> 
</body> 
</html> 

답변

1

각 앵커가 mouseenter /하는 MouseLeave 이벤트가를 표시하는 이미지 내부/숨기기 방법을 보여 사용할 수 있습니다 앵커 마우스가 이미지에 들어갈 때 :

image.on("mouseleave",function(){ anchor1.hide(); } 

image.on("mouseenter",function(){ anchor1.show(); layer.draw(); } 

문제를 당신의 앵커는 이미지 외부에 부분적으로 있기 때문에, 그래서 앵커를 숨기는 것은 마우스가 떠날 때 사용자가 사용하고자 할 때 앵커가 "사라"할 수있는 이미지 그들.

이상적인 해결책은 이미지가 포함 된 그룹에서 마우스 이벤트/마우스 제거 이벤트를 수신하는 것이지만 앵커의 바깥 부분을 포함하도록 확장하는 것이 가장 좋습니다. 안타깝게도 Kinetic.Group은 mouseenter/mouseleave 이벤트에 응답하지 않습니다.

해결 방법은 이미지와 앵커가 포함 된 그룹에 Kinetic.Rect 배경을 만드는 것입니다. rect는 mouseenter/mouseleave 이벤트를 수신하고 앵커를 표시하거나 숨 깁니다. 배경 사각형을 표시하지 않으려면 불투명도를 .001로 설정하십시오. rect는 여전히 이벤트를 수신하지만 보이지 않습니다.

groupBackgroundRect.on("mouseleave",function(){ anchor1.hide(); } 

groupBackgroundRect.on("mouseenter",function(){ anchor1.show(); layer.draw(); } 

관련 메모 : KineticJS 함께

리사이징과 회전 결합은 KineticJS가 객체의 회전 지점과 같이 모두 같은 offsetX은/offsetY 사용하기 때문에 필요 이상 더 어려워진다 그 위치로 오프셋. 작업을 수행하는 핵심은 이전 중심점이 아닌 새로운 중심점을 중심으로 회전이 수행되도록 크기를 조정 한 후 오프셋 점을 다시 중심화하는 것입니다. (또는 오프셋 참조 점을 회전하려는 다른 점으로 재설정하십시오).

+0

정말 고마워요! – gikygik