我正在从用户的网络相机拍照,并在画布上画它。我已经建立了使用CSS的视频控件,如缩放视频,旋转它,左/右移动。它适用于实时流,但当我在画布上拍照和绘画时,这些功能(旋转,缩放)不适用。我知道,因为我没有改变画布,这就是为什么它不适用。
因此,我可以使用相同的CSS代码在画布上画旋转、缩放、左/右移动。(或者可能是特定于画布上下文的代码)。
发布于 2016-01-02 18:34:34
转换简化了.
不幸的是,给出的答案未能描述缩放、平移和旋转函数的正确用法。这些函数乘以现有的变换,因此结果是相对的,而不是绝对的。例如,来自默认转换
ctx.setTransform(1, 0, 0, 1, 0, 0); // set the transformation to the default identity matrix
ctx.scale(2, 2); // scale the transform. Objects are now drawn 2 time larger
ctx.scale(2, 2); // This is applied to the existing scale
// objects are now draw 4 times as large not 2 times
ctx.rotate(Math.PI / 2); // rotate the transformation 90 deg clockwise
// objects are drawn with the x axis down the screen
ctx.rotate(Math.PI / 2); // Rotate a further 90 deg clockwise
// objects are drawn with the x axis from right to left
// and the y axis moves up
ctx.translate(x, y)
函数也是相对的,当您提供的坐标被现有的转换转换时,计算起来就更复杂了。因此,如果在上面的代码之后应用,给出100乘100的平移,将首先缩放并旋转4度和180度。得到的位置将位于画布坐标x:-400和y:-400处。要转换到所需的坐标(100,100),首先需要应用逆变换,这将导致ctx.translate(-25, -25)
因为无法确切地知道当前的转换,所以很难计算反变换并加以应用,这样就可以在画布坐标中工作。
setTransform
不是所有的东西都丢失了,Canvas2DAPI提供了一个函数ctx.setTransform()
,它用一个新的函数替换了当前的转换。它不是相对的,而是绝对的。这使您能够确切地知道当前的转换,并极大地简化了转换图像(或正在绘制的任何内容)的过程。
通用函数.
旋转,缩放和定位图像在这里是一个通用的功能,为您做到这一点。
的参数
Math.PI / 2
、Math.PI
、Math.PI * 1.5
和回到开始Math.PI * 2
。它做什么
该函数以所需的比例和翻译设置绝对转换。将旋转应用于该转换,然后绘制图像偏移量,将centerX、centerY放置在所需的坐标处。最后,函数将转换设置为默认值。如果您将函数或setTransform用于所有转换,则严格不需要这样做,但我添加它是为了避免80%的现有代码依赖于当前的默认转换。
函数源代码.
function drawImage(ctx, image, x, y, centerX, centerY, scale, rotate){
ctx.setTransform(scale, 0, 0, scale, x, y); // resets transform and
// set scale and position
ctx.rotate(rotate); // apply the rotation to the above transformation
ctx.drawImage(image, -centerX, -centerY); // draw the image offset to its center
ctx.setTransform(1, 0, 0, 1, 0, 0); // restore the transformation to default.
}
或不对默认转换执行不必要的重置的更简单版本。
function drawImage(ctx, image, x, y, centerX, centerY, scale, rotate){
ctx.setTransform(scale, 0, 0, scale, x, y); // resets transform and
// set scale and position
ctx.rotate(rotate); // apply the rotation to the above transformation
ctx.drawImage(image, -centerX, -centerY); // draw the image offset to its center
}
或者这个假设你总是使用图像中心
function drawImageCentered(ctx, image, x, y, scale, rotate){
ctx.setTransform(scale, 0, 0, scale, x, y); // resets transform and
// set scale and position
ctx.rotate(rotate); // apply the rotation to the above transformation
ctx.drawImage(image, -image.width / 2, -image.height / 2); // draw the image offset to its center
}
使用
// image; is a 200 by 200 pixel image
// ctx; is the canvas 2D context
// canvas; is the canvas element
// call the function
drawImage(
ctx, // the context
image, // the image to draw
canvas.width / 2, canvas.height / 2, //draw it at the center of the canvas
image.width / 2, image.height / 2, // at the image center
2, // scale to twice its size
Math.PI / 4 // and rotated clockwise 45 deg
);
发布于 2016-01-02 14:28:24
您不能通过CSS来完成它,但是在画布上绘图时可以使用一些javascript。对于缩放,您需要半手动地处理它,在来自drawImage
的上下文中使用参数canvas.getContext()
。基本上,参数2-5是(按顺序),x,y,宽度和高度,从其中提取的图像和参数6-9是相同的,它是如何被放入图像。
因此,例如,如果您的基本图像是2000x2000,并且要将其成像到一个画布中,该画布是1000x1000:
下面只需将整个图像绘制到较小的图像中。
var ctx = canvas.getContext("2d");
ctx.drawImage(img,0,0,2000,2000,0,0,1000,1000);
这将将基本图像的中间1000x1000绘制到画布中(即2x缩放):
var ctx = canvas.getContext("2d");
ctx.drawImage(img,500,500,1000,1000,0,0,1000,1000);
在上面,它是说,提取面积从(500,500)到(1500,1500),并“打印”到帆布。
旋转更复杂一些,因为如果您只是rotate
图像并从画布的原点(0,0)绘制,则图像将结束于画布之外。您还需要在画布上执行translate
。
var ctx = canvas.getContext("2d");
ctx.rotate(90 * Math.PI/180); //rotate 90 degrees
ctx.translate(0, -canvas.height); //translate down the height of the canvas
或
var ctx = canvas.getContext("2d");
ctx.rotate(180 * Math.PI/180); //rotate 180 degrees
ctx.translate(-canvas.width,-canvas.height); // translate down and over
或
var ctx = canvas.getContext("2d");
ctx.rotate(270 * Math.PI/180); //rotate 270 degrees
ctx.translate(-canvas.width,0); // translate down and over
注意,旋转发生在左上角附近。如果你想支持自由旋转,一切都会变得更加复杂。
编辑:正如Blindman67在他的注释中正确地指出的,转换应用于基于以前应用的任何转换的上下文的转换状态。我更新了代码示例,以说明这是将转换应用于干净上下文时的效果,而以前没有对其应用任何转换。
https://stackoverflow.com/questions/34566518
复制相似问题