2016-01-02 117 views
0

我从用户的网络摄影机拍摄照片并在画布上绘制。我使用CSS构建了视频控件,例如缩放视频,旋转视频,左右移动。它在直播中应用,但是当我在Canvas上拍照和画画时,这些功能(旋转,缩放)不适用。 我知道,因为我没有改变帆布,这就是为什么它不适用。在画布上绘制CSS转换(比例,旋转,左,右)

因此,任何想法如何使用相同的CSS代码在画布上绘制[旋转,缩放,左移/右移]。 (或者可能是Canvas上下文特有的代码)。

+0

查看html2canvas脚本https://html2canvas.hertzen.com。 –

+0

嗨@DariuszSikorski,不是添加许多scripts.libraries的忠实粉丝。 :) –

回答

0

转换变得简单。

不幸的是,给定的答案没有描述正确使用比例,平移和旋转函数。这些函数乘以现有的变换,因此结果是相对而非绝对的。例如从默认的转换

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

并非一切都失去了画布2D API提供了一个功能ctx.setTransform()其替换为新的一个当前变换。这不是相对的,而是绝对的。这使您可以确定地了解当前的转换并大大简化转换图像(或任何正在绘制的图像)的过程。

通用功能。

要在这里旋转缩放和定位图像是一个通用功能,为您做到这一点。

的争论

  • CTX:该2D画布上下文提请。
  • 图片:要绘制的图像。
  • x,y:绝对画布坐标,放置中心 坐标为,以画布左上角的像素为单位度量。
  • centerX,centerY:以像素为单位的图像原点坐标相对于协调的图像。如果图像是100乘100,那么将centerX,centerY设置为50,50将缩放并围绕图像中心旋转,并将该中心绘制在由参数x和y给定的坐标处。如果centerX,centerY被赋值为0,0,则图像将围绕左上角进行旋转和缩放。
  • 比例尺:绘制图像的比例。 1的值不是刻度,2是 的两倍大0.5是一半的大小。负数REVERS在x图像 和y方向
  • 旋转:以弧度0是没有 旋转和给出的旋转量,然后在90度步骤顺时针是Math.PI/2Math.PIMath.PI * 1.5,并返回到启动Math.PI * 2

它能做什么

的功能设置与所需的规模和T是绝对转型ranslation。将旋转应用于该变换,然后绘制图像偏移以将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 
); 
+0

谢谢@ blindman67 ... –

0

你不能通过CSS来做到这点,但是在绘制到画布上时有一些javascript。对于缩放,您需要半手动处理它,使用canvas.getContext()上下文中的参数drawImage。基本上参数2-5是从中提取图像的区域(按顺序),x,y,宽度和高度,参数6-9与图像的放入方式相同。

因此,举例来说,如果你的基础图像是2000×2000,你是成像成画布是1000×1000:

下面将刚刚绘制整个图像到较小的图像。

var ctx = canvas.getContext("2d"); 
ctx.drawImage(img,0,0,2000,2000,0,0,1000,1000); 

虽然这将绘制基本图像的中间1000×1000到画布(即2倍变焦):

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 

OR

var ctx = canvas.getContext("2d"); 
ctx.rotate(180 * Math.PI/180); //rotate 180 degrees 
ctx.translate(-canvas.width,-canvas.height); // translate down and over 

OR

var ctx = canvas.getContext("2d"); 
ctx.rotate(270 * Math.PI/180); //rotate 270 degrees 
ctx.translate(-canvas.width,0); // translate down and over 

注意周围的左上角发生旋转。如果你想支持自由旋转,它会变得更加复杂。

编辑:由于Blindman67在他的评论中正确注释,转换适用于基于任何先前应用的转换的上下文转换状态。我更新了代码示例,以澄清这是在应用于干净上下文时没有应用转换的转换的影响。

+0

嗨巴里,谢谢你的答案。虽然,现在我认为这需要额外的努力。所以,我正在取消控制。我喜欢如何绘制较小的图像部分。我补充说。感谢您的快速响应。 :) –

+0

@KalpeshSingh - :-) - 这是可以理解的。这有点痛苦。 –

+0

你没有提到旋转和翻译是相对于现有的变换。最后的代码段完全不正确,第一次旋转和平移是错误的方式,下面的转换是相对于现有的,注释并不反映实际的转换。我只能因为错误而投票,因为它只会让人们感到困惑。 – Blindman67