160 lines
2.8 KiB
QML
160 lines
2.8 KiB
QML
import QtQuick 2.15
|
|
|
|
/**
|
|
* Provides a flip-panel effect on a given item
|
|
* It is assumed we have the same geometry of that item and anchored on top
|
|
*/
|
|
|
|
// in any sane world we would hide the flipEffect when we're not animating
|
|
// however QtQuick tries to be clever and flushes with Effectsource when there's no monitor
|
|
// and I relied on that..
|
|
// doesn't seem too costly, so meh
|
|
// it does look hilarious if you resize though...
|
|
|
|
Item
|
|
{
|
|
id: root
|
|
property Item sourceItem
|
|
property int duration: 1000
|
|
property bool supress: true
|
|
|
|
function flip()
|
|
{
|
|
// lazy hack to avoid the first flip that happens on initial bind
|
|
if (supress)
|
|
{
|
|
supress = false;
|
|
return;
|
|
}
|
|
|
|
flipAnim.start()
|
|
}
|
|
|
|
ShaderEffectSource
|
|
{
|
|
id: oldTop
|
|
sourceItem: root.sourceItem
|
|
sourceRect: Qt.rect(0, 0, root.sourceItem.width, root.sourceItem.height/2)
|
|
live: false
|
|
}
|
|
|
|
ShaderEffectSource
|
|
{
|
|
id: oldBottom
|
|
sourceItem: root.sourceItem
|
|
sourceRect: Qt.rect(0, root.sourceItem.height/2, root.sourceItem.width, root.sourceItem.height/2)
|
|
live: false
|
|
}
|
|
|
|
ShaderEffectSource
|
|
{
|
|
id: newBottom
|
|
sourceItem: root.sourceItem
|
|
sourceRect: Qt.rect(0, root.sourceItem.height/2, root.sourceItem.width, root.sourceItem.height/2)
|
|
live: false
|
|
textureMirroring: ShaderEffectSource.NoMirroring
|
|
}
|
|
|
|
ShaderEffect
|
|
{
|
|
id: effect
|
|
anchors.top: root.top
|
|
anchors.bottom: root.verticalCenter
|
|
anchors.left: root.left
|
|
anchors.right: root.right
|
|
property variant source: oldTop
|
|
z: 10
|
|
transform: Rotation
|
|
{
|
|
id: upperRotation
|
|
origin.x: effect.width/2
|
|
origin.y: effect.height
|
|
axis.x: 1
|
|
axis.y: 0
|
|
axis.z: 0
|
|
angle: 90
|
|
}
|
|
}
|
|
|
|
ShaderEffect
|
|
{
|
|
id: effect2
|
|
anchors.top: root.top
|
|
anchors.bottom: root.verticalCenter
|
|
anchors.left: root.left
|
|
anchors.right: root.right
|
|
property variant source: newBottom
|
|
z: 10
|
|
transform: Rotation
|
|
{
|
|
id: lowerRotation
|
|
origin.x: effect.width/2
|
|
origin.y: effect.height
|
|
axis.x: 1
|
|
axis.y: 0
|
|
axis.z: 0
|
|
angle: 90
|
|
}
|
|
}
|
|
|
|
ShaderEffect
|
|
{
|
|
property variant source: oldBottom
|
|
anchors.top: root.verticalCenter
|
|
anchors.bottom: root.bottom
|
|
anchors.left: root.left
|
|
anchors.right: root.right
|
|
z:1
|
|
}
|
|
|
|
SequentialAnimation
|
|
{
|
|
id: flipAnim
|
|
|
|
NumberAnimation
|
|
{
|
|
target: upperRotation
|
|
property: "angle"
|
|
from: 0
|
|
to: -90
|
|
duration: root.duration / 2
|
|
}
|
|
|
|
ScriptAction
|
|
{
|
|
script:
|
|
{
|
|
newBottom.scheduleUpdate()
|
|
}
|
|
}
|
|
|
|
NumberAnimation
|
|
{
|
|
target: lowerRotation
|
|
property: "angle"
|
|
from: -90
|
|
to: -180
|
|
duration: root.duration / 2
|
|
}
|
|
|
|
ScriptAction
|
|
{
|
|
script:
|
|
{
|
|
oldTop.scheduleUpdate();
|
|
oldBottom.scheduleUpdate();
|
|
}
|
|
}
|
|
}
|
|
|
|
// horizontal line to make it look like a flippy thing
|
|
Rectangle
|
|
{
|
|
color: "#9b0000"
|
|
height: 2
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
z: 20
|
|
}
|
|
}
|