2013-08-21 2 views
0

У меня возникли проблемы с получением рисунка для масштабирования, используя KineticJs. У меня есть рисунок, состоящий из нескольких объектов кинетического рисования, которые все находятся в группе. То, что я пытаюсь сделать, - отрегулировать длину чертежа, и если новая длина превышает определенный порог, тогда чертеж будет изменен.Масштабирование и перемещение чертежа с использованием KineticJs

Он хорошо работает до этого момента. Повторное масштабирование работает так, как ожидалось, но у меня возникают проблемы, когда дело доходит до того, чтобы снова нарисовать чертеж. Происходит подсчет начала рисунка, и я пытаюсь его переместить с помощью

drawingGroup.move(newOrigin.x, newOrigin.y) 

Начальное происхождение примерно 200 пикселей. Когда чертеж начинает масштабироваться, это значение равно 0, но по мере того, как изображение продолжает уменьшаться, оно начинает падать с левой стороны экрана.

Я не нашел хорошего примера, чтобы отрегулировать длину чертежа, а затем масштабировать, изменять размер и центрировать новый чертеж. Есть ли хороший способ сделать это?

ответ

0

Как сворачивать свою группу, чтобы поместиться на сцене, даже если группа состоит шире

Эта иллюстрация показывает, начиная «синий» группа - не расширен и не масштабируется.

enter image description here

Эта иллюстрация показывает синий группу после того, как он расширился за пределы сцены и масштабируется обратно.

enter image description here

Вот как сворачивать свою группу без нее «плавающим» слева:

  • Отменить любую предыдущую группу смещение (на величину любого предыдущего коэффициента масштабирования).
  • Рассчитать новый коэффициент масштабирования (например: уменьшить масштаб).
  • Сохраните новый коэффициент масштабирования для использования в любом будущем масштабировании.
  • Рассчитать новое смещение группы на основе нового коэффициента масштабирования.
  • Установите смещение группы на недавно измененное смещение.
  • Перерисовать слой.

Вам нужно будет добавить несколько свойств drawingGroup, связанные с масштабированием:

// the current SCALED offset 
drawingGroup.offsetX=0; 
drawingGroup.offsetY=0; 

// the point from which all scaling will occur 
drawingGroup.scalePtX=0; 
drawingGroup.scalePtY=0; 

// the amount of current scaling applied to the group 
// ==1.00 is the beginning un-scaled group 
// >1.00 scales the group larger 
// <1.00 scales the group smaller 
drawingGroup.scaleFactor=1.00; 

Затем добавьте этот метод drawingGroup фактически сделать масштабирование:

drawingGroup.scaleBy=function(scaleChange){ 

    // undo previous offset 
    this.offsetX += this.scalePtX/this.scaleFactor; 
    this.offsetY += this.scalePtY/this.scaleFactor; 

    // calc new scaling factor 
    var newScaleFactor = this.scaleFactor*(1+scaleChange); 

    // create new offset 
    this.offsetX -= this.scalePtX/newScaleFactor; 
    this.offsetY -= this.scalePtY/newScaleFactor; 

    // set new scale factor 
    this.scaleFactor=newScaleFactor; 

    // do the new offset 
    this.setOffset(this.offsetX,this.offsetY); 

    // do the new scale 
    this.setScale(this.scaleFactor); 

    layer.draw(); 

}; 

Это тестовый код, который оба расширяют группу и автоматически уменьшают ее, чтобы соответствовать этапу:

Этот тестовый код также заживает группу после downscal ING.

// widen by 20px 
    // if wider than stage, scale down by 15% 
    $("#wider").click(function(){ 
     drawingGroup.setWidth(drawingGroup.getWidth()+20); 
     rect.setWidth(drawingGroup.getWidth()); 
     var width=drawingGroup.getWidth()*drawingGroup.scaleFactor; 
     if(drawingGroup.getX()+width>stageWidth){ 
      drawingGroup.scaleBy(-0.15); 
      recenter(); 
     } 
     setStatus(); 
     layer.draw(); 
    }); 

    function recenter(){ 
     var w=drawingGroup.getWidth()*drawingGroup.scaleFactor; 
     var h=drawingGroup.getHeight()*drawingGroup.scaleFactor; 
     drawingGroup.setX(stage.getWidth()/2-w/2); 
     drawingGroup.setY(stage.getHeight()/2-h/2); 
    } 

Обратите внимание, что setX()/setY() может использоваться обычно для группы.

Просто не забудьте рассчитать шкалу ширину/высоту группы путем умножения на scalingFactor.

Вот полный код и скрипку: http://jsfiddle.net/m1erickson/UyDbW/

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.4.min.js"></script> 

<style> 
body{ padding:15px; } 
#container{ 
    border:solid 1px #ccc; 
    margin-top: 10px; 
    width:300px; 
    height:300px; 
} 
</style>   
<script> 
$(function(){ 

    var stage = new Kinetic.Stage({ 
     container: 'container', 
     width: 300, 
     height: 300 
    }); 
    var layer = new Kinetic.Layer(); 
    stage.add(layer); 

    // objects used in jquery events 
    var drawingGroup; 
    var rect,circle; 
    var stageWidth=stage.getWidth(); 
    var stageHeight=stage.getHeight(); 


    drawingGroup=new Kinetic.Group({ 
     x:stageWidth/2-50, 
     y:stageHeight/2-50, 
     width:100, 
     height:100, 
    }); 
    drawingGroup.offsetX=0; 
    drawingGroup.offsetY=0; 
    drawingGroup.scalePtX=0; 
    drawingGroup.scalePtY=0; 
    drawingGroup.scaleFactor=1.00; 
    drawingGroup.scaleBy=function(scaleChange){ 

     // undo previous offset 
     this.offsetX += this.scalePtX/this.scaleFactor; 
     this.offsetY += this.scalePtY/this.scaleFactor; 

     // calc new scaling factor 
     var newScaleFactor = this.scaleFactor*(1+scaleChange); 

     // create new offset 
     this.offsetX -= this.scalePtX/newScaleFactor; 
     this.offsetY -= this.scalePtY/newScaleFactor; 

     // set new scale factor 
     this.scaleFactor=newScaleFactor; 

     // do the new offset 
     this.setOffset(this.offsetX,this.offsetY); 

     // do the new scale 
     this.setScale(this.scaleFactor); 

     layer.draw(); 

    }; 
    layer.add(drawingGroup); 

    var rect=new Kinetic.Rect({ 
     x:0, 
     y:0, 
     width:100, 
     height:100, 
     stroke:"lightgray", 
     fill:"skyblue" 
    }); 
    drawingGroup.add(rect); 

    var circle=new Kinetic.Circle({ 
     x:50, 
     y:50, 
     radius:20, 
     fill:"blue" 
    }); 
    drawingGroup.add(circle); 

    var status=new Kinetic.Text({ 
     x:15, 
     y:15, 
     text:"width=100, scale=1.00", 
     fontSize:18, 
     fill:"red" 
    }); 
    layer.add(status); 

    setStatus(); 

    layer.draw(); 

    function setStatus(){ 
     var width=drawingGroup.getWidth(); 
     var scale=Math.round(drawingGroup.scaleFactor*100); 
     status.setText("Width: "+width+", Scale: "+scale+"%"); 
    } 


    // widen by 20px 
    // if wider than stage, scale down by 15% 
    $("#wider").click(function(){ 
     drawingGroup.setWidth(drawingGroup.getWidth()+20); 
     rect.setWidth(drawingGroup.getWidth()); 
     var width=drawingGroup.getWidth()*drawingGroup.scaleFactor; 
     if(drawingGroup.getX()+width>stageWidth){ 
      drawingGroup.scaleBy(-0.15); 
      recenter(); 
     } 
     setStatus(); 
     layer.draw(); 
    }); 

    function recenter(){ 
     var w=drawingGroup.getWidth()*drawingGroup.scaleFactor; 
     var h=drawingGroup.getHeight()*drawingGroup.scaleFactor; 
     drawingGroup.setX(stage.getWidth()/2-w/2); 
     drawingGroup.setY(stage.getHeight()/2-h/2); 
    } 


}); // end $(function(){}); 

</script>  
</head> 

<body> 
    <p>Blue group will scale if extending past stage</p> 
    <button id="wider">Wider</button> 
    <div id="container"></div> 
</body> 
</html> 
+0

Это близко к тому, что я ищу. Разница в том, что каждый раз, когда длина группы рисования расширяется, я пытаюсь обновить изображение внутри слоя, когда оно будет перерисовано. Знаете ли вы хороший способ сделать это? – Tom

+0

Я отредактировал свой ответ, чтобы повторно включить группу после того, как она была уменьшена. Обратите внимание, что вы можете использовать setX/setY обычно в группе. Тем не менее, getWidth/getHeight будет сообщать о немасштабированных значениях, поэтому вы должны умножить эту ширину/высоту с помощью scaleFactor drawingGroup, чтобы получить масштабированные размеры. – markE

+0

У меня есть обновление по этому вопросу. То, что я хотел бы сделать, - отрегулировать длину чертежа и масштабировать чертеж с каждым шагом. Я хотел бы, чтобы рисунок был центрирован по оси y, но рисунок должен быть установлен на 20 пикселей с левой стороны сцены. Я не смог правильно настроить масштабирование при использовании increment/decment. Есть ли способ заставить это работать? – Tom

Смежные вопросы