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

  • 相关阅读:
    volley框架使用
    Insert Interval
    candy(贪心)
    Best Time to Buy and Sell Stock
    Best Time to Buy and Sell Stock III
    distinct subsequences
    edit distance(编辑距离,两个字符串之间相似性的问题)
    trapping rain water
    word break II(单词切分)
    sudoku solver(数独)
  • 原文地址:https://www.cnblogs.com/hiker-blogs/p/12860533.html
Copyright © 2011-2022 走看看