首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在画布上绘制CSS转换(缩放、旋转、左、右)

在画布上绘制CSS转换(缩放、旋转、左、右)
EN

Stack Overflow用户
提问于 2016-01-02 13:40:46
回答 2查看 2.1K关注 0票数 1

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

因此,我可以使用相同的CSS代码在画布上画旋转、缩放、左/右移动。(或者可能是特定于画布上下文的代码)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-02 18:34:34

转换简化了.

不幸的是,给出的答案未能描述缩放、平移和旋转函数的正确用法。这些函数乘以现有的变换,因此结果是相对的,而不是绝对的。例如,来自默认转换

代码语言:javascript
运行
复制
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(),它用一个新的函数替换了当前的转换。它不是相对的,而是绝对的。这使您能够确切地知道当前的转换,并极大地简化了转换图像(或正在绘制的任何内容)的过程。

通用函数.

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

的参数

  • ctx:要绘制的2D画布上下文。
  • 图像:要绘制的图像。
  • x,y:将中心坐标放在画布左上角的绝对画布坐标,以像素为单位。
  • centerX,centerY:图像原点的坐标(相对于图像协调的像素)。如果图像为100×100,则设置centerX,centerY为50,50将缩放和旋转图像的中心,并在参数x和y所给的坐标处绘制该中心。如果centerX,centerY设为0,0,则图像在左上角旋转和缩放。
  • 刻度:绘制图像的比例。1的值不是刻度,2是大0.5的两倍是一半大小。负数在x和y方向上恢复图像。
  • 旋转:以弧度表示的旋转量,0不旋转,然后顺时针方向旋转90度,依次为Math.PI / 2Math.PIMath.PI * 1.5和回到开始Math.PI * 2

它做什么

该函数以所需的比例和翻译设置绝对转换。将旋转应用于该转换,然后绘制图像偏移量,将centerX、centerY放置在所需的坐标处。最后,函数将转换设置为默认值。如果您将函数或setTransform用于所有转换,则严格不需要这样做,但我添加它是为了避免80%的现有代码依赖于当前的默认转换。

函数源代码.

代码语言:javascript
运行
复制
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.
}

或不对默认转换执行不必要的重置的更简单版本。

代码语言:javascript
运行
复制
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
}

或者这个假设你总是使用图像中心

代码语言:javascript
运行
复制
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
}

使用

代码语言:javascript
运行
复制
// 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
); 
票数 2
EN

Stack Overflow用户

发布于 2016-01-02 14:28:24

您不能通过CSS来完成它,但是在画布上绘图时可以使用一些javascript。对于缩放,您需要半手动地处理它,在来自drawImage的上下文中使用参数canvas.getContext()。基本上,参数2-5是(按顺序),x,y,宽度和高度,从其中提取的图像和参数6-9是相同的,它是如何被放入图像。

因此,例如,如果您的基本图像是2000x2000,并且要将其成像到一个画布中,该画布是1000x1000:

下面只需将整个图像绘制到较小的图像中。

代码语言:javascript
运行
复制
var ctx = canvas.getContext("2d");
ctx.drawImage(img,0,0,2000,2000,0,0,1000,1000);

这将将基本图像的中间1000x1000绘制到画布中(即2x缩放):

代码语言:javascript
运行
复制
var ctx = canvas.getContext("2d");
ctx.drawImage(img,500,500,1000,1000,0,0,1000,1000);

在上面,它是说,提取面积从(500,500)到(1500,1500),并“打印”到帆布。

旋转更复杂一些,因为如果您只是rotate图像并从画布的原点(0,0)绘制,则图像将结束于画布之外。您还需要在画布上执行translate

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
var ctx = canvas.getContext("2d");
ctx.rotate(180 * Math.PI/180);    //rotate 180 degrees
ctx.translate(-canvas.width,-canvas.height);  // translate down and over

代码语言:javascript
运行
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34566518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档