zoukankan      html  css  js  c++  java
  • QML设计飘散效果

    1,目标及展示

    首先希望实现文字、图片、控件等在触发后,呈现飘散并消失的效果。在QT例程《Qt Quick Particles Examples》是一个海星点击鼠标后呈现打散的效果,这个效果和最终需要的略有不同,所以我们在它的基础上再加上我需要的一些元素,最终实现如下效果。

    图1(gif)


    图6

    2,设计分析

    这个项目我们分析可以拆分成两个部分,第一是背景飘散效果,第二是背景逐渐消失效果,然后将这两种效果进行组合,就实现最终需要的效果。
    首先先实现飘散效果,QT具有非常强大的粒子化效果,并且只需很少的几行代码就能实现效果。不过对于初次使用qml语言进行开发的设计人员,需要先了解关键字的含义和功能,当然我们可以在例程中微调每个关键字参数,根据效果变化进行快速了解作用,也可以直接通过强大的F1帮助键对关键字说明文档进行全面的了解。
    在我们这些关键字有一定认识后,就可以快速进行粒子化设计了。
    第二就是逐步消失的效果,这里的方法就有很多了:方法一可以使用PS技术,找个单侧是过渡效果的蒙版图片,利用动画效果逐步遮住显示内容;
    方法二可以直接使用qml 中的 LinearGradient:线性过渡的方法来实现,从单侧开始让逐步隐藏,使10%的区域从透明度为0(全透明)过渡到1(不透明)状态,然后让这10%的区域逐渐扩大范围,最终实现背景消失。如果希望过渡区间更加均匀可以把10%改成20%或更大。
    还有很多方法可以实现这个效果,从适应性考虑采用的是后者。

    3,设计内容

    先说下我的开发环境:
    qt5.4.2集成的Qt creator 3.4.1版本
    首先创建Quick项目,如果自动创建了MainForm.ui.qml,直接删除就可以了,我们直接在main.qml中开发就可以了。
    我们在建粒子系统之前,先建立一个画布,画布大小填充父画布。然后在这个画布上添加粒子系统的基本元素:ParticleSystem、Emitter、ImageParticle和应用文件import QtQuick.Particles 2.0代码如下:

    import QtQuick 2.4
    import QtQuick.Window 2.2
    import QtQuick.Particles 2.0
    
    Window {
         800
        height: 320
        visible: true
    
        Rectangle {
            id: root
            anchors.fill: parent
            color: "#1f1f1f"
    
            ParticleSystem {
                id: myParticleSystem
            }
    
            Emitter {
                id: myEmitter
                system: myParticleSystem
    
                //发射器区域宽和高
                 240
                height: parent.height
    
                //发射频率每秒500个元素
                emitRate: 500
                //每个元素的生命周期是1000毫秒
                lifeSpan: 1000
                //每个元素的大小是16*16像素
                size: 16
            }
    
            ImageParticle {
                system: myParticleSystem
                //Qt自带粒子图,可以换成自定义图片
                source: "qrc:///particleresources/fuzzydot.png"
                //粒子图使用白色
                color: "white"
            }
    
        }
    }

    图2(gif)

    这个图看来只有粒子,我们还需要动态飘动的效果,下面在粒子发射器中增加如下代码。

    velocity: PointDirection {
    	x: 150
    }
    acceleration: PointDirection {
    	x: 12
    }

    水平向右设置150像素/秒的速度,水平向右添加一个12像素/秒^2的加速。如果我们需要让他向左发射时,可以让x:-150,加速设置也是同理,添加一个符号就表示向左加速。如果我们需要向下发射可以y:150,同理向上发射时是y:-150。
    这时我们就有了所有粒子向右飘动的界面,但是飘动状态还比较单调。我们可以给他增加一些差异性的元素,让元素更丰富。
    让元素在±8*8像素范围内随机变化

    sizeVariation: 8

    在velocity中增加x/y速度的随机变化

    xVariation: 60
    yVariation: 20

    在acceleration中增加x/y加速度的随机变化

    xVariation: 6
    yVariation: 5

    到此元素飘动就有了雪花飞舞的感觉了,飘动的层次均匀并且舒服。

    现在感觉颜色稍微有点单调,我们可以在ImageParticle中对颜色增加随机系数

    colorVariation: 0.1

    颜色也有一定的波动了,如下图显示

    图3

    现在我们的任务就是让发射器一边发射一边向右移动,直到移动到界面外,实现飘散的元素飞舞过程。这里我们可以使用动画元素,让发射器在1秒内从窗体的最左边向右侧窗口外移动,实现的代码如下

    NumberAnimation {
    	id: myAnimation
    	//设定动画的目标
    	target: myEmitter
    	//设定改变的属性是x坐标
    	properties: "x"
    	//x移动到父窗口的边沿
    	to: root.width
    	//在1秒内完成移动
    	duration: 1000
    }

    有了动画代码,我们还需要一个触发这个动画的事件,另外粒子系统创建后先不要发送,我们演示时通过鼠标来激活动画和粒子系统。
    在粒子系统ParticleSystem添加如下代码,让粒子系统在创建时停止运行。
    running: false
    然后提那家数据触发代码

    MouseArea {
    	anchors.fill: parent
    
    	//鼠标点击测试
    	onClicked: {
    		//让myEmitter窗口复位,这样鼠标可重复点击
    		if (myEmitter.x > 0)
    		{
    			myAnimation.stop()
    			myEmitter.x = 0;
    		}
    			
    		//激活粒子系统
    		myParticleSystem.restart()
    		//激活动画
    		myAnimation.restart()
    	}
    }

    由于每次动画执行结束后,myEmitter窗口已经在显示窗体以外了,那么在点击时先让myEmitter窗口回到初始位置,我们就实现了点击后重复演示功能。
    效果如下

    图4

    到这里我们第一项飘散的效果就完成了,下一步是实现背景元素逐渐消失的特效。
    我们后续会用到LinearGradient元素,需要添加引用import QtGraphicalEffects 1.0。我们首先测试文字,添加如下内容。注意添加的位置,qml添加图层的规则是先建立的(代码行号偏小的)图层在底层,后建立的(代码行号偏大的)图层在顶层,我们文字需要显示在飘飞效果的下面显示,所以代码尽量靠前放置。

    Text {
    	id:myText
    	anchors.centerIn: parent
    	text: "Hello world!"
    	font.bold: true
    	font.pixelSize: 120
    	font.family: "微软雅黑"
    	visible: false
    }
    
    LinearGradient {
    	source: myText
    	anchors.fill: myText
    	start: Qt.point(0, 0)
    	end: Qt.point(myText.width, 0)
    	gradient: Gradient {
    		GradientStop{id: myGradientStart; position: 0.0; color: "#FFFFFFFF"}
    		GradientStop{id: myGradientEnd; position: 0.1; color: "#FFFFFFFF"}
    	}
    }

    代码中Text项目被设置为隐藏。是因为我们下面的渐变效果已经基于Text进行渐变覆盖,我们需要显示的是渐变的内容,Text的内容就不再被需要了,且当渐变被设置为透明时,会显示背景的内容,这时Text如果显示出了就不是我们所希望的效果了。
    现在文本内容有了,下一步如何让其逐步消失,我们可以用动画控制渐变的定位。
    图5
    如上图所示,首先让定位点myGradientStart在200毫秒内变成无色,然后让定位点myGradientEnd移动到终点,这个过程同时让myGradientStart跟随移动到终点,但是他们之间需要有个时间差,消失边界才会有个过渡区间。这里我们可以使用顺序动画、并行动画来组合完成这个功能。

    最终代码如下

    import QtQuick 2.4
    import QtQuick.Window 2.2
    import QtQuick.Particles 2.0
    import QtGraphicalEffects 1.0
    
    
    Window {
         800
        height: 320
        visible: true
    
        Rectangle {
            id: root
            anchors.fill: parent
            color: "#1f1f1f"
    
            Text {
                id:myText
                anchors.centerIn: parent
                text: "Hello world!"
                font.bold: true
                font.pixelSize: 120
                font.family: "微软雅黑"
                visible: false
            }
    
            LinearGradient {
                source: myText
                anchors.fill: myText
                start: Qt.point(0, 0)
                end: Qt.point(myText.width, 0)
                gradient: Gradient {
                    GradientStop{id: myGradientStart; position: 0.0; color: "#FFFFFFFF"}
                    GradientStop{id: myGradientEnd; position: 0.1; color: "#FFFFFFFF"}
                }
            }
    
            ParticleSystem {
                id: myParticleSystem
                running: false
            }
    
            Emitter {
                id: myEmitter
                system: myParticleSystem
                anchors.verticalCenter: parent.verticalCenter
    
                //发射器区域宽和高
                 240
                height: 180
    
                //发射频率每秒500个元素
                emitRate: 500
                //每个元素的生命周期是1000毫秒
                lifeSpan: 1000
                //每个元素的大小是16*16像素
                size: 16
                //元素可以在±8*8像素范围内随机变化
                sizeVariation: 8
                //元素发射速度设置,使用点方向模式
                velocity: PointDirection {
                    //水平方式速度 150像素/秒
                    x: 150
                    //随着变量调整
                    xVariation: 60
                    yVariation: 20
                }
                //元素行进加速度设置,使用点方式模式
                acceleration: PointDirection {
                    x: 12
                    //随着变量调整
                    xVariation: 6
                    yVariation: 5
                }
            }
    
            ImageParticle {
                system: myParticleSystem
                //Qt自带粒子图,可以换成自定义图片
                source: "qrc:///particleresources/fuzzydot.png"
                //粒子图使用白色
                color: "white"
                //颜色随机系数
                colorVariation: 0.1
            }
    
            ParallelAnimation {
                id: myAnimation
    
                //数值动画
                NumberAnimation {
                    //设定动画的目标
                    target: myEmitter
                    //设定改变的属性是x坐标
                    properties: "x"
                    //x移动到父窗口的边沿
                    to: root.width
                    //在1秒内完成移动
                    duration: 1000
                }
    
                SequentialAnimation {
                    PropertyAnimation {
                        target: myGradientStart
                        properties: "color"
                        to: "#00FFFFFF"
                        duration: 200
                    }
    
                    ParallelAnimation {
                        PropertyAnimation {
                            target: myGradientEnd
                            properties: "position"
                            to: "1.0"
                            duration: 1000
                        }
    
                        PropertyAnimation {
                            target: myGradientStart
                            properties: "position"
                            to: "0.9"
                            duration: 1000
                        }
                    }
    
                    PropertyAnimation {
                        target: myGradientEnd
                        properties: "color"
                        to: "#00FFFFFF"
                        duration: 200
                    }
                }
            }
    
            MouseArea {
                anchors.fill: parent
    
                //鼠标点击测试
                onClicked: {
                    //让myEmitter窗口复位,这样鼠标可重复点击
                    if (myEmitter.x > 0)
                    {
                        myAnimation.stop()
                        myEmitter.x = 0;
    
                        myGradientStart.position = 0.0
                        myGradientStart.color = "#FFFFFFFF"
    
                        myGradientEnd.position = 0.1
                        myGradientEnd.color = "#FFFFFFFF"
                    }
    
                    //激活粒子系统
                    myParticleSystem.restart()
                    //激活动画
                    myAnimation.restart()
                }
            }
        }
    }

    在以上代码中简单修改,就可以实现图6的效果了。

    4,总结

    此例程主要使用的功能块粒子系统,给粒子增加一些随机设置参数,可以让粒子系统显示更自然。另外在粒子系统中还有很有趣的功能如精灵显示、粒子影响器等等。另外一个主要的功能就是渐变功能,可以让颜色A过渡到颜色B,及本例程中使用的从无色A过渡到有色B。

     https://www.simbahiker.com/news/0220200428001.html

  • 相关阅读:
    详解ASP.NET页面的asp“.NET研究”x扩展 狼人:
    Microsoft NLa“.NET研究”yerApp案例理论与实践 多层架构与应用系统设计原则 狼人:
    HTML5 搭建“.NET研究”移动Web应用 狼人:
    VS201“.NET研究”0 C++下编译调试MongoDB源码 狼人:
    Silverlight 的多线程能力(下“.NET技术”) 狼人:
    Log4Net 全方“.NET技术”位跟踪程序运行 狼人:
    三种属性操作性能比较:PropertyInfo + Expression Tree + Delega“.NET技术”te.CreateDelegate 狼人:
    .NET简谈观察者“.NET技术”模式 狼人:
    Microsoft NLayerApp案例理论与实践 项目简“.NET研究”介与环境搭建 狼人:
    “.NET研究”专访微软MVP衣明志:走进ASP.NET MVC 2框架开发 狼人:
  • 原文地址:https://www.cnblogs.com/hiker-blogs/p/12860533.html
Copyright © 2011-2022 走看看