调整形状宽度时,旋转形状在y轴上移动

Jom*_*ppe 6 javascript html5-canvas

我正在尝试在画布上调整旋转的形状.我的问题是,当我调用渲染功能时,形状会根据形状角度开始"漂移".我怎么能阻止这个?

我做了一个简化的小提示来演示这个问题,当点击画布时,形状会长大,并且由于某种原因它会向上漂移.

这是小提琴:https://jsfiddle.net/x5gxo1p7/

<style>
    canvas {
        position: absolute;
        box-sizing: border-box;
        border: 1px solid red;
    }
</style>
<body>
<div>
    <canvas id="canvas"></canvas>
</div>
</body>

<script type="text/javascript">
    var canvas = document.getElementById('canvas');
    canvas.width = 300;
    canvas.height= 150;
    var ctx = canvas.getContext('2d');
    var counter = 0;

    var shape = {
        top: 120,
        left: 120,
        width: 120,
        height: 60,
        rotation: Math.PI / 180 * 15
    };



    function draw() {
        var h2 = shape.height / 2;
        var w2 = shape.width / 2;

        var x = w2;
        var y = h2;


        ctx.save();
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.translate(75,37.5)
        ctx.translate(x, y);

        ctx.rotate(Math.PI / 180 * 15);
        ctx.translate(-x, -y);

        ctx.fillStyle = '#000';
        ctx.fillRect(0, 0, shape.width, shape.height);
        ctx.restore();
}


canvas.addEventListener('click', function() {

    shape.width = shape.width + 15;
    window.requestAnimationFrame(draw.bind(this));
});

window.requestAnimationFrame(draw.bind(this));
</script>
Run Code Online (Sandbox Code Playgroud)

在"真实"代码中,单击并移动调整大小句柄时调整形状的大小,但我认为此示例充分展示了问题.

编辑:更新小提琴澄清问题:

https://jsfiddle.net/x5gxo1p7/9/

Jom*_*ppe 0

找到了解决方案,问题是我没有计算新的中心点坐标。

新的解决方案:https://jsfiddle.net/HTxGb/151/

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

canvas.width =500;
canvas.height = 500;

var x = canvas.width/2;
var y = canvas.height/2;
var rectw = 20;
var recth = 20;
var rectx = -rectw/2;
var recty = -recth/2;
var rotation = 0;
var addedRotation = Math.PI/12;
var addedWidth = 20;
var addedHeight = 10;

var draw = function() {
  ctx.save();
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.translate(x, y);
  ctx.rotate(rotation);
  ctx.fillRect(rectx, recty, rectw, recth);
  ctx.restore();
}


document.getElementById('growXRight').addEventListener('click', function() {
  rectx -= addedWidth/2;
  x += addedWidth/2 * Math.cos(rotation);
  y -= addedWidth/2 * Math.sin(-rotation);
  rectw += addedWidth;
  draw();
})

document.getElementById('growXLeft').addEventListener('click', function() {
  rectx -= addedWidth/2;
  x -= addedWidth/2 * Math.cos(rotation);
  y += addedWidth/2 * Math.sin(-rotation);
  rectw += addedWidth;
  draw();
})

document.getElementById('growYTop').addEventListener('click', function() {
  recty -= addedHeight/2;
  x += addedHeight/2 * Math.sin(rotation);
  y -= addedHeight/2 * Math.cos(-rotation);
  recth += addedHeight;
  draw();
})

document.getElementById('growYBottom').addEventListener('click', function() {
  recty -= addedHeight/2;
  x -= addedHeight/2 * Math.sin(rotation);
  y += addedHeight/2 * Math.cos(-rotation);
  recth += addedHeight;
  draw();
})

document.getElementById('rotatePlus').addEventListener('click', function() {
  rotation += addedRotation;
  rotation = rotation % (Math.PI*2);
  if(rotation % Math.PI*2 < 0) {
    rotation += Math.PI*2;
  }
  draw();
})

document.getElementById('rotateMinus').addEventListener('click', function() {
  rotation -= addedRotation;
  rotation = rotation % (Math.PI*2);
  if(rotation % Math.PI*2 < 0) {
    rotation += Math.PI*2;
  }
  draw();
})

draw();
Run Code Online (Sandbox Code Playgroud)