QML Canvas:渲染中的不同行为
Posted
技术标签:
【中文标题】QML Canvas:渲染中的不同行为【英文标题】:QML Canvas: different behaviour in rendering 【发布时间】:2016-02-25 13:31:39 【问题描述】:我正在尝试使用 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你可以运行上面的代码。 输出是这样的:
接下来,我将相同的代码移动到 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;
在这种情况下,我得到以下输出:
如您所见,底部有一个缺陷。
我真的不明白为什么会有这种缺陷;而且我不明白为什么相同的代码给出不同的输出。
感谢任何帮助! 谢谢
【问题讨论】:
【参考方案1】:lineTo
p3
是不需要的,因为在绘制arc
线段时,会根据Canvas
规范自动绘制连接线:
arc()方法等价于ellipse()方法 其中两个半径相等。 [...]
当调用 ellipse() 方法时,它必须进行如下操作。 首先,如果对象的路径有任何子路径,那么方法必须添加 从子路径中的最后一点到起点的直线 弧线。
另外,moveTo
p1
也不需要,因为它会作为第一个弧的一部分完成。
至于为什么额外的线被画得比第二个弧的开始更远,这可能是 Qt 中的一个错误(可能是 0
的除法问题 - 只是在这里猜测),或者也许你根本没有计算它的位置正确。
【讨论】:
可以验证这是否修复了它。好的。 :) 哇,我确认这是一个解决方案!谢谢!以上是关于QML Canvas:渲染中的不同行为的主要内容,如果未能解决你的问题,请参考以下文章