【问题标题】:Scaling of JavaScript canvas looks strange after rotation旋转后 JavaScript 画布的缩放看起来很奇怪
【发布时间】:2019-09-18 21:28:13
【问题描述】:

我有一个 html 画布,它在 JS 脚本中被拉伸到浏览器窗口的尺寸。我想保持画布适合窗口尺寸(通过 ctx.scale 或 ctx.setTransform),但是当窗口垂直时将其旋转 90°,即 window.innerHeight > window.innerWidth。但是,我在垂直情况下看到一些奇怪的行为,不知道我错过了什么。

我的 JavaScript 代码如下:

var canvas = document.getElementById("GameCanvas");
var ctx = canvas.getContext("2d");
canv_start_w = canvas.width;
canv_start_h = canvas.height;

// drawing functions
function set_canvas_bg() {  
    ctx.fillStyle = "lightblue";
    ctx.fillRect(0,0,canvas.width, canvas.height);
}
function draw_line() {
    ctx.beginPath();
    ctx.lineWidth="3";
    ctx.strokeStyle="black";
    ctx.moveTo(canv_start_w/16, canv_start_h/2);
    ctx.lineTo(15*canv_start_w/16, canv_start_h/2);
    ctx.stroke();
    ctx.closePath();
}
function draw_circ() {
    ctx.beginPath();
    ctx.fillStyle="black";
    ctx.arc(canv_start_w/2, canv_start_h/2, canv_start_w/10, 0, 2*Math.PI);
    ctx.fill();
    ctx.closePath();
}

// canvas transformation functions
function resize_canvas() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
}
function scale_ctx() {
    var smaller_dim = Math.min(canvas.width, canvas.height);
    var larger_dim = Math.max(canvas.width, canvas.height)
    var xscale = larger_dim/canv_start_w;
    var yscale = smaller_dim/canv_start_h;
    ctx.setTransform(xscale, 0, 0, yscale, 0, 0);
}
function rotate_ctx(deg) {
    ctx.rotate((deg/360)*(2*Math.PI));
}

function update() {

    resize_canvas();
    scale_ctx();

    // distinction: vertical or horizontal window?
    if (window.innerWidth < window.innerHeight) {
        // CASE 1: vertical
        rotate_ctx(90);
        ctx.translate(0, -canvas.width); // move back into view
    } else {
        // CASE 2: horizontal
        rotate_ctx(0);
        ctx.translate(0, 0); // move back into view
    }

    // drawing elements to canvas
    set_canvas_bg();
    draw_circ();
    draw_line();
    requestAnimationFrame(update);
}

update();

【问题讨论】:

  • 可以发一张画布的截图吗?
  • 问题在于setTransform 和同时旋转,你需要在应用缩放后围绕中心旋转(计算它)

标签: javascript canvas rotatetransform scaletransform


【解决方案1】:

每次更改画布尺寸时,都会删除上下文转换(即旋转、缩放)。工作脚本可以在这里找到并进行试验:https://jsfiddle.net/nicoa47/3fsan6c0/

三部分解决方案是

(1) 在每个更新循环开始时重置转换 通过

ctx.setTransform(1, 0, 0, 1, 0, 0);

(2) 将上下文翻译到窗口中心并在旋转/缩放(确保围绕窗口中心旋转)后翻译回

ctx.translate(window.innerWidth/2, window.innerHeight/2);
// rotate...
// scale...
ctx.translate(-window.innerWidth/2, -window.innerHeight/2);

在垂直情况下,需要交换第二个翻译的参数。

(3) 根据当前比例更改缩放功能。也就是说,创建新变量

var canv_current_w = window.innerWidth;
var canv_current_h = window.innerHeight;

跟踪最后一帧的尺寸,即在更新循环集结束时:

canv_current_w = window.innerWidth;
canv_current_h = window.innerHeight;

再次,在垂直情况下交换值。用 scale 函数中的这些新变量替换 canv_start_w、canv_start_h。

【讨论】:

    猜你喜欢
    • 2012-08-07
    • 2014-08-23
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 2016-06-27
    • 2023-03-23
    • 1970-01-01
    相关资源
    最近更新 更多