2013-03-21 134 views
0

我有一个包含8个锚点的图像。感谢example,我设法让四个角落的人只能缩放图片。但是我很难让其他4只能够拉伸图像。使用锚点对图像进行比例缩放和拉伸

midTop & midBottom船锚应垂直拉伸; midLeft和midRight锚点应水平延伸。我认为这可能涉及这些船锚可以移动的范围,但我不知道如何继续。

http://jsfiddle.net/Dppm7/3/(抱歉不能得到这个的jsfiddle工作)..

输出类似于this.

请如果有人可以提供帮助。 :)

为锚的一些代码(不是所有的代码中间锚已实施):

// 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()); 
     midRight.setY(activeHandle.getY()); 
     midTop.setY(activeHandle.getY()); 
     bottomLeft.setX(activeHandle.getX()); 
     midLeft.setX(activeHandle.getX()); 
     midBottom.setX(activeHandle.getX()); 
     break; 
    case "topRight": 
     topLeft.setY(activeHandle.getY()); 
     midLeft.setY(activeHandle.getY()); 
     midTop.setY(activeHandle.getY()); 
     bottomRight.setX(activeHandle.getX()); 
     midBottom.setX(activeHandle.getX()); 
     midRight.setX(activeHandle.getX()); 
     break; 
    case "bottomRight": 
     bottomLeft.setY(activeHandle.getY()); 
     midBottom.setY(activeHandle.getY()); 
     midLeft.setY(activeHandle.getY()); 
     topRight.setX(activeHandle.getX()); 
     midTop.setX(activeHandle.getX()); 
     midRight.setX(activeHandle.getX()); 
     break; 
    case "bottomLeft": 
     bottomRight.setY(activeHandle.getY()); 
     midBottom.setY(activeHandle.getY()); 
     midRight.setY(activeHandle.getY()); 
     topLeft.setX(activeHandle.getX()); 
     midTop.setX(activeHandle.getX()); 
     midLeft.setX(activeHandle.getX()); 
     break; 
    case "midTop": 
     topRight.setY(activeHandle.getY()); 
     topLeft.setY(activeHandle.getY()); 
     midRight.setY(activeHandle.getY()); 
     midLeft.setY(activeHandle.getY()); 
     break; 
    case "midBottom": 
     bottomRight.setY(activeHandle.getY()); 
     bottomLeft.setY(activeHandle.getY()); 
     midRight.setY(activeHandle.getY()); 
     midLeft.setY(activeHandle.getY()); 
     break; 
    case "midRight": 
     topRight.setX(activeHandle.getX()); 
     bottomRight.setX(activeHandle.getX()); 
     midTop.setX(activeHandle.getX()); 
     midBottom.setX(activeHandle.getX()); 
     break; 
    case "midLeft": 
     topLeft.setX(activeHandle.getX()); 
     bottomLeft.setX(activeHandle.getX()); 
     midTop.setX(activeHandle.getX()); 
     midBottom.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); 

midTop.setPosition(imageX + image.getWidth()/2, imageY); 
midBottom.setPosition(imageX + image.getWidth()/2, imageY + newHeight); 
midRight.setPosition(imageX + image.getWidth(), imageY + image.getHeight()/2); 
midLeft.setPosition(imageX, imageY + image.getHeight()/2); 

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

回答

0
<script> 
    var imWidth; 
    var imHeight; 
    var topRight; 
    var topLeft; 
    var bottomLeft; 
    var width; 
    var height; 
    var group; 
    var bottomRight; 
    var image; 
    var aspectRatio; 
    var oldwidth; 
    var oldheight; 
    var oldtopleftX; 
    var oldtopleftY; 
    var shrinkLimitBound; 

    function update(activeAnchor) { 
    group = activeAnchor.getParent(); 
    var anchorX = activeAnchor.getX(); 
    var anchorY = activeAnchor.getY(); 
    actRatio=imWidth/imHeight; 
    shrinkLimitBound=100; 
    height=bottomLeft.getY() - topLeft.getY(); 
    width=topRight.getX() - topLeft.getX(); 
    newRatio=(width)/(height); 
    width=actRatio*height; 
    switch (activeAnchor.getName()) { 
     case 'topLeft': 
     if(height<shrinkLimitBound) 
     { 
      height=shrinkLimitBound; 
      width=actRatio*height;; 
      topRight.setY(bottomRight.getY()-height); 
     } 
     else 
     { 
      if(anchorY < bottomRight.getY()) 
      topRight.setY(anchorY); 
      else 
      topRight.setY(bottomRight.getY()-height); 
     } 
     topRight.setX(bottomRight.getX()); 
     bottomLeft.setX(bottomRight.getX()-width); 
     bottomLeft.setY(bottomRight.getY()); 
     topLeft.setX(bottomRight.getX()-width); 
     topLeft.setY(bottomRight.getY()-height); 
     break; 
     case 'topRight': 
     if(height<shrinkLimitBound) 
     { 
      height=shrinkLimitBound; 
      width=actRatio*height;; 
      topLeft.setY(bottomLeft.getY()-height); 
     } 
     else 
     { 
      if(anchorY < bottomLeft.getY()-shrinkLimitBound) 
      { 
      topLeft.setY(anchorY) 
      } 
      else 
      { 
      topLeft.setY(bottomLeft.getY()-height); 
      } 
     } 
     topLeft.setX(bottomLeft.getX()); 
     bottomRight.setX(bottomLeft.getX()+width); 
     bottomRight.setY(bottomLeft.getY()); 
     topRight.setX(bottomLeft.getX()+width); 
     topRight.setY(bottomLeft.getY()-height); 
     break; 
     case 'bottomRight': 
     if(height<shrinkLimitBound) 
     { 
      height=shrinkLimitBound; 
      width=actRatio*height;; 
      bottomLeft.setY(topLeft.getY()+height); 
     } 
     else 
     { 
      if(anchorY > topLeft.getY()+shrinkLimitBound) 
      { 
      bottomLeft.setY(anchorY); 
      } 
      else 
      bottomLeft.setY(topLeft.getY()+height); 
     } 
     bottomLeft.setX(topLeft.getX()); 
     topRight.setX(topLeft.getX()+width); 
     topRight.setY(topLeft.getY()); 
     bottomRight.setX(topLeft.getX()+width); 
     bottomRight.setY(topLeft.getY()+height); 
     break; 
     case 'bottomLeft': 
     if(height<shrinkLimitBound) 
     { 
      height=shrinkLimitBound; 
      width=actRatio*height;; 
      bottomRight.setY(topRight.getY()+height); 
     } 
     else 
     { 
      if(anchorY > topRight.getY()) 
      bottomRight.setY(anchorY); 
      else 
      bottomRight.setY(topRight.getY()+height); 
     } 
     bottomRight.setX(topRight.getX()); 
     topLeft.setX(topRight.getX()-width); 
     topLeft.setY(topRight.getY()); 
     bottomLeft.setX(topRight.getX()-width); 
     bottomLeft.setY(topLeft.getY()+height); 
     break; 
    } 
    image.setPosition(topLeft.getPosition()); 
    if(width>0 && height>0) 
    { 
     image.setSize(width,height); 
    } 
    oldwidth=width; 
    oldheight=height; 
    oldtopleftX=topLeft.getX(); 
    oldtopleftY=topLeft.getY(); 

    } 

    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: 0, 
     radius: 4, 
     name: name, 
     draggable: true, 
     dragOnTop: false 
    }); 

    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 initStage(images) { 
    var conWidth = 578; //container Width. 
    var conHeight = 400; //container Heitgh. 
    imWidth = images.dressTrailImage.width; 
    imHeight = images.dressTrailImage.height; 
    if (imWidth > conWidth) 
    { 
     imHeight = (imHeight/imWidth)*conWidth; 
     imWidth = conWidth; 
    } 
    if (imHeight > conHeight) 
    { 
     imWidth = (imWidth/imHeight)*conHeight; 
     imHeight = conHeight; 
    } 
    if ((imHeight < conHeight) && (imWidth < conWidth)) 
    { 
     var diffX = conWidth - imWidth; 
     var diffY = conHeight - imHeight; 

     var diffY2 = (imHeight/imWidth)*diffX; 

     if (diffY2 > diffY) 
     { 
      imWidth = (imWidth/imHeight)*conHeight; 
      imHeight = conHeight; 
     } 
     else 
     { 
      imHeight = (imHeight/imWidth)*conWidth; 
      imWidth = conWidth; 
     }  
    } 
    images.UsrTrail.width = imWidth; 
    images.UsrTrail.height = imHeight; 
    var stage = new Kinetic.Stage({ 
     container: 'container', 
     width: imWidth, 
     height: imHeight 
    }); 
    var dressTrailImageGroup = new Kinetic.Group({ 
     x: 0, 
     y: 0, 
     draggable: true, 

     //dragBoundFunc: function(pos) { 

     // console.log(pos); 
     // // var newX; 
     // // var newY; 
     // console.log(topLeft.x+","+bottomRight.y); 
     // x1=topLeft.x; 
     // x2=bottomRight.x; 
     // y1=topLeft.y; 
     // y2=bottomRight.y; 
     // x=pos.x; 
     // y=pos.y; 
     // var calsign = ((x-x1)*(y-y2))-((y-y1)*(x-x2)) 
     // if (calsign < 0){ 
     // return { 
     // x : pos.x, 
     // y : pos.y 
     // } 
     // }else { 
     // return { 
     // x : 50, 
     // y : 50 
     // } 
     // } 

     //} 
     // if (pos.x <){ 
     // newX=10; 
     // } 
     // else if ((pos.x+dressTrailImage.getWidth()) > stage.getWidth()-50){ 
     //  newX = stage.getWidth()-dressTrailImage.getWidth()-50; 
     // } 
     // else{ 
     //  newX = pos.x; 
     // }; 


     // if(pos.y < 10){ 
     //  newY = 10; 
     // } 
     // else if((pos.y + dressTrailImage.getHeight()) > stage.getHeight()-50){ 
     //  newY = stage.getHeight()-dressTrailImage.getHeight()-50; 
     // } 
     // else { 
     //  newY = pos.y; 
     // } 

     //console.log("newX:"+newX+", newY:"+newY); 
     // return { 
     // x : newX, 
     // y : newY, 
     // }; 
     //} 
    }); 
    // UsrTrail 
    var UsrTrailImg = new Kinetic.Image({ 
     x: 0, 
     y: 0, 
     image: images.UsrTrail, 
     width: images.UsrTrail.width, 
     height: images.UsrTrail.height, 
     name: 'image' 
    }); 
    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(dressTrailImageGroup); 
    layer.add(UsrTrailImg); 
    stage.add(layer); 
    UsrTrailImg.moveToBottom(); 
    intialAspRatio = images.dressTrailImage.width/images.dressTrailImage.height; 
    console.log("aspectRatio is :"+intialAspRatio); 

    // dress Trail Image 

    var inith=200; //set this to the desired height of the dress that shows up initially 
    var initw=intialAspRatio*inith; 

    var neck_user_x=50;//from backend 
    var neck_user_y=20;//from backend 
    var neck_dress_x=50;//from backend 
    var neck_dress_y=5;//from backend 

//for getting the actual width and height of the User's Image 
var UsrImgObjActual= new Image(); 
UsrImgObjActual.src=sources.UsrTrail; 
UsrimgWidth=UsrImgObjActual.width; 
UsrimgHeight=UsrImgObjActual.height; 
////////////////////////////////////////// 

    // var UsrimgWidth= 180; 
    // var UsrimgHeight=270; 
console.log("height Should Be 270 and is:"+UsrimgHeight); 
console.log("Width Should Be 180 and is:"+UsrimgWidth); 
    var dressimgWidth=initw; 
    var dressimgHeight=inith; 

    console.log("usertrail image width adn height"+images.UsrTrail.width+"::"+images.UsrTrail.height); 
    console.log("neck user and dress resp"+neck_user_x+","+neck_user_y+','+neck_dress_x+','+neck_dress_y); 

    var x_draw=((neck_user_x*UsrimgWidth)-(neck_dress_x*dressimgWidth)); 
    var y_draw=((neck_user_y*UsrimgHeight)-(neck_dress_y*dressimgHeight)); 

    x_draw=x_draw/100; 
    y_draw=y_draw/100; 

    console.log("xdraw and ydraw:"+x_draw+','+y_draw); 

    //top left corner coordinates of the dress image. 
    var initx=x_draw; 
    var inity=y_draw; 

    var dressTrailImage = new Kinetic.Image({ 
     x: initx, 
     y: inity, 
     image: images.dressTrailImage, 
     name: 'image', 
     width: initw,// images.dressTrailImage.width, 
     height: inith //images.dressTrailImage.height 
    }); 

    // dressTrailImage.width = 50; 
    // dressTrailImage.height = dressTrailImage.width/intialAspRatio; 

    // console.log(dressTrailImage.height); 

    dressTrailImageGroup.add(dressTrailImage); 
    addAnchor(dressTrailImageGroup, initx , inity, 'topLeft'); 
    addAnchor(dressTrailImageGroup, initx + initw , inity , 'topRight'); 
    addAnchor(dressTrailImageGroup, initx + initw , inity + inith, 'bottomRight'); 
    addAnchor(dressTrailImageGroup, initx , inity + inith, 'bottomLeft'); 
    topLeft = dressTrailImageGroup.get('.topLeft')[0]; 
    topRight = dressTrailImageGroup.get('.topRight')[0]; 
    bottomRight = dressTrailImageGroup.get('.bottomRight')[0]; 
    bottomLeft = dressTrailImageGroup.get('.bottomLeft')[0]; 
    image = dressTrailImageGroup.get('.image')[0]; 
    dressTrailImageGroup.on('dragstart', function() { 
     this.moveToTop(); 
    }); 
    stage.draw(); 
    } 
    var sources = { 
    dressTrailImage: "http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg", 
    UsrTrail: "http://www.html5canvastutorials.com/demos/assets/yoda.jpg" 
    }; 

    loadImages(sources, initStage); 
    //function called on clicking the submit button. 
    function Sunmit_fn(){ 
       //neck positions of the trail dress in percentages (assumed for now!). 
       neckDressX=50;//in percentage. 
       neckDressY=5;//in percentage. 
       //height and width of the user image used in the canvas. 
     //original here here is refered to the height and width used in the canavs 
       var originalUserImgWidth = imWidth; 
       var originalUserImgHeight = imHeight; 
       var trailDressWidth = image.getWidth();//Final Image Width 
       var trailDressHeight = image.getHeight();//Final Image Height 
       imageX=topLeft.getParent().getX()+topLeft.getX()+1;//upper right anchor X Position 
       imageY=topLeft.getParent().getY()+topLeft.getY()+1;//upper right anchor Y Position 
       //formula for calculating the final neck positions of the resized and dragged dress 
      //with respect to the user image in percentages 
       neckFinalX=(imageX+(trailDressWidth*(neckDressX/100)))/originalUserImgWidth; 
       neckFinalY=(imageY+(trailDressHeight*(neckDressY/100)))/originalUserImgHeight; 
       //neck in percentages trail pic neck x,y. 
       neckFinalX=neckFinalX*100; 
       neckFinalY=neckFinalY*100; 
     //Just for testing. 
    console.log("neck position updated by User:"); 
     console.log("X:"+neckFinalX+", Y:"+neckFinalY+")"); 
     console.log("Resized Size of the dress is:"); 
     console.log("Width:"+trailDressWidth+", Height:"+trailDressHeight); 
      } 
</script> 

此脚本只沿一个轴调整大小四points.You可以计算出所有点相同