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 }