我已经编写了一些 Javascript 代码并使用 HTML5 Canvas 和 Qt 的 QML 2D Canvas 对其进行了测试。令我惊讶的是,它们的行为完全不同,我不明白为什么。 HTML5 代码使矩形以螺旋状运动旋转,而 QML 代码使其在 x 方向旋转和移动。
HTML5/Javascipt 代码:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="1000" height="500" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var xOffset = 50
var yOffset = 50
var xLength = 100
var yLength = 100
var xCenter = xOffset + xLength / 2
var yCenter = yOffset + yLength / 2
var angle = 0
function rotateSquare(xCenter, xCenter, width, height, angleIncrement)
{
ctx.save()
ctx.translate(xCenter, yCenter)
ctx.rotate(angle * Math.PI / 180)
ctx.translate(-xCenter, -yCenter)
ctx.clearRect(xOffset, yOffset, width, height)
var newAngle
newAngle = angle + angleIncrement
newAngle %= 360
var increment = deltaAngle(newAngle, angle)
ctx.translate(xCenter, yCenter)
ctx.rotate(increment * Math.PI / 180)
ctx.translate(-xCenter, -yCenter)
ctx.fillRect(xOffset++, yOffset, width, height)
angle = newAngle
ctx.restore()
}
function deltaAngle(current, previous)
{
if (current >= previous)
{
return current - previous
}
else
{
return (360 + current) - previous
}
}
setInterval( "rotateSquare(xCenter, yCenter, xLength, yLength, 1)", 20 );
</script>
</body>
</html>
QML代码:
import QtQuick 2.5
import QtQuick.Window 2.2
Window {
id: root
visible: true
minimumHeight: 600
minimumWidth: 800
property int xOffset: 50
property int yOffset: 50
property int xLength: 100
property int yLength: 100
property var ctx
property int xCenter: xOffset + xLength / 2
property int yCenter: yOffset + yLength / 2
property int angle: 0 //Degrees
Timer {
interval: 20;
repeat: true;
running: true;
onTriggered: {
graphCanvas.requestPaint()
}
}
Canvas {
id: graphCanvas
anchors.fill: parent
renderTarget: Canvas.Image
renderStrategy: Canvas.Cooperative
onPaint: {
ctx.fillStyle = "steelblue"
rotateSquare(xCenter, yCenter, xLength, yLength, 1)
}
function rotateSquare(xCenter, yCenter, width, height, angleIncrement)
{
ctx.save()
ctx.translate(xCenter, yCenter)
ctx.rotate(angle * Math.PI / 180)
ctx.translate(-xCenter, -yCenter)
ctx.clearRect(xOffset, yOffset, width, height)
var newAngle
newAngle = angle + angleIncrement
newAngle %= 360
var increment = deltaAngle(newAngle, angle)
ctx.translate(xCenter, yCenter)
ctx.rotate(increment * Math.PI / 180)
ctx.translate(-xCenter, -yCenter)
ctx.fillRect(xOffset++, yOffset, width, height)
angle = newAngle
ctx.restore()
}
function deltaAngle(current, previous)
{
if (current >= previous)
{
return current - previous
}
else
{
return (360 + current) - previous
}
}
Component.onCompleted: ctx = getContext("2d")
}
}
最佳答案
要获得与 HTML 中相同的效果,请将您的组件初始化修改为:
Component.onCompleted: {
ctx = getContext("2d")
xCenter = xOffset + xLength / 2
yCenter = yOffset + yLength / 2
}
在 QML 中,当你说:
property int xCenter: xOffset + xLength / 2
您创建了一个属性绑定(bind) - 每当 xOffset 或 xLength 发生变化时,xCenter 也会发生变化,并且您确实在渲染代码中修改了 xOffset,因此它产生的效果不同于您的 JavaScript - 其中 xCenter 计算一次并且永远不会改变。
我提供的代码以编程方式为 xCenter
属性分配了一个值,这清除了它可能具有的任何绑定(bind),因此它不再更改。
关于javascript - Qt 2D Canvas 和 HTML5 canvas 的行为并不相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33456203/