画布:模拟带刻度和旋转的相机

时间:2014-07-16 15:29:57

标签: javascript math canvas

我创建了一个相机对象,其位置充当了屏幕的中心。相机允许缩放和旋转。基本上我所做的就是将画布的中心转换为原点,应用比例,然后旋转,现在我需要知道需要使用哪种棘手的数学将其转换回中心,这是我到目前为止的代码:

__Stage__.prototype.__cameraTransform = function() {
    var canvas = this.__canvas;
    var cam = this.camera;
    var context = this.__canvasContext;

    var cx = canvas.width/2;
    var cy = canvas.height/2;
    context.translate(-cx,-cy);

    var scale = {x: canvas.width/cam.width, y: canvas.height/cam.height};
    context.scale(scale.x,scale.y);

    var rotation = Math.PI*2 - (cam.rotation%(Math.PI*2));
    context.rotate(-rotation);

    context.translate(/*What translation to get the point back in the center*/);
}

1 个答案:

答案 0 :(得分:2)

首先,您可能希望保存上下文或因某种原因重置它 对于保存/恢复的事情,我无法猜测你将如何处理它,并通过以下方式完成重置:

function resetTransform() {
    c.setTransform(1, 0, 0, 1, 0, 0);
}

第二件事是你没有提到相机在哪里看,我认为它看起来是centerXcenterY

第三件事是你要避免在缩放时改变宽高比,而是计算画布的宽高比并使摄像机视图高度=摄像机视图宽度*画布比。

Object.defineProperty允许在对象上定义属性,因此您可以以干净的方式执行此操作:

// at the global level, after document loaded
//    OR where you handle the canvas
var canvasRatio = canvas.height / canvas.width;

//... in your camera constructor 
Object.defineProperty(this, 'height', {
    get: function () {
        return canvasRatio * this.width ;
    },
    set: function (val) {},
    enumerable: true
});

然后,您可能希望缓存画布大小,以避免在游戏过程中访问DOM。

对于你的旋转计算,我没有得到它但不需要钳制[0,2 * PI]或类似:只使用你拥有的任何弧度值(初始化为0)。

现在,对于您的相机,代码现在如下:

__Stage__.prototype.__cameraTransform = function() {
    var canvas = this.__canvas;
    var cam = this.camera;
    var context = this.__canvasContext;
   // O. reset ??
   resetTransform();
    //
    var cx = this.__canvasWidth/2;
    var cy = this.__canvasHeight/2;
    // 1 .  translate  to the middle of the canvas
    context.translate(cx,cy);
    // 2. scale
    var scale = this.__canvasWidth/cam.width;
    context.scale(scale,scale);
    // 3. translate to where the camera looks
    context.translate(-cam.centerX,-cam.centerY);
    // 4. rotate
    context.rotate(cam.rotation);    
}