javascript - QML Canvas : different behaviour in rendering

标签 javascript html 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;
}

Here你可以运行上面的代码。 输出是这样的:

enter image description here

接下来,我将相同的代码移动到 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;
            }


        }
    }
}

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

enter image description here

如您所见,底部有一个缺陷。

我真的不明白为什么会有那个不完美;而且我不明白为什么相同的代码会给出不同的输出。

感谢任何帮助! 谢谢

最佳答案

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

The arc() method is equivalent to the ellipse() method in the case where the two radii are equal. [...]

When the ellipse() method is invoked, it must proceed as follows. First, if the object's path has any subpaths, then the method must add a straight line from the last point in the subpath to the start point of the arc.

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

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

关于javascript - QML Canvas : different behaviour in rendering,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35628733/

相关文章:

javascript - Blazor JS 互操作 : how to pass undefined to a JavaScript function

html - 在 HTML5 Canvas 中绘制 X 数量的圆圈的最快方法是什么?

html - 特定 ID 的 CSS 媒体查询

javascript - 如何在html中获取数组中的两个条目?

c++ - Qt在ComboBox1的基础上改变ComboBox2

c++ - Qt 构建发布和调试库

c++ - 隐藏 QPushButton 和 QLineEdit 边框

javascript - Chrome Dev Tools 控制台 - 以编程方式选择框架

javascript - jquery,点击div内的任何地方,除了某些 child

javascript - jQuery .each 函数帮助