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 }