# 简单变化

变化操作对象的几何形状。一般来说,QML 项目可以被转换,旋转和放大缩小。这些操作有简单方式和高级方式两种。

让我们从简单的变化开始。这将作为我们的学习的起点。

简单的变化通过修改 x,y 坐标来实现。旋转通过 rotation 属性完成。该值的格式的角度(0.. 360)。缩小和放大通过 scale 属性完成,其值 <1 意味着缩小,>1 意味着放大。旋转和缩放不会修改元素的坐标和大小:x,ywidth/height 不会改变,仅修改了绘图指令。

展示例子前,先看看这个:ClickableImage 元素。ClickableImage 是一个包含鼠标点击区域的图片。一个有用的经验法则 —— 如果一段代码重复出现三次,就将其封装为组件。

// ClickableImage.qml
// 可被点击的简单图片

import QtQuick

Image {
    id: root
    signal clicked

    MouseArea {
        anchors.fill: parent
        onClicked: root.clicked()
    }
}

我们用可点击图片展示3个对象,方形,圆形和三角形。每个对象被点击时都会进行简单变化。点击背景将会重置场景。

// TransformationExample.qml

import QtQuick

Item {
    // 宽高设置与所给背景图相同
    width: bg.width
    height: bg.height

    Image { // 不错的背景图
        id: bg
        source: "assets/background.png"
    }

    MouseArea {
        id: backgroundClicker
        // 需要放在图片之前,因为错误的顺序会导致该鼠标区域在其它元素之前,消费了点击事件
        anchors.fill: parent
        onClicked: {
            // 重置小场景
            circle.x = 84
            box.rotation = 0
            triangle.rotation = 0
            triangle.scale = 1.0
        }
    }

    ClickableImage {
        id: circle
        x: 84; y: 68
        source: "assets/circle_blue.png"
        antialiasing: true
        onClicked: {
            // 点击时增加 x 坐标
            x += 20
        }
    }

    ClickableImage {
        id: box
        x: 164; y: 68
        source: "assets/box_green.png"
        antialiasing: true
        onClicked: {
            // 点击时增加旋转角度
            rotation += 15
        }
    }

    ClickableImage {
        id: triangle
        x: 248; y: 68
        source: "assets/triangle_red.png"
        antialiasing: true
        onClicked: {
            // 多个变化
            rotation += 15
            scale += 0.05
        }
    }
    
    // ...

每次点击原型会增加其 x 坐标,而每次点击放行会使其旋转。每次点击三角形会触发组合变化,旋转和放大。对于放大和旋转操作,我们设置了 antialiasing: true,起用了因为性能原因而关闭的抗锯齿功能(与裁剪属性 clip 相同)。当你在工作中看到图形里有些栅格化的边缘时,打开平滑开关可能是个不错的主意。

提示

为了在缩放图片时达到更佳的显示效果,建议仅做缩小操作,不要做放大操作。使用一个较大的放大系数放大图片会导致图片模糊不清。当缩放图片时,你需要考虑使用 smooth: true 牺牲性能,启用更高质量的过滤器。

背景的 MouseArea 覆盖了整个背景图并重置了对象状态。

提示

代码中先出现的元素在堆栈中的排序(称为 z 排序)更低。如果你多次点击 circle,你会看到它出现在了 box 之下。z 排序也可通过元素的 z 属性修改。

这是因为在代码中,box 在后面。鼠标区域也遵循相同的规则。代码中靠后的鼠标区域会与靠前的重叠,并捕捉鼠标事件。

请牢记:元素的顺序与其在文档中的顺序息息相关