• 3173阅读
  • 7回复

养生编程之眼见不为实(3) [复制链接]

上一主题 下一主题
离线yanhubin
 

图酷模式  只看楼主 倒序阅读 楼主  发表于: 2019-09-03
因为工作的关系这篇帖子拖了好久,废话不多说,此篇主要讲动画及粒子效果。
首先,我们看到,当用户列表这个代理Item被往左边拽的时候,右侧的按钮是有一个过冲弹簧动画的,为了实现这个动画,我们在右侧的删除按钮的Item中x属性是被这样绑定的   x: contactDelegate_item.x + parent.width     而不是通过anchors锚定在contactDelegate_item的右边线。这样,我们就可以通过设置一个目标为contactDelegateDel_item NumberAnimation 动画,这个动画曲线设置为我们想要的过冲弹簧效果 easing.type:Easing.OutElastic 并通过一些时间等参数设定,达到我们想要的效果。代码如下:
  1. NumberAnimation {
  2.                 id: contactDelegateDelBg_rect_inAnimation
  3.                 target: contactDelegateDel_item
  4.                 properties: "x"
  5.                 to: parent.width - contactDelegateDel_item.width
  6.                 duration: 1000; easing.type:Easing.OutElastic; easing.period: 0.5; onStarted: delImg_animation.start()
  7.             }
其实除了这个过冲弹簧效果,我们会看到上面现实的垃圾箱也会通过摇摆,来证明它的存在。
因此,我们在过冲动画开始的同时给这个垃圾箱嗑个药,让它摇摆起来。RotationAnimation就是这药丸的罪魁祸首,同样通过一下属性设置实现我们想要的效果。
  1. RotationAnimation { id: delImg_animation; target: del_img; properties: "rotation"; from: -50; to: 0; duration: 2000 ; easing.type:Easing.OutElastic; easing.period: 0.1}
有出现自然有退场, 退场动画我们也加上,兄弟情还是有的,也有回心转意不想让它灰飞烟灭的时候
  1. NumberAnimation {
  2.                 id: contactDelegateDelBg_rect_outAnimation
  3.                 target: contactDelegateDel_item
  4.                 properties: "x"
  5.                 to: parent.width
  6.                 duration: 200
  7.             }
到这里,基本的动画效果都实现了,接下来是本系列篇的重点灰飞烟面。
而这里才是本篇主题眼见不为实想要表达的。
第一篇里我介绍过老版本微信眼睛渐开的效果,很多人如果需要实现它,可能想到的是找UI要一个动画效果,但是我们发现,这个眼睛的展开程度是与拖动距离有关,如果使用动画我们就得将距离与动画帧绑定,这个很费力不讨好。
带过很多人,新手往往不太喜欢善用z轴,可能跟大家学习qt都是通过widget入门,在学习widget的时候又是通过.ui去实现自己人生的第一个界面效果,而通过这样的方式是不会去考虑z轴的,今天我要说的就是把界面提升到3维空间,用z轴去解决一些我们平时觉得很难实现的东西,这就是本篇的主题,眼见不为实。
首先,我们来分析下微信这个眼睛,我的实现方法是在listview的header中添加一个item,并且把我们看到的眼睛锚定到item的中心,之后我们在这个item的上面覆盖一层遮罩,遮罩是一个中心透明的圆,边上同背景色一样的颜色,实现方法可以是用图片,也可以用canvas ,通过拖拽距离与透明圆大小绑定,实现透明视窗变大,眼睛渐露,画张图给大家看下


那么现在,各位在看到飞灰烟面效果,想要去实现的时候是否想到了什么。我们观察到实现效果中,所有粒子颜色是不一样的,看上去就像是从背景中各个位置取了颜色,给我们的粒子系统中的粒子上色,且从不同的位置发射,页面还要从右边逐渐消失,这太南南南南南南了,跟本没有实现的思路。
简直跟昨天看男篮世界杯周琦进攻犯规,两个发球失误还想赢球一样难。

但如果我们换个思路,所谓的消失如果是我们通过z轴覆盖一层跟背景色一样的遮罩,是不是看上去就跟消失一样了,看上去是减,其实是加,我们这样做试试。我们加一个遮罩,躲在最右侧,等待指令大杀四方。
  1. Item {
  2.                 id: mask_item
  3.                 x: parent.width
  4.                 width: parent.width
  5.                 height: parent.height
  6.                 Behavior on x { NumberAnimation {duration: 1000} }
  7.                 Rectangle{
  8.                     id: maskgradient_rect
  9.                     height: parent.height
  10.                     width: height
  11.                     rotation: -90
  12.                     gradient: Gradient {
  13.                         GradientStop { position: 0.0; color: "#00F7F9FE" }
  14.                         GradientStop { position: 0.7; color: "#00F7F9FE" }
  15.                         GradientStop { position: 1.0; color: "#FFFFFFFF" }
  16.                     }
  17.                 }
  18.                 Rectangle{
  19.                     anchors{
  20.                         left: maskgradient_rect.right
  21.                         top: maskgradient_rect.top
  22.                         bottom: maskgradient_rect.bottom
  23.                     }
  24.                     width: contactDelegateBg_rect.width + 100
  25.                     color: "white"
  26.                 }
  27.             }
在点击删除后开始从右到左的动画,看上去就像页面从右到左消失一样。
好了,只剩下粒子效果了,那么我们又如何实现那个复杂粒子生成算法。
同样换条路走,我们给界面截个图,将图片粒子化,是不是就很简单了,看看是否可行。

组装加农炮
  1. ParticleSystem {
  2.                 id: particleSystem
  3.                 anchors.left: mask_item.left
  4.                 height: parent.height
  5.                 Emitter {
  6.                     id: emitter;
  7.                     anchors.verticalCenter: parent.verticalCenter;
  8.                     emitRate: 2000;
  9.                     lifeSpan: 1000;
  10.                     size: 3;     //粒子大小
  11.                     sizeVariation: 5;  //    粒子大小变化
  12.                     velocity: PointDirection{ x: -100; xVariation: 150; yVariation: 50}
  13.                     width: 100;
  14.                     height: mask_item.height
  15.                 }
  16.             }
  17.             CustomParticle {
  18.                 system: particleSystem
  19.                 property real maxWidth: parent.width
  20.                 property real maxHeight: parent.height
  21.                 ShaderEffectSource {
  22.                     id: pictureSource
  23.                     sourceItem: picture
  24.                     hideSource: true
  25.                 }
  26.                 Image {
  27.                     id: picture
  28.                 }
  29.                 ShaderEffectSource {
  30.                     id: particleSource
  31.                     sourceItem: particle
  32.                     hideSource: true
  33.                 }
  34.                 Rectangle{
  35.                     id: particle
  36.                     width: 5
  37.                     height: width
  38.                     color: "#ec534e"
  39.                     radius: width/2
  40.                 }
  41.                 vertexShader:"
  42.                     uniform highp float maxWidth;
  43.                     uniform highp float maxHeight;
  44.                     varying highp vec2 fTex2;
  45.                     varying lowp float fFade;
  46.                     uniform lowp float qt_Opacity;
  47.                     void main() {
  48.                         fTex2 = vec2(qt_ParticlePos.x, qt_ParticlePos.y);
  49.                         //Uncomment this next line for each particle to use full texture, instead of the solid color at the center of the particle.
  50.                         //fTex2 = fTex2 + ((- qt_ParticleData.z / 2. + qt_ParticleData.z) * qt_ParticleTex); //Adjusts size so it's like a chunk of image.
  51.                         fTex2 = fTex2 / vec2(maxWidth, maxHeight);
  52.                         highp float t = (qt_Timestamp - qt_ParticleData.x) / qt_ParticleData.y;
  53.                         fFade = min(t*4., (1.-t*t)*.75) * qt_Opacity;
  54.                         defaultMain();
  55.                     }
  56.                 "
  57.                 property variant particleTexture: particleSource
  58.                 property variant pictureTexture: pictureSource
  59.                 fragmentShader: "
  60.                     uniform sampler2D particleTexture;
  61.                     uniform sampler2D pictureTexture;
  62.                     varying highp vec2 qt_TexCoord0;
  63.                     varying highp vec2 fTex2;
  64.                     varying lowp float fFade;
  65.                     void main() {
  66.                         gl_FragColor = texture2D(pictureTexture, fTex2) * texture2D(particleTexture, qt_TexCoord0).w * fFade;
  67.                 }"
  68.             }
装上子弹,并发射
  1. MouseArea {
  2.                     anchors.fill: parent
  3.                     onClicked: {
  4.                         contactDelegateBg_rect.grabToImage(function(grabResult) {
  5.                             picture.source = grabResult.url;})
  6.                         emitter.enabled = true
  7.                         contactDelegateDelMask_item_inAnimation.start()
  8.                     }
  9.                 }

完美!!!
最后,当页面都被遮住,加农炮子弹射完后,我们把整个Item的身高压缩到0,最后真正的消灭它。
至此本篇核心内容到此为止,对于新手,很多效果的实现不要去看表面,我们可以把他们分解,并抽象到三维空间,无中生有,虚实结合!
最后把完整的Demo代码附上!代码使用5.13,可能大家没那么新,把import改一下即可。此Demo纯属养生代码,用于消遣,没有任何注释!
完整效果




海寒养生编程之灰飞烟面.zip (11 K) 下载次数:69

离线305750665

只看该作者 1楼 发表于: 2019-09-04
老哥牛逼
雨田哥: 群号:853086607
QQ: 3246214072

刘典武-feiyangqingyun:专业各种自定义控件编写+UI定制+输入法定制+视频监控+工业控制+仪器仪表+嵌入式linux+各种串口网络通信,童叟无欺,量大从优,欢迎咨询购买定制!QQ:517216493
离线liudianwu

只看该作者 2楼 发表于: 2019-09-04
拖得不算久,还可以!
欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线suzhuorui

只看该作者 3楼 发表于: 2019-09-05
老哥,这个zip格式损坏了
离线suzhuorui

只看该作者 4楼 发表于: 2019-09-05
为啥,用迅雷下载的就不可用,用浏览器下载的就可以
离线modongzhen

只看该作者 5楼 发表于: 2019-10-09
大佬你好,我想问一下为什么我编译运行之后,没有显示用户头像的呢

有这个提示。QNetworkReplyHttpImplPrivate::_q_startOperation was called more than once QUrl("http://img5.duitang.com/uploads/item/201411/29/20141129010249_dh32E.thumb.700_0.jpeg")
离线xdh873939316

只看该作者 6楼 发表于: 2019-10-10
  
离线coolee

只看该作者 7楼 发表于: 2019-11-06
感谢分享,向楼主学习,编程也是一种态度!
快速回复
限100 字节
 
上一个 下一个