在画布上绘制CSS变换(缩放,旋转,左,右) [英] Draw CSS transformation (Scale, Rotate, Left, Right) on Canvas

查看:160
本文介绍了在画布上绘制CSS变换(缩放,旋转,左,右)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从用户的网络相机拍照,并在画布上绘制。我已经使用CSS构建视频控件,如缩放视频,旋转它,向左/右移动。它应用于实时流,但是当我拍摄照片和在画布上绘制这些功能(旋转,缩放)不适用。
我知道,因为我没有改变Canvas,这就是为什么它不适用。



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

解决方案

>

不幸的是,给定的答案无法描述scale,translate和rotate函数的正确用法。这些函数乘以现有变换,因此结果是相对的,而不是绝对的。例如从默认转换

  ctx.setTransform(1,0,0,1,0,0); //将转换设置为默认单位矩阵
ctx.scale(2,2); //缩放变换。对象现在绘制大2倍
ctx.scale(2,2); //这适用于现有的缩放
//对象现在绘制4倍大,而不是2倍
ctx.rotate(Math.PI / 2); //旋转变换90度顺时针
//对象被绘制为x轴在屏幕上
ctx.rotate(Math.PI / 2); //顺时针旋转90度
//对象用x轴从右到左绘制
//,y轴向上移动

ctx.translate(x,y)函数也是相对的,您提供的坐标将通过现有转换进行转换。因此,如果在上述代码给出100乘100的平移之后应用将首先缩放并旋转4和180度。所得到的位置将在画布坐标x:-400和y:-400。要转换到所需的坐标(100,100)将需要首先应用逆变换,这将导致 ctx.translate(-25,-25)



因为没有办法确定地知道当前的变换,很难计算逆变换和应用,所以你可以在画布坐标工作。



setTransform



不是所有的都丢失了canvas 2D API提供了一个函数 ctx.setTransform(),它用当前的转换替换一个新的转换。这不是相对的,而是绝对的。这允许您确定地知道当前的变换,并大大简化了变换图像(或任何绘制的东西)的过程。



一个通用函数。 strong>



在这里旋转缩放和放置图片是一个通用的功能。



参数




  • ctx :要绘制的2D画布上下文。

  • image :要绘制的图片。

  • x,y :以画布左上角的像素为单位,以画布为中心放置中心
    坐标的绝对画布坐标。

  • centerX,centerY :图像原点的坐标,相对于协调的图像以像素为单位。如果图像是100乘100,则将centerX,centerY设置为50,50将缩放并围绕图像的中心旋转,并在由参数x和y给出的坐标处绘制该中心。如果centerX,centerY指定为0,0,则图像将围绕左上角旋转和缩放。

  • 缩放:绘制图像的比例。值为1是无刻度,2是
    两倍大0.5是一半的大小。负数将在x和y方向上颠倒图片

  • 旋转:以弧度表示的旋转量,旋转,然后顺时针旋转90Deg步骤 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
      //设置比例和位置
      ctx.rotate(rotate); //将旋转应用于上述转换
      ctx.drawImage(image,-centerX,-centerY); //将图像偏移绘制到它的中心
      ctx.setTransform(1,0,0,1,0,0); //将转换恢复为默认值。
      }



      或者更简单的版本不做不必要的重置为默认转换

        function drawImage(ctx,image,x,y,centerX,centerY,scale,rotate){
      ctx.setTransform (scale,0,0,scale,x,y); // resets transform and
      //设置比例和位置
      ctx.rotate(rotate); //将旋转应用于上述转换
      ctx.drawImage(image,-centerX,-centerY); //将图像偏移绘制到它的中心
      }

      图像中心

        function drawImageCentered(ctx,image,x,y,scale,rotate){
      ctx.setTransform (scale,0,0,scale,x,y); // resets transform and
      //设置比例和位置
      ctx.rotate(rotate); //将旋转应用到上面的转换
      ctx.drawImage(image,-image.width / 2,-image.height / 2); // draw the image offset to its center
      }

      使用

        // image;是一个200乘200像素的图像
      // ctx;是canvas 2D上下文
      // canvas;是画布元素

      //调用函数
      drawImage(
      ctx,//上下文
      image,//要绘制的图像
      canvas .width / 2,canvas.height / 2,//在画布的中心绘制
      image.width / 2,image.height / 2,//在图像中心
      2, /缩放到其大小的两倍
      Math.PI / 4 //,顺时针旋转45度
      );


      I'm taking photos from user's web camera and drawing it on Canvas. I have built video controls using CSS such as zooming video, rotating it, moving left/right. It's applying on live stream, but When I take photos and draw on Canvas these features (rotate, zoom) don't apply. I know, because I haven't altered Canvas that's why it isn't applying.

      So, any idea how can I draw [rotated, zoomed, moved left/right] on canvas using that same CSS code. (or may be code specific to Canvas context).

      解决方案

      Transformation made easy.

      Unfortunately the given answer fails to describe the correct usage of scale, translate, and rotate functions. These function multiply the existing transformation and thus the results are relative rather than absolute. For example from the default transformation

      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
      

      The ctx.translate(x, y) function is also relative and is more complicated to work out as the coordinates that you provide are transformed by the existing transformation. So if applied after the above code giving a translation of 100 by 100 would first scale and rotate by 4 and 180 degrees. The resulted position would be at the canvas coordinates x:-400 and y:-400. To translate to the desired coordinates (100, 100) would require first applying the inverse transformation, that would result in ctx.translate(-25, -25)

      Because there is no way to know with certainty the current transformation it is very difficult to compute the inverse transformation and apply that so you can work in canvas coordinates.

      setTransform

      Not all is lost the canvas 2D API provides a function ctx.setTransform() which replaces the current transformation with a new one. It is not relative but absolute. This allows you to know with certainty the current transformation and greatly simplifies the process of transforming an image (or anything being drawn)

      A general purpose function.

      To rotate zoom and position an image here is a general purpose function to do that for you.

      The Arguments

      • ctx: The 2D canvas context to draw to.
      • image: The Image to be drawn.
      • x, y: The absolute canvas coordinates to place the center coordinates at, measured in pixels from the top left of the canvas.
      • centerX, centerY: The coordinates of the image origin in pixels relative to the image coordinated. If the image is 100 by 100 then setting centerX, centerY to 50,50 will scale and rotate around the center of the image and draw that center at the coordinates given by the arguments x and y. if centerX, centerY are given as 0,0 then the image is rotated and scaled around the top left corner.
      • scale: The scale to draw the image. A value of 1 is no scale, 2 is twice as big 0.5 is half the size. Negative numbers revers the image in the x and y directions
      • rotate: The amount of rotation given in radians with 0 being no rotation and then in 90Deg steps clockwise are Math.PI / 2, Math.PI, Math.PI * 1.5, and back to the start Math.PI * 2

      What it does

      The function sets the absolute transformation with the desired scale and translation. The applies the rotation to that transform, then draws the image offset to place the centerX, centerY at the desired coordinates. Finally the function set the transformation back to the default. This is strictly not needed if you use the function or setTransform for all transformations but I have added it to not mess up 80% of existing code that would rely on the default transform being current.

      The Function source code.

      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.
      }
      

      Or the simpler version that does not do the unneeded reset to the default transform

      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
      }
      

      Or this that assumes you always use the image 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
      }
      

      Usage

      // 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
      ); 
      

      这篇关于在画布上绘制CSS变换(缩放,旋转,左,右)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆