2012-10-30 28 views

回答

10

我知道這是一個可怕的老文章,但我需要實現這個確切的事情,發現接受的答案是相當有缺陷 - 在左邊的兩個拖拽手柄移動整個圖像和行爲非常不同的圖像編輯程序會,例如。我發佈了我的解決方案,以防有人像我一樣從Google搜索中絆倒了Google。

// Update the positions of handles during drag. 
// This needs to happen so the dimension calculation can use the 
// handle positions to determine the new width/height. 
switch (activeHandleName) { 
    case "topLeft": 
     topRight.setY(activeHandle.getY()); 
     bottomLeft.setX(activeHandle.getX()); 
     break; 
    case "topRight": 
     topLeft.setY(activeHandle.getY()); 
     bottomRight.setX(activeHandle.getX()); 
     break; 
    case "bottomRight": 
     bottomLeft.setY(activeHandle.getY()); 
     topRight.setX(activeHandle.getX()); 
     break; 
    case "bottomLeft": 
     bottomRight.setY(activeHandle.getY()); 
     topLeft.setX(activeHandle.getX()); 
     break; 
} 

// Calculate new dimensions. Height is simply the dy of the handles. 
// Width is increased/decreased by a factor of how much the height changed. 
newHeight = bottomLeft.getY() - topLeft.getY(); 
newWidth = image.getWidth() * newHeight/image.getHeight(); 

// Move the image to adjust for the new dimensions. 
// The position calculation changes depending on where it is anchored. 
// ie. When dragging on the right, it is anchored to the top left, 
//  when dragging on the left, it is anchored to the top right. 
if(activeHandleName === "topRight" || activeHandleName === "bottomRight") { 
    image.setPosition(topLeft.getX(), topLeft.getY()); 
} else if(activeHandleName === "topLeft" || activeHandleName === "bottomLeft") { 
    image.setPosition(topRight.getX() - newWidth, topRight.getY()); 
} 

imageX = image.getX(); 
imageY = image.getY(); 

// Update handle positions to reflect new image dimensions 
topLeft.setPosition(imageX, imageY); 
topRight.setPosition(imageX + newWidth, imageY); 
bottomRight.setPosition(imageX + newWidth, imageY + newHeight); 
bottomLeft.setPosition(imageX, imageY + newHeight); 

// Set the image's size to the newly calculated dimensions 
if(newWidth && newHeight) { 
    image.setSize(newWidth, newHeight); 
} 

修改KineticJS例如JSBin:http://jsbin.com/iyimuy/1/edit

+0

嘿,好人.. :)很酷 – ashishashen

+0

這是非常好的,你可以請張貼一個新的例子,最小的高度和寬度限制。那太好了 ! –

+0

只需將kinetic.js指向一個有效的URL,這就像一個魅力。 –

1

更改線路:

var width = topRight.attrs.x - topLeft.attrs.x; 
var height = bottomLeft.attrs.y - topLeft.attrs.y; 
if(width && height) { 
    image.setSize(width, height); 
} 

要:

var height = bottomLeft.attrs.y - topLeft.attrs.y; 
var width = image.getWidth()*height/image.getHeight(); 

topRight.attrs.x = topLeft.attrs.x + width; 
topRight.attrs.y = topLeft.attrs.y; 
bottomRight.attrs.x = topLeft.attrs.x + width; 
bottomRight.attrs.y = topLeft.attrs.y + height; 

if(width && height) { 
    image.setSize(width, height); 
} 

Example

+0

好..That是我question..How改變錨Logic..I已經知道如何保持縱橫比.. – ashishashen

+0

對不起,沒有正確理解你。我是編輯答案。 –

+0

THANKs man..works like a charm ... :) – ashishashen

0

我知道是不是這個問題,但伊夫失去了很多時間試圖當錨超越的圖像大小爲0,它拋出一個javasacript解決問題錯誤:

IndexSizeError: Index or size is negative or greater than the allowed amount 

我所做的是增加Math.abs圖像尺寸測算公式:

newHeight = Math.abs(bottomLeft.getY() - topLeft.getY()); 
newWidth = Math.abs(image.getWidth() * newHeight/image.getHeight()); 

它與兩個底部錨點都可以正常工作,但對頂部錨點不太好,我只是移除了頂部錨點,這對我的項目來說已經足夠好解決方案了....

希望這有助於某人!

1

這是:JSFIDDLE

JS:

function update(group, activeHandle) { 
     var topLeft = group.get(".topLeft")[0], 
      topRight = group.get(".topRight")[0], 
      bottomRight = group.get(".bottomRight")[0], 
      bottomLeft = group.get(".bottomLeft")[0], 
      image = group.get(".image")[0], 
      activeHandleName = activeHandle.getName(), 
      newWidth, 
      newHeight, 
      minWidth = 32, 
      minHeight = 32, 
      oldX, 
      oldY, 
      imageX, 
      imageY; 

     // Update the positions of handles during drag. 
     // This needs to happen so the dimension calculation can use the 
     // handle positions to determine the new width/height. 
     switch (activeHandleName) { 
      case "topLeft": 
       oldY = topRight.getY(); 
       oldX = bottomLeft.getX(); 
       topRight.setY(activeHandle.getY()); 
       bottomLeft.setX(activeHandle.getX()); 
       break; 
      case "topRight": 
       oldY = topLeft.getY(); 
       oldX = bottomRight.getX(); 
       topLeft.setY(activeHandle.getY()); 
       bottomRight.setX(activeHandle.getX()); 
       break; 
      case "bottomRight": 
       oldY = bottomLeft.getY(); 
       oldX = topRight.getX(); 
       bottomLeft.setY(activeHandle.getY()); 
       topRight.setX(activeHandle.getX()); 
       break; 
      case "bottomLeft": 
       oldY = bottomRight.getY(); 
       oldX = topLeft.getX(); 
       bottomRight.setY(activeHandle.getY()); 
       topLeft.setX(activeHandle.getX()); 
       break; 
     } 



     // Calculate new dimensions. Height is simply the dy of the handles. 
     // Width is increased/decreased by a factor of how much the height changed. 
     newHeight = bottomLeft.getY() - topLeft.getY(); 
     newWidth = image.getWidth() * newHeight/image.getHeight(); 

     // It's too small: move the active handle back to the old position 
     if(newWidth < minWidth || newHeight < minHeight){ 
      activeHandle.setY(oldY); 
      activeHandle.setX(oldX); 
      switch (activeHandleName) { 
      case "topLeft": 
       topRight.setY(oldY); 
       bottomLeft.setX(oldX); 
       break; 
      case "topRight": 
       topLeft.setY(oldY); 
       bottomRight.setX(oldX); 
       break; 
      case "bottomRight": 
       bottomLeft.setY(oldY); 
       topRight.setX(oldX); 
       break; 
      case "bottomLeft": 
       bottomRight.setY(oldY); 
       topLeft.setX(oldX); 
       break; 
      } 
     } 


     newHeight = bottomLeft.getY() - topLeft.getY(); 
     //comment the below line and uncomment the line below tha line to allow free resize of the images because the below line preserves the scale and aspect ratio 
     newWidth = image.getWidth() * newHeight/image.getHeight();//for restricted resizing 
     //newWidth = topRight.getX() - topLeft.getX();//for free resizing 

     // Move the image to adjust for the new dimensions. 
     // The position calculation changes depending on where it is anchored. 
     // ie. When dragging on the right, it is anchored to the top left, 
     //  when dragging on the left, it is anchored to the top right. 
     if(activeHandleName === "topRight" || activeHandleName === "bottomRight") { 
      image.setPosition(topLeft.getX(), topLeft.getY()); 
     } else if(activeHandleName === "topLeft" || activeHandleName === "bottomLeft") { 
      image.setPosition(topRight.getX() - newWidth, topRight.getY()); 
     } 

     imageX = image.getX(); 
     imageY = image.getY(); 

     // Update handle positions to reflect new image dimensions 
     topLeft.setPosition(imageX, imageY); 
     topRight.setPosition(imageX + newWidth, imageY); 
     bottomRight.setPosition(imageX + newWidth, imageY + newHeight); 
     bottomLeft.setPosition(imageX, imageY + newHeight); 

     // Set the image's size to the newly calculated dimensions 
     if(newWidth && newHeight) { 
      image.setSize(newWidth, newHeight); 
     } 
     } 
     function addAnchor(group, x, y, name) { 
     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 
     }); 

     anchor.on("dragmove", function() { 
      update(group, 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 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, 0, 0, "topLeft"); 
     addAnchor(darthVaderGroup, 200, 0, "topRight"); 
     addAnchor(darthVaderGroup, 200, 138, "bottomRight"); 
     addAnchor(darthVaderGroup, 0, 138, "bottomLeft"); 

     darthVaderGroup.on("dragstart", function() { 
      this.moveToTop(); 
     }); 
     // yoda 
     var yodaImg = new Kinetic.Image({ 
      x: 0, 
      y: 0, 
      image: images.yoda, 
      width: 93, 
      height: 104, 
      name: "image" 
     }); 

     yodaGroup.add(yodaImg); 
     addAnchor(yodaGroup, 0, 0, "topLeft"); 
     addAnchor(yodaGroup, 93, 0, "topRight"); 
     addAnchor(yodaGroup, 93, 104, "bottomRight"); 
     addAnchor(yodaGroup, 0, 104, "bottomLeft"); 

     yodaGroup.on("dragstart", function() { 
      this.moveToTop(); 
     }); 

     stage.draw(); 
     } 

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

不錯的拉胡爾! –

+0

謝謝,約瑟夫菲尼斯! :) –