Warning, /network/neochat/src/qml/FancyEffectsContainer.qml is written in an unsupported language. File is not indexed.
0001 // SPDX-FileCopyrightText: 2021 Alexey Andreyev <aa13q@ya.ru> 0002 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0003 0004 import QtQuick 0005 import QtQuick.Layouts 0006 import QtQuick.Particles 0007 0008 import org.kde.kirigami as Kirigami 0009 0010 Item { 0011 id: root 0012 property bool enabled: false 0013 property int effectInterval: Kirigami.Units.veryLongDuration*10; 0014 property color darkSnowColor: "grey" 0015 property bool isThemeDark: Kirigami.Theme.backgroundColor.hslLightness <= darkSnowColor.hslLightness 0016 0017 function showConfettiEffect() { 0018 confettiTimer.start() 0019 } 0020 0021 function showSnowEffect() { 0022 snowTimer.start() 0023 } 0024 0025 function showFireworksEffect() { 0026 fireworksTimer.start() 0027 } 0028 0029 // Confetti 0030 0031 Timer { 0032 id: confettiTimer 0033 interval: root.effectInterval; 0034 running: false; 0035 repeat: false; 0036 triggeredOnStart: true; 0037 onTriggered: { 0038 if (root.enabled) { 0039 confettiSystem.running = !confettiSystem.running 0040 } 0041 } 0042 } 0043 0044 ParticleSystem { 0045 id: confettiSystem 0046 anchors.fill: parent 0047 0048 running: false 0049 onRunningChanged: { 0050 if (running) { 0051 opacity = 1 0052 } else { 0053 opacity = 0 0054 } 0055 } 0056 0057 Behavior on opacity { 0058 SequentialAnimation { 0059 NumberAnimation { duration: Kirigami.Units.longDuration } 0060 } 0061 } 0062 0063 ImageParticle { 0064 source: "qrc:/org/kde/neochat/qml/confetti.png" 0065 entryEffect: ImageParticle.Scale 0066 rotationVariation: 360 0067 rotationVelocity: 90 0068 color: Qt.hsla(Math.random(), 0.5, 0.6, 1) 0069 colorVariation: 1 0070 } 0071 0072 Emitter { 0073 anchors { 0074 left: parent.left 0075 right: parent.right 0076 top: parent.top 0077 } 0078 0079 sizeVariation: Kirigami.Units.iconSizes.small/2 0080 lifeSpan: Kirigami.Units.veryLongDuration*10 0081 size: Kirigami.Units.iconSizes.small 0082 0083 velocity: AngleDirection { 0084 angle: 90 0085 angleVariation: 42 0086 magnitude: 500 0087 } 0088 } 0089 } 0090 0091 // Snow 0092 0093 Timer { 0094 id: snowTimer 0095 interval: root.effectInterval; 0096 running: false; 0097 repeat: false; 0098 triggeredOnStart: true; 0099 onTriggered: { 0100 if (root.enabled) { 0101 snowSystem.running = !snowSystem.running 0102 } 0103 } 0104 } 0105 0106 ParticleSystem { 0107 id: snowSystem 0108 anchors.fill: parent 0109 0110 running: false 0111 onRunningChanged: { 0112 if (running) { 0113 opacity = 1 0114 } else { 0115 opacity = 0 0116 } 0117 } 0118 0119 Behavior on opacity { 0120 SequentialAnimation { 0121 NumberAnimation { duration: Kirigami.Units.longDuration } 0122 } 0123 } 0124 0125 ItemParticle { 0126 delegate: Rectangle { 0127 width: 10 0128 height: width 0129 radius: width 0130 color: root.isThemeDark ? "white" : darkSnowColor 0131 scale: Math.random() 0132 opacity: Math.random() 0133 } 0134 } 0135 0136 Emitter { 0137 anchors { 0138 left: parent.left 0139 right: parent.right 0140 top: parent.top 0141 } 0142 0143 sizeVariation: Kirigami.Units.iconSizes.medium 0144 lifeSpan: Kirigami.Units.veryLongDuration*10 0145 size: Kirigami.Units.iconSizes.large 0146 emitRate: 42 0147 0148 velocity: AngleDirection { 0149 angle: 90 0150 angleVariation: 10 0151 magnitude: 300 0152 } 0153 } 0154 } 0155 0156 // Fireworks 0157 0158 Timer { 0159 id: fireworksTimer 0160 interval: root.effectInterval; 0161 running: false; 0162 repeat: false; 0163 triggeredOnStart: true; 0164 onTriggered: { 0165 if (root.enabled) { 0166 fireworksInternalTimer.running = !fireworksInternalTimer.running 0167 } 0168 } 0169 } 0170 0171 Timer { 0172 id: fireworksInternalTimer 0173 interval: 300 0174 triggeredOnStart: true 0175 running: false 0176 repeat: true 0177 onTriggered: { 0178 var x = Math.random() * parent.width 0179 var y = Math.random() * parent.height 0180 customEmit(x, y) 0181 customEmit(x, y) 0182 customEmit(x, y) 0183 } 0184 } 0185 0186 ParticleSystem { 0187 id: fireworksSystem 0188 anchors.fill: parent 0189 running: fireworksInternalTimer.running 0190 onRunningChanged: { 0191 if (running) { 0192 opacity = 1 0193 } else { 0194 opacity = 0 0195 } 0196 } 0197 0198 Behavior on opacity { 0199 SequentialAnimation { 0200 NumberAnimation { duration: Kirigami.Units.longDuration } 0201 } 0202 } 0203 } 0204 0205 ImageParticle { 0206 id: fireworksParticleA 0207 system: fireworksSystem 0208 source: "qrc:/org/kde/neochat/qml/glowdot.png" 0209 alphaVariation: root.isThemeDark ? 0.1 : 0.1 0210 alpha: root.isThemeDark ? 0.5 : 1 0211 groups: ["a"] 0212 opacity: fireworksSystem.opacity 0213 entryEffect: ImageParticle.Scale 0214 rotationVariation: 360 0215 } 0216 0217 ImageParticle { 0218 system: fireworksSystem 0219 source: "qrc:/org/kde/neochat/qml/glowdot.png" 0220 color: root.isThemeDark ? "white" : "gold" 0221 alphaVariation: root.isThemeDark ? 0.1 : 0.1 0222 alpha: root.isThemeDark ? 0.5 : 1 0223 groups: ["light"] 0224 opacity: fireworksSystem.opacity 0225 entryEffect: ImageParticle.Scale 0226 rotationVariation: 360 0227 } 0228 0229 ImageParticle { 0230 id: fireworksParticleB 0231 system: fireworksSystem 0232 source: "qrc:/org/kde/neochat/qml/glowdot.png" 0233 alphaVariation: root.isThemeDark ? 0.1 : 0.1 0234 alpha: root.isThemeDark ? 0.5 : 1 0235 groups: ["b"] 0236 opacity: fireworksSystem.opacity 0237 entryEffect: ImageParticle.Scale 0238 rotationVariation: 360 0239 } 0240 0241 Component { 0242 id: emitterComp 0243 Emitter { 0244 id: container 0245 property int life: 23 0246 property real targetX: 0 0247 property real targetY: 0 0248 width: 1 0249 height: 1 0250 system: fireworksSystem 0251 size: 16 0252 endSize: 8 0253 sizeVariation: 5 0254 Timer { 0255 interval: life 0256 running: true 0257 onTriggered: { 0258 container.destroy(); 0259 var randomHue = Math.random() 0260 var lightness = root.isThemeDark ? 0.8 : 0.7 0261 fireworksParticleA.color = Qt.hsla(randomHue, 0.8, lightness, 1) 0262 fireworksParticleB.color = Qt.hsla(1-randomHue, 0.8, lightness, 1) 0263 } 0264 } 0265 velocity: AngleDirection {angleVariation:360; magnitude: 200} 0266 } 0267 } 0268 0269 function customEmit(x,y) { 0270 var currentSize = Math.round(Math.random() * 200) + 40 0271 var currentLifeSpan = Math.round(Math.random() * 1000) + 100 0272 for (var i=0; i<8; i++) { 0273 var obj = emitterComp.createObject(parent); 0274 obj.x = x 0275 obj.y = y 0276 obj.targetX = Math.random() * currentSize - currentSize/2 + obj.x 0277 obj.targetY = Math.random() * currentSize - currentSize/2 + obj.y 0278 obj.life = Math.round(Math.random() * 23) + 150 0279 obj.emitRate = Math.round(Math.random() * 32) + 5 0280 obj.lifeSpan = currentLifeSpan 0281 const group = Math.round(Math.random() * 3); 0282 switch (group) { 0283 case 0: 0284 obj.group = "light"; 0285 break; 0286 case 1: 0287 obj.group = "a"; 0288 break; 0289 case 2: 0290 obj.group = "b"; 0291 break; 0292 } 0293 } 0294 } 0295 }