html5画布中两个图像开始位置之间的差异

html5画布中两个图像开始位置之间的差异,html,html5-canvas,Html,Html5 Canvas,在画布中,我正在绘制一个矩形,缩放和转换后的矩形的起始位置与原始位置不同 是否有任何计算来查找原始矩形和缩放矩形的起始位置之间的差异。如何获取缩放矩形的差异或起始位置?缩放画布后,将缩放接下来的每个操作,包括变换。 所以你的第二个翻译: var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); ctx.strokeRect(50,50,200,200); ctx.translate(100,100); ctx.

在画布中,我正在绘制一个矩形,缩放和转换后的矩形的起始位置与原始位置不同


是否有任何计算来查找原始矩形和缩放矩形的起始位置之间的差异。如何获取缩放矩形的差异或起始位置?缩放画布后,将缩放接下来的每个操作,包括变换。
所以你的第二个翻译:

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

ctx.strokeRect(50,50,200,200);
ctx.translate(100,100);
ctx.scale(0.751,0.751);
ctx.translate(-100,-100);
ctx.strokeRect(50,50,200,200);
实际上是在原始坐标系中执行平移(-75.1,-75.1)。

平移(移动)、缩放和旋转都是变换。

一旦你做了几次深度变换,用算术追踪原始与变换的位置会变得非常可怕

在幕后,html画布使用矩阵数学来跟踪变换后的矩形的绘制位置

您还可以使用矩阵的幂来跟踪原始矩形左上角和变换矩形左上角之间的差异

矩阵实际上是一个由6个数字组成的数组。这是“单位矩阵”,表示原始未转换空间中的一个点

ctx.translate(-100,-100);
假设您的原始矩形位于X/Y(在您的示例中为50/50)

使用此包装器函数来平移和矩阵跟踪,而不仅仅是ctx.translate(100100)

var x=50;
var y=50;
回到原始空间后,使用矩阵跟踪变换后的矩形的位置

可以获得变换后的X/Y(但在原始空间中)的位置,如下所示:

function translate(translateByX,translateByY){
    matrix[4] += matrix[0] * translateByX + matrix[2] * translateByY;
    matrix[5] += matrix[1] * translateByX + matrix[3] * translateByY;
    ctx.translate(translateByX,translateByY);
}

下面是代码和小提琴:


正文{背景色:象牙;}
画布{边框:1px纯红;}
$(函数(){
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
//测试值
//目标:将此点跟踪到变换的空间中
var x=50;
变量y=50;
//x/y点的变换矩阵
var矩阵=[1,0,0,1,0,0];
//用蓝色绘制第一个矩形
ctx.save();
ctx.beginPath();
ctx.strokeStyle=“蓝色”;
ctx.strokeRect(x,y,200200);
//使用包装的变换函数进行变换
//所以矩阵也被跟踪了
翻译(100100);
刻度(0.751,0.751);
翻译(-100,-100);
//绘制第二个矩形(现在在变换的空间中)
ctx.beginPath();
ctx.strokeStyle=“绿色”;
ctx.strokeRect(x,y,200200);
ctx.restore();
//注意:ctx.restore()已取消转换我们的空间
//得到原始XY,该XY已使用矩阵进行变换
var=getXY();
//在变换后的x/y轴上绘制一个点
ctx.beginPath();
弧(转换后的.x,转换后的.y,5,0,数学PI*2,假);
ctx.closePath();
ctx.fillStyle=“红色”;
ctx.fill();
//翻译
//但也要将翻译保存在矩阵中
函数平移(x,y){
矩阵[4]+=矩阵[0]*x+矩阵[2]*y;
矩阵[5]+=矩阵[1]*x+矩阵[3]*y;
ctx.translate(x,y);
}
//做秤
//而且还可以在矩阵中保存规模
功能标度(x,y){
矩阵[0]*=x;
矩阵[1]*=x;
矩阵[2]*=y;
矩阵[3]*=y;
ctx.刻度(x,y);
}
//做旋转运动
//但也保存矩阵中的旋转
函数旋转(弧度){
var cos=数学cos(弧度);
var sin=数学sin(弧度);
var m11=矩阵[0]*cos+矩阵[2]*sin;
var m12=矩阵[1]*cos+矩阵[3]*sin;
var m21=-矩阵[0]*sin+矩阵[2]*cos;
var m22=-矩阵[1]*sin+矩阵[3]*cos;
矩阵[0]=m11;
矩阵[1]=m12;
矩阵[2]=m21;
矩阵[3]=m22;
ctx.旋转(弧度);
}
//从矩阵中获取变换点
函数getXY(顶点){
newX=x*矩阵[0]+y*矩阵[2]+矩阵[4];
newY=x*矩阵[1]+y*矩阵[3]+矩阵[5];
返回({x:newX,y:newY});
}
}); // end$(函数(){});
蓝色=在原始空间中绘制

绿色=绘制的变换空间

红色=在原始空间绘制,但使用矩阵跟踪

跟踪x/y=


将第二个矩形与比例参数相乘:)<代码>冲程(x*0.751,y*0.751,h*0.751,w*0.751)
function translate(translateByX,translateByY){
    matrix[4] += matrix[0] * translateByX + matrix[2] * translateByY;
    matrix[5] += matrix[1] * translateByX + matrix[3] * translateByY;
    ctx.translate(translateByX,translateByY);
}
function getXY(){
    newX = x * matrix[0] + y * matrix[2] + matrix[4];
    newY = x * matrix[1] + y * matrix[3] + matrix[5];
    return({x:newX,y:newY});
} 
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

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

    // test values
    // objective: track this point into transformed space
    var x=50;
    var y=50;

    // a transform matrix for point x/y
    var matrix=[1,0,0,1,0,0];

    // draw the first rectangle in blue
    ctx.save();
    ctx.beginPath();
    ctx.strokeStyle="blue";
    ctx.strokeRect(x,y,200,200);

    // do transforms using the wrapped transform functions
    // so the matrix is also tracked
    translate(100,100);
    scale(0.751,0.751);
    translate(-100,-100);


    // draw the second rectangle (now in transformed space)
    ctx.beginPath();
    ctx.strokeStyle="green";
    ctx.strokeRect(x,y,200,200);
    ctx.restore();

    // Note: ctx.restore() has un-transformed our space

    // get our original XY which has been transformed using the matrix
    var transformed=getXY();

    // draw a dot at the transformed x/y
    ctx.beginPath();
    ctx.arc(transformed.x,transformed.y,5,0,Math.PI*2,false);
    ctx.closePath();
    ctx.fillStyle="red";
    ctx.fill();


    // do the translate
    // but also save the translate in the matrix
    function translate(x,y){
        matrix[4] += matrix[0] * x + matrix[2] * y;
        matrix[5] += matrix[1] * x + matrix[3] * y;
        ctx.translate(x,y);
    }

    // do the scale
    // but also save the scale in the matrix
    function scale(x,y){
        matrix[0] *= x;
        matrix[1] *= x;
        matrix[2] *= y;
        matrix[3] *= y;    
        ctx.scale(x,y);
    }

    // do the rotate
    // but also save the rotate in the matrix
    function rotate(radians){
        var cos = Math.cos(radians);
        var sin = Math.sin(radians);
        var m11 = matrix[0] * cos + matrix[2] * sin;
        var m12 = matrix[1] * cos + matrix[3] * sin;
        var m21 = -matrix[0] * sin + matrix[2] * cos;
        var m22 = -matrix[1] * sin + matrix[3] * cos;
        matrix[0] = m11;
        matrix[1] = m12;
        matrix[2] = m21;
        matrix[3] = m22;   
        ctx.rotate(radians);
    }

    // get the transformed point from the matrix
    function getXY(vertex){
        newX = x * matrix[0] + y * matrix[2] + matrix[4];
        newY = x * matrix[1] + y * matrix[3] + matrix[5];
        return({x:newX,y:newY});
    }

}); // end $(function(){});
</script>

</head>

<body>
    <p>Blue=drawn in original space</p>
    <p>Green=drawn transformed space</p>
    <p>Red=drawn in original space but tracked with matrix!</p>
    <p id="newXY">Tracked x/y=</p>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>