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 { 0060 duration: Kirigami.Units.longDuration 0061 } 0062 } 0063 } 0064 0065 ImageParticle { 0066 source: "qrc:/org/kde/neochat/qml/confetti.png" 0067 entryEffect: ImageParticle.Scale 0068 rotationVariation: 360 0069 rotationVelocity: 90 0070 color: Qt.hsla(Math.random(), 0.5, 0.6, 1) 0071 colorVariation: 1 0072 } 0073 0074 Emitter { 0075 anchors { 0076 left: parent.left 0077 right: parent.right 0078 top: parent.top 0079 } 0080 0081 sizeVariation: Kirigami.Units.iconSizes.small / 2 0082 lifeSpan: Kirigami.Units.veryLongDuration * 10 0083 size: Kirigami.Units.iconSizes.small 0084 0085 velocity: AngleDirection { 0086 angle: 90 0087 angleVariation: 42 0088 magnitude: 500 0089 } 0090 } 0091 } 0092 0093 // Snow 0094 0095 Timer { 0096 id: snowTimer 0097 interval: root.effectInterval 0098 running: false 0099 repeat: false 0100 triggeredOnStart: true 0101 onTriggered: { 0102 if (root.enabled) { 0103 snowSystem.running = !snowSystem.running; 0104 } 0105 } 0106 } 0107 0108 ParticleSystem { 0109 id: snowSystem 0110 anchors.fill: parent 0111 0112 running: false 0113 onRunningChanged: { 0114 if (running) { 0115 opacity = 1; 0116 } else { 0117 opacity = 0; 0118 } 0119 } 0120 0121 Behavior on opacity { 0122 SequentialAnimation { 0123 NumberAnimation { 0124 duration: Kirigami.Units.longDuration 0125 } 0126 } 0127 } 0128 0129 ItemParticle { 0130 delegate: Rectangle { 0131 width: 10 0132 height: width 0133 radius: width 0134 color: root.isThemeDark ? "white" : darkSnowColor 0135 scale: Math.random() 0136 opacity: Math.random() 0137 } 0138 } 0139 0140 Emitter { 0141 anchors { 0142 left: parent.left 0143 right: parent.right 0144 top: parent.top 0145 } 0146 0147 sizeVariation: Kirigami.Units.iconSizes.medium 0148 lifeSpan: Kirigami.Units.veryLongDuration * 10 0149 size: Kirigami.Units.iconSizes.large 0150 emitRate: 42 0151 0152 velocity: AngleDirection { 0153 angle: 90 0154 angleVariation: 10 0155 magnitude: 300 0156 } 0157 } 0158 } 0159 0160 // Fireworks 0161 0162 Timer { 0163 id: fireworksTimer 0164 interval: root.effectInterval 0165 running: false 0166 repeat: false 0167 triggeredOnStart: true 0168 onTriggered: { 0169 if (root.enabled) { 0170 fireworksInternalTimer.running = !fireworksInternalTimer.running; 0171 } 0172 } 0173 } 0174 0175 Timer { 0176 id: fireworksInternalTimer 0177 interval: 300 0178 triggeredOnStart: true 0179 running: false 0180 repeat: true 0181 onTriggered: { 0182 var x = Math.random() * parent.width; 0183 var y = Math.random() * parent.height; 0184 customEmit(x, y); 0185 customEmit(x, y); 0186 customEmit(x, y); 0187 } 0188 } 0189 0190 ParticleSystem { 0191 id: fireworksSystem 0192 anchors.fill: parent 0193 running: fireworksInternalTimer.running 0194 onRunningChanged: { 0195 if (running) { 0196 opacity = 1; 0197 } else { 0198 opacity = 0; 0199 } 0200 } 0201 0202 Behavior on opacity { 0203 SequentialAnimation { 0204 NumberAnimation { 0205 duration: Kirigami.Units.longDuration 0206 } 0207 } 0208 } 0209 } 0210 0211 ImageParticle { 0212 id: fireworksParticleA 0213 system: fireworksSystem 0214 source: "qrc:/org/kde/neochat/qml/glowdot.png" 0215 alphaVariation: root.isThemeDark ? 0.1 : 0.1 0216 alpha: root.isThemeDark ? 0.5 : 1 0217 groups: ["a"] 0218 opacity: fireworksSystem.opacity 0219 entryEffect: ImageParticle.Scale 0220 rotationVariation: 360 0221 } 0222 0223 ImageParticle { 0224 system: fireworksSystem 0225 source: "qrc:/org/kde/neochat/qml/glowdot.png" 0226 color: root.isThemeDark ? "white" : "gold" 0227 alphaVariation: root.isThemeDark ? 0.1 : 0.1 0228 alpha: root.isThemeDark ? 0.5 : 1 0229 groups: ["light"] 0230 opacity: fireworksSystem.opacity 0231 entryEffect: ImageParticle.Scale 0232 rotationVariation: 360 0233 } 0234 0235 ImageParticle { 0236 id: fireworksParticleB 0237 system: fireworksSystem 0238 source: "qrc:/org/kde/neochat/qml/glowdot.png" 0239 alphaVariation: root.isThemeDark ? 0.1 : 0.1 0240 alpha: root.isThemeDark ? 0.5 : 1 0241 groups: ["b"] 0242 opacity: fireworksSystem.opacity 0243 entryEffect: ImageParticle.Scale 0244 rotationVariation: 360 0245 } 0246 0247 Component { 0248 id: emitterComp 0249 Emitter { 0250 id: container 0251 property int life: 23 0252 property real targetX: 0 0253 property real targetY: 0 0254 width: 1 0255 height: 1 0256 system: fireworksSystem 0257 size: 16 0258 endSize: 8 0259 sizeVariation: 5 0260 Timer { 0261 interval: life 0262 running: true 0263 onTriggered: { 0264 container.destroy(); 0265 var randomHue = Math.random(); 0266 var lightness = root.isThemeDark ? 0.8 : 0.7; 0267 fireworksParticleA.color = Qt.hsla(randomHue, 0.8, lightness, 1); 0268 fireworksParticleB.color = Qt.hsla(1 - randomHue, 0.8, lightness, 1); 0269 } 0270 } 0271 velocity: AngleDirection { 0272 angleVariation: 360 0273 magnitude: 200 0274 } 0275 } 0276 } 0277 0278 function customEmit(x, y) { 0279 var currentSize = Math.round(Math.random() * 200) + 40; 0280 var currentLifeSpan = Math.round(Math.random() * 1000) + 100; 0281 for (var i = 0; i < 8; i++) { 0282 var obj = emitterComp.createObject(parent); 0283 obj.x = x; 0284 obj.y = y; 0285 obj.targetX = Math.random() * currentSize - currentSize / 2 + obj.x; 0286 obj.targetY = Math.random() * currentSize - currentSize / 2 + obj.y; 0287 obj.life = Math.round(Math.random() * 23) + 150; 0288 obj.emitRate = Math.round(Math.random() * 32) + 5; 0289 obj.lifeSpan = currentLifeSpan; 0290 const group = Math.round(Math.random() * 3); 0291 switch (group) { 0292 case 0: 0293 obj.group = "light"; 0294 break; 0295 case 1: 0296 obj.group = "a"; 0297 break; 0298 case 2: 0299 obj.group = "b"; 0300 break; 0301 } 0302 } 0303 } 0304 }