0

KineticJs を使用して図面を適切にスケーリングするのに問題があります。すべてがグループに保持されている多数のキネティック描画オブジェクトで構成された描画があります。私がやろうとしているのは、図面の長さを調整することです。新しい長さが特定のしきい値を超えると、図面が再スケーリングされます。

ここまではうまく機能します。再スケーリングは期待どおりに機能していますが、図面を再び中央に配置すると問題が発生します。図面の原点が計算されており、次を使用して移動しようとしています

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

最初の原点は約 200px です。描画が再スケーリングされ始めると、この値は 0 になりますが、画像が縮小し続けると、画面の左側からはみ出し始めます。

図面の長さを調整してから、新しい図面を拡大縮小、サイズ変更、中央揃えする良い例に出くわしませんでした。これを行う良い方法はありますか?

4

1 に答える 1

0

グループが広くなってもステージに収まるようにグループを縮小する方法

この図は、最初の「青」グループを示しています。拡大も縮小もされていません。

ここに画像の説明を入力

この図は、ステージを超えて拡大し、縮小した後の青色のグループを示しています。

ここに画像の説明を入力

グループを左に「フローティング」せずに縮小する方法は次のとおりです。

  • 以前のグループ オフセットを元に戻します (以前の倍率の量だけ)。
  • 新しい倍率を計算します (例: 縮小)。
  • 将来のスケーリングで使用するために、新しいスケーリング係数を保存します。
  • 新しい倍率に基づいて新しいグループ オフセットを計算します。
  • グループのオフセットを新しくスケーリングされたオフセットに設定します。
  • レイヤーを再描画します。

スケーリングに関連するいくつかのプロパティを 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();

};

これは、ステージに合わせてグループを拡大し、自動縮小するテスト コードです。

このテスト コードは、ダウンスケーリング後にグループを再センタリングします。

    // 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>
于 2013-08-22T06:14:19.967 に答える