Warning, /frameworks/kirigami/src/controls/Hero.qml is written in an unsupported language. File is not indexed.
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Marco Martin <mart@kde.org> 0003 * SPDX-FileCopyrightText: 2020 Carson Black <uhhadd@gmail.com> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 import QtQuick 2.14 0009 import QtQuick.Controls 2.4 as QQC2 0010 import org.kde.kirigami 2.13 as Kirigami 0011 0012 /** 0013 * @brief An element that implements a shared element transition, otherwise known as a "hero animation". 0014 */ 0015 Item { 0016 id: root 0017 0018 //BEGIN properties 0019 /** 0020 * @brief This property holds the item to animate from in the Hero animation. 0021 */ 0022 property Item source 0023 0024 /** 0025 * @brief This property holds the item to animate to in the Hero animation. 0026 */ 0027 property Item destination 0028 0029 /** 0030 * @brief This property sets whether the source item will reappear 0031 * in the original position when the Hero animation completes. 0032 * 0033 * default: ``true`` 0034 */ 0035 property bool restore: true 0036 0037 /** 0038 * Group of properties related to the mask of the object when performing a hero animation. 0039 * This contains the default mask as well as the properties required to create a custom mask. 0040 * 0041 * The default mask of the Hero will transition from a circle to a rectangle on open(), and 0042 * from a rectangle to a circle on close(). 0043 * 0044 * This grouped property has the following sub-properties: 0045 * * ``sourceProgress: real`` the progress of the animation, where 0 is the start and 1 is the end. 0046 * * ``destinationProgress: real`` the progress of the animation, where 1 is the start and 0 is the end. 0047 * * ``mask.sourceHeight: real`` the height of the source item. 0048 * * ``mask.sourceWidth: real`` the width of the source item. 0049 * * ``mask.destinationWidth: real`` the width of the destination item. 0050 * * ``mask.destinationHeight: real`` the height of the destination item. 0051 * * ``item: Rectangle`` the item used to mask the Hero during animation. This should bind to the sourceProgress and destinationProgress to change as the animation progresses. 0052 * 0053 */ 0054 readonly property QtObject mask: QtObject { 0055 /** 0056 * @brief This property holds the progress of the animation, 0057 * where 0 is the start and 1 is the end. 0058 */ 0059 readonly property real sourceProgress: sourceEffect.progress 0060 0061 /** 0062 * @brief This property holds the progress of the animation, 0063 * where 1 is the start and 0 is the end. 0064 */ 0065 readonly property real destinationProgress: destinationEffect.progress 0066 0067 /** 0068 * @brief This property holds the height of the source item. 0069 */ 0070 readonly property real sourceHeight: sourceEffect.height 0071 0072 /** 0073 * @brief This property holds the width of the source item. 0074 */ 0075 readonly property real sourceWidth: sourceEffect.width 0076 0077 /** 0078 * @brief This property holds the width of the destination item. 0079 */ 0080 readonly property real destinationWidth: destinationEffect.width 0081 0082 /** 0083 * @brief This property holds the height of the destination item. 0084 */ 0085 readonly property real destinationHeight: destinationEffect.height 0086 0087 /** 0088 * @brief This property holds the item used to mask the Hero during animation. 0089 * 0090 * This should bind to the sourceProgress and destinationProgress to change as the animation progresses. 0091 */ 0092 property Item item: Rectangle { 0093 visible: false 0094 color: "white" 0095 0096 radius: (width/2) * mask.destinationProgress 0097 width: (mask.sourceWidth * mask.sourceProgress) + (mask.destinationWidth * mask.destinationProgress) 0098 height: (mask.sourceHeight * mask.sourceProgress) + (mask.destinationHeight * mask.destinationProgress) 0099 0100 layer.enabled: true 0101 layer.smooth: true 0102 } 0103 } 0104 0105 property alias duration: sourceAni.duration 0106 readonly property QtObject easing: QtObject { 0107 property alias amplitude: sourceAni.easing.amplitude 0108 property alias bezierCurve: sourceAni.easing.bezierCurve 0109 property alias overshoot: sourceAni.easing.overshoot 0110 property alias period: sourceAni.easing.period 0111 property alias type: sourceAni.easing.type 0112 } 0113 //END properties 0114 0115 function open() { 0116 if (source !== null && destination !== null && !heroAnimation.running) { 0117 heroAnimation.source = source 0118 heroAnimation.destination = destination 0119 heroAnimation.restart() 0120 } 0121 } 0122 function close() { 0123 if (source !== null && destination !== null && !heroAnimation.running) { 0124 // doing a switcheroo simplifies the code 0125 heroAnimation.source = destination 0126 heroAnimation.destination = source 0127 heroAnimation.restart() 0128 } 0129 } 0130 0131 SequentialAnimation { 0132 id: heroAnimation 0133 0134 property Item source: Item {} 0135 property Item destination: Item {} 0136 0137 ScriptAction { 0138 script: { 0139 heroAnimation.source.layer.enabled = true 0140 heroAnimation.source.layer.smooth = true 0141 heroAnimation.destination.layer.enabled = true 0142 heroAnimation.destination.layer.smooth = true 0143 sourceEffect.visible = true 0144 destinationEffect.visible = true 0145 sourceEffect.source = null 0146 sourceEffect.source = heroAnimation.source 0147 destinationEffect.source = null 0148 destinationEffect.source = heroAnimation.destination 0149 heroAnimation.source.opacity = 0 0150 heroAnimation.destination.opacity = 0 0151 sourceEffect.parent.visible = true 0152 } 0153 } 0154 ParallelAnimation { 0155 NumberAnimation { 0156 id: sourceAni 0157 0158 target: sourceEffect 0159 property: "progress" 0160 from: 0 0161 to: 1 0162 duration: Kirigami.Units.longDuration 0163 easing.type: Easing.InOutQuad 0164 } 0165 NumberAnimation { 0166 target: destinationEffect 0167 property: "progress" 0168 from: 1 0169 to: 0 0170 duration: root.duration 0171 easing.amplitude: root.easing.amplitude 0172 easing.bezierCurve: root.easing.bezierCurve 0173 easing.overshoot: root.easing.overshoot 0174 easing.period: root.easing.period 0175 easing.type: root.easing.type 0176 } 0177 } 0178 ScriptAction { 0179 script: { 0180 sourceEffect.visible = false 0181 destinationEffect.visible = false 0182 heroAnimation.source.layer.enabled = false 0183 heroAnimation.source.layer.smooth = false 0184 heroAnimation.destination.layer.enabled = false 0185 heroAnimation.destination.layer.smooth = false 0186 heroAnimation.destination.opacity = 1 0187 if (root.restore) { 0188 heroAnimation.source.opacity = 1 0189 } 0190 sourceEffect.parent.visible = false 0191 } 0192 } 0193 0194 } 0195 0196 QtObject { 0197 id: __privateShaderSources 0198 readonly property string vertexShader: ` 0199 uniform highp mat4 qt_Matrix; 0200 attribute highp vec4 qt_Vertex; 0201 attribute highp vec2 qt_MultiTexCoord0; 0202 varying highp vec2 qt_TexCoord0; 0203 uniform highp float startX; 0204 uniform highp float startY; 0205 uniform highp float targetX; 0206 uniform highp float targetY; 0207 uniform highp float scaleWidth; 0208 uniform highp float scaleHeight; 0209 uniform highp float progress; 0210 0211 highp mat4 morph = mat4(1.0 + (scaleWidth - 1.0) * progress, 0.0, 0.0, startX*(1.0-progress) + targetX*progress, 0212 0.0, 1.0 + (scaleHeight - 1.0) * progress, 0.0, startY*(1.0-progress) + targetY*progress, 0213 0.0, 0.0, 1.0, 0.0, 0214 0.0, 0.0, 0.0, 1.0); 0215 0216 void main() { 0217 qt_TexCoord0 = qt_MultiTexCoord0; 0218 gl_Position = qt_Matrix * qt_Vertex * morph; 0219 } 0220 ` 0221 } 0222 0223 ShaderEffect { 0224 id: sourceEffect 0225 x: 0 0226 y: 0 0227 parent: heroAnimation.source.QQC2.Overlay.overlay 0228 width: heroAnimation.source.width 0229 height: heroAnimation.source.height 0230 visible: false 0231 property variant source: heroAnimation.source 0232 property real progress: 0 0233 property real startX: heroAnimation.source.Kirigami.ScenePosition.x / (applicationWindow().width / 2) 0234 property real startY: -heroAnimation.source.Kirigami.ScenePosition.y / (applicationWindow().height / 2) 0235 0236 property real targetX: scaleWidth - 1 + (heroAnimation.destination.Kirigami.ScenePosition.x * 2) / applicationWindow().width 0237 property real targetY: 1-scaleHeight - (heroAnimation.destination.Kirigami.ScenePosition.y * 2) / applicationWindow().height 0238 property real scaleWidth: heroAnimation.destination.width/heroAnimation.source.width 0239 property real scaleHeight: heroAnimation.destination.height/heroAnimation.source.height 0240 vertexShader: __privateShaderSources.vertexShader 0241 fragmentShader: ` 0242 varying highp vec2 qt_TexCoord0; 0243 uniform sampler2D source; 0244 uniform lowp float qt_Opacity; 0245 uniform lowp float progress; 0246 void main() { 0247 gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity * (1.0 - progress); 0248 } 0249 ` 0250 } 0251 0252 ShaderEffect { 0253 id: destinationEffect 0254 x: 0 0255 y: 0 0256 parent: heroAnimation.destination.QQC2.Overlay.overlay 0257 width: heroAnimation.destination.width 0258 height: heroAnimation.destination.height 0259 visible: false 0260 property variant source: heroAnimation.destination 0261 property real progress: sourceEffect.progress 0262 property real startX: heroAnimation.destination.Kirigami.ScenePosition.x / (applicationWindow().width / 2) 0263 property real startY: -heroAnimation.destination.Kirigami.ScenePosition.y / (applicationWindow().height / 2) 0264 0265 property real targetX: scaleWidth - 1 + (heroAnimation.source.Kirigami.ScenePosition.x * 2) / applicationWindow().width 0266 property real targetY: 1-scaleHeight - (heroAnimation.source.Kirigami.ScenePosition.y * 2) / applicationWindow().height 0267 property real scaleWidth: heroAnimation.source.width/heroAnimation.destination.width 0268 property real scaleHeight: heroAnimation.source.height/heroAnimation.destination.height 0269 0270 property variant maskSource: root.mask.item 0271 0272 vertexShader: __privateShaderSources.vertexShader 0273 fragmentShader: ` 0274 varying highp vec2 qt_TexCoord0; 0275 uniform sampler2D source; 0276 uniform sampler2D maskSource; 0277 uniform lowp float qt_Opacity; 0278 uniform lowp float progress; 0279 void main() { 0280 gl_FragColor = texture2D(source, qt_TexCoord0) * texture2D(maskSource, qt_TexCoord0).a * qt_Opacity * (1.0 - progress); 0281 } 0282 ` 0283 } 0284 }