QML Canvas:渲染中的不同行为

Mau*_*uri 11 html javascript qt canvas qml

我试图使用Canvas对象在QML中绘制环形扇区.首先,我编写了javascript代码,并通过在浏览器中执行它验证了它是正确的.

这里是:

var can = document.getElementById('myCanvas');
var ctx=can.getContext("2d");
var center = {
  x: can.width / 2,
  y: can.height / 2
};
var minRad = 100;
var maxRad = 250;

var startAngle = toRad(290);
var endAngle = toRad(310);

drawAxis();
drawSector();

function drawSector() {
  var p1 = {
    x: maxRad * Math.cos(startAngle),
    y: maxRad * Math.sin(startAngle)
  }
  p1 = toCanvasSpace(p1);

  var p2 = {
    x: minRad * Math.cos(startAngle),
    y: minRad * Math.sin(startAngle)
  }
  p2 = toCanvasSpace(p2);

  var p3 = {
    x: minRad * Math.cos(endAngle),
    y: minRad * Math.sin(endAngle)
  }
  p3 = toCanvasSpace(p3);
  var p4 = {
    x: maxRad * Math.cos(endAngle),
    y: maxRad * Math.sin(endAngle)
  }
  p4 = toCanvasSpace(p4);

  ctx.beginPath();
  ctx.moveTo(p1.x, p1.y);
  ctx.arc(center.x, center.y, maxRad, startAngle, endAngle);
  ctx.lineTo(p3.x, p3.y);
  ctx.arc(center.x, center.y, minRad, endAngle, startAngle, true);
  ctx.closePath();

  ctx.strokeStyle = "blue";
  ctx.lineWidth = 2;
  ctx.stroke();
}


function drawAxis() {
  ctx.beginPath();
  ctx.moveTo(can.width / 2, 0);
  ctx.lineTo(can.width / 2, can.height);
  ctx.stroke();
  ctx.beginPath();
  ctx.moveTo(0, can.height / 2);
  ctx.lineTo(can.width, can.height / 2);
  ctx.stroke();
}

function toRad(degrees) {
  return degrees * Math.PI / 180;
}

function toCanvasSpace(p) {
  var ret = {};
  ret.x = p.x + can.width / 2;
  ret.y = p.y + can.height / 2;
  return ret;
}
Run Code Online (Sandbox Code Playgroud)

在这里你可以运行上面的代码.输出是这样的:

在此输入图像描述

接下来,我将相同的代码移动到Qml中的Canvas对象中.

在这里看到包含Canvas的main.qml:

import QtQuick 2.5
import QtQuick.Window 2.2

Window {
    visible: true
    width: 500
    height: 500
    x:500

    Canvas
    {
        id: can
        anchors.fill: parent
        antialiasing: true



        onPaint: {
            var ctx=can.getContext("2d");

            var center = {
                x: can.width / 2,
                y: can.height / 2
            };
            var minRad = 100;
            var maxRad = 250;

            var startAngle = toRad(290);
            var endAngle = toRad(310);

            drawAxis();
            drawSector();

            function drawSector() {
                var p1 = {
                    x: maxRad * Math.cos(startAngle),
                    y: maxRad * Math.sin(startAngle)
                }
                p1=toCanvasSpace(p1);

                var p2 = {
                    x: minRad * Math.cos(startAngle),
                    y: minRad * Math.sin(startAngle)
                }
                p2=toCanvasSpace(p2);

                var p3 = {
                    x: minRad * Math.cos(endAngle),
                    y: minRad * Math.sin(endAngle)
                }
                p3=toCanvasSpace(p3);
                var p4 = {
                    x: maxRad * Math.cos(endAngle),
                    y: maxRad * Math.sin(endAngle)
                }
                p4=toCanvasSpace(p4);

                ctx.beginPath();
                ctx.moveTo(p1.x, p1.y);
                ctx.arc(center.x, center.y, maxRad, startAngle, endAngle);
                ctx.lineTo(p3.x, p3.y);
                ctx.arc(center.x, center.y, minRad, endAngle, startAngle, true);
                ctx.closePath();

                ctx.strokeStyle="blue";
                ctx.lineWidth=2;
                ctx.stroke();
            }


            function drawAxis() {
                ctx.beginPath();
                ctx.moveTo(can.width / 2, 0);
                ctx.lineTo(can.width / 2, can.height);
                ctx.stroke();
                ctx.beginPath();
                ctx.moveTo(0, can.height / 2);
                ctx.lineTo(can.width, can.height / 2);
                ctx.stroke();
            }

            function toRad(degrees) {
                return degrees * Math.PI / 180;
            }

            function toCanvasSpace(p) {
                var ret = {};
                ret.x = p.x + can.width / 2;
                ret.y = p.y + can.height / 2;
                return ret;
            }


        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我得到这个输出:

在此输入图像描述

正如你所看到的,底部有一个不完美的地方.

我真的不明白为什么会有这种不完美之处; 而且我不明白为什么相同的代码给出不同的输出.

任何帮助表示赞赏!谢谢

Ali*_*aru 4

不需要lineTo p3,因为arc绘制线段时,会根据Canvas规范自动绘制连接线:

在两个半径相等的情况下,arc() 方法与 ellipse() 方法等效。[...]

当调用 ellipse() 方法时,必须按如下方式进行。首先,如果对象的路径有任何子路径,则该方法必须添加一条从子路径中的最后一个点到圆弧起点的直线。

另外,moveTo p1也不需要,因为它将作为第一个弧的一部分完成。

至于为什么额外的线被绘制得比第二条弧线的起点更远,这可能是 Qt 中的一个错误(可能是按问题除法0- 只是在这里猜测),或者也许您只是没有正确计算它的位置。