qt动画效果_Qml特效1-进场动画-飞入

目录

(放个目录方便预览。知乎不支持目录,这个目录是从博客复制过来的,点击会跳转到博客)

  • 简介
  • 关于文章
  • 飞入效果预览
  • 实现原理
  • QtQuick动画系统
    • 动画组件
    • 动画的使用
      • 用例一 直接声明动画
      • 用例二 on语法
      • 用例三 Transitions或状态机
  • ShaderEffect
  • 飞入效果源码

简介

这是《Qml特效-进场动画》系列文章的第一篇,涛哥将会教大家一些Qml进场动画相关的知识。

关于文章

《Qml组件化编程》系列文章,已经发布了10篇,暂时没有更多内容了,后续可能会更新,看情况。

涛哥开始了新的系列文章《Qml特效》,计划是三部曲《Qml特效-进场动画》

《Qml特效-页面切换动画》《Qml特效-3D特效》,欢迎大家关注。

进场动画效果 参考了WPS版ppt的动画,基本效果已经全部实现,可以到github TaoQuick项目中预览:

jaredtao/TaoQuick​github.com
6b19ff9f937b1acd6c7285d568a78c97.png

文章主要发布在涛哥的博客 和 涛哥的知乎专栏-Qt进阶之路

进入效果预览

第一篇文章,就放一个简单的进入动画

6d84f5b5d387a515a6a4b1a6f547e5c5.gif

实现原理

进场动画,使用了QtQuick的动画系统,以及ShaderEffect特效。

Qml中有一个模块QtGraphicalEffects,提供了部分特效,就是使用ShaderEffect实现的。

使用ShaderEffect实现特效,需要有一些OpenGL/DirectX知识,了解GPU渲染管线,同时也需要一些数学知识。

QtQuick动画系统

动画组件

Qt动画系统,在帮助文档有详细的介绍,搜索关键词”Animation”,涛哥在这里说一些重点。

涛哥用思维导图列出了Qml中所有的动画组件:

26fc88a463395f694d5b75757cbca8d1.png
  • 右边带虚线框的部分比较常用,是做动画必须要掌握的,尤其是属性动画PropertyAnimation和数值动画NumberAinmation。
    常见的各种坐标动画、宽高动画、透明度动画、颜色动画等等,都可以用这些组件来实现。
  • 底下的States、Behavior 和 Traisitions,也是比较常用的和动画相关的组件。可在帮助文档搜索
    关键词”Qt Quick States”、”Behavior”、”Animation and Transitions”。后续的文章,涛哥会专门讲解。
  • 左边的Animator系列,属于Scene Graph渲染层面的优化,其属性Change信号只在最终值时发出,不发出中间值,使用的时候需要注意。
  • 顶上的AnimationController,属于高端玩家,用来控制整个动画的进度。

动画的使用

用例一 直接声明动画

直接声明动画,指定target和property,之后可以在槽函数/js脚本中通过id控制动画的运行。

也可以通过设定loops 和 running属性来控制动画

Rectangle {
    id: flashingblob
    width: 75; height: 75
    color: "blue"
    opacity: 1.0

    MouseArea {
        anchors.fill: parent
        onClicked: {
            animateColor.start()
            animateOpacity.start()
        }
    }

    PropertyAnimation {id: animateColor; target: flashingblob; properties: "color"; to: "green"; duration: 100}

    NumberAnimation {
        id: animateOpacity
        target: flashingblob
        properties: "opacity"
        from: 0.99
        to: 1.0
        loops: Animation.Infinite
        easing {type: Easing.OutBack; overshoot: 500}
   }
}

用例二 on语法

on语法可以使用动画组件,也可以用Behavior,直接on某个特定的属性即可。效果一样。

on动画中,如果直接指定了running属性,默认就会执行这个动画。

也可以不指定running属性,其它地方修改这个属性时,会自动按照动画来执行。

示例代码: on动画

Rectangle {
    width: 100; height: 100; color: "green"
    RotationAnimation on rotation {
        loops: Animation.Infinite
        from: 0
        to: 360
        running: true
    }
}

示例代码 Behavior 动画

import QtQuick 2.0

Rectangle {
    id: rect
    width: 100; height: 100
    color: "red"

    Behavior on width {
        NumberAnimation { duration: 1000 }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: rect.width = 50
    }
}

用例三 Transitions或状态机

过度动画和状态机动画,本质还是直接使用动画组件。只不过是把动画声明并存储起来,以在状态切换时使用。

这里先不细说了,后面会有系列文章<Qml特效-页面切换动画>,会专门讲解。

ShaderEffect

动画只能控制组件的属性整体的变化,做特效需要精确到像素。

Qml中提供了ShaderEffect这个组件,就能实现像素级别的操作。

大名鼎鼎的ShaderToy网站,就是使用Shader实现各种像素级别的酷炫特效。

ShaderToy

作者iq大神

ShaderToy上面的特效都是可以移植到Qml中的。

使用Shader开发,需要一定的图形学知识。其中使用GLSL需要熟悉OpenGL, 使用HLSL需要熟悉DirectX。

进入效果源码

封装了一个平移进入的动画组件,能够支持从四个方向进场。

//ASlowEnter.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import "../.."
Item {
    id: r
    property int targetX: 0
    property int targetY: 0
    property alias animation: animation
    enum Direct {
        FromLeft = 0,
        FromRight = 1,
        FromTop = 2,
        FromBottom = 3
    }
    property int dir: ASlowEnter.Direct.FromBottom
    property int duration: 2000
    //额外的距离,组件在父Item之外时,额外移动一点,避免边缘暴露在父Item的边缘
    property int extDistance: 10
    property var __propList: ["x", "x", "y", "y"]
    property var __fromList: [
        -r.parent.width - r.width - extDistance,
        r.parent.width + r.width + extDistance,
        -r.parent.height - r.height - extDistance,
        r.parent.height + r.height + extDistance]
    property var __toList: [targetX, targetX, targetY, targetY]
    NumberAnimation {
        id: animation
        target: r
        property: __propList[dir]
        from: __fromList[dir]
        to: __toList[dir]
        duration: r.duration
        loops: 1
        alwaysRunToEnd: true
    }
}

进场组件的使用

//Enter.qml

import QtQuick 2.12
import QtQuick.Controls 2.12
import "../Animation/Enter"
Item {
    anchors.fill: parent
    ASlowEnter {
        id: a1
        width: 160
        height: 108
        x: (parent.width - width) / 2
        targetY: parent.height / 2
        dir: ASlowEnter.Direct.FromBottom
        Image {
            anchors.fill: parent
            source: "qrc:/EffectImage/Img/baby.jpg"
        }
    }
    ASlowEnter {
        id: a2
        width: 160
        height: 108
        x: (parent.width - width) / 2
        targetY: parent.height / 2 - height
        dir: ASlowEnter.Direct.FromTop
        Image {
            anchors.fill: parent
            source: "qrc:/EffectImage/Img/baby.jpg"
        }
    }
    ASlowEnter {
        id: a3
        width: 160
        height: 108
        targetX: parent.width / 2 - width * 1.5
        y: (parent.height - height) / 2
        dir: ASlowEnter.Direct.FromLeft
        Image {
            anchors.fill: parent
            source: "qrc:/EffectImage/Img/baby.jpg"
        }
    }
    ASlowEnter {
        id: a4
        width: 160
        height: 108
        targetX: parent.width / 2 + width / 2
        y: (parent.height - height) / 2
        dir: ASlowEnter.Direct.FromRight
        Image {
            anchors.fill: parent
            source: "qrc:/EffectImage/Img/baby.jpg"
        }
    }
    ParallelAnimation {
        id: ani
        ScriptAction{ script: {a1.animation.restart()} }
        ScriptAction{ script: {a2.animation.restart()} }
        ScriptAction{ script: {a3.animation.restart()} }
        ScriptAction{ script: {a4.animation.restart()} }
    }
    Component.onCompleted: {
        ani.restart()
    }
    Button {
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        text: "replay"
        onClicked: {
            ani.restart()
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QML中可以通过使用动画来实现各种特效,包括进场动画。其中,百叶窗特效是一种常见的进场动画,可以让界面元素以一定的节奏和方式出现。下面是一个简单的实现示例: ```qml import QtQuick 2.0 Rectangle { width: 300 height: 300 color: "white" Repeater { model: 5 Image { id: image source: "image.png" width: parent.width / 5 height: parent.height x: index * width clip: true transform: Scale { id: scale origin.x: width / 2 origin.y: height / 2 xScale: 1 yScale: 0 } Behavior on transform { PropertyAnimation { duration: 500 easing.type: Easing.InOutQuad } } } } Component.onCompleted: { for (var i = 0; i < repeater.count; i++) { var image = repeater.itemAt(i); image.scale.y = 1; } } } ``` 在这个示例中,我们使用了一个Repeater来创建了5个相同的Image元素,每个元素的宽度都是父元素宽度的1/5。我们将这些元素放置在一起,然后通过使用clip属性来将它们裁剪成相同大小。接着,我们为每个元素添加了一个缩放变换,初始时y轴的比例为0,这样它们就会“收缩”起来。最后,在组件完成时,我们将每个元素的缩放比例y设置为1,这样它们就会“展开”出现。 在这个示例中,我们使用了PropertyAnimation来控制变换的动画效果。该动画持续500ms,并且使用了Easing.InOutQuad缓动函数,使它看起来更加平滑。你可以根据需要对这些参数进行调整,以达到更好的效果。 总体来说,百叶窗特效是一种简单而又实用的进场动画,可以轻松地让你的应用程序变得更加生动有趣。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值