pragma ComponentBehavior: Bound import QtQuick import QtQuick.Shapes // A mug of coffee with steam. Design space is 44 x 52 units, mug on the ground. Item { id: cup readonly property real unit: width / 44 implicitWidth: 44 implicitHeight: 52 Item { width: 44 height: 52 transformOrigin: Item.TopLeft scale: cup.unit Rectangle { // ground shadow x: 8; y: 46 width: 26; height: 5 radius: 2.5 color: "#000000" opacity: 0.18 antialiasing: true } // steam Repeater { model: 3 Shape { id: wisp required property int index x: 10 + index * 7 y: 2 width: 8 height: 16 opacity: 0 preferredRendererType: Shape.CurveRenderer ShapePath { strokeColor: "#ffffff" strokeWidth: 1.8 capStyle: ShapePath.RoundCap fillColor: "transparent" startX: 4; startY: 15 PathQuad { controlX: 0; controlY: 10; x: 4; y: 7 } PathQuad { controlX: 8; controlY: 4; x: 4; y: 0 } } SequentialAnimation { running: true loops: Animation.Infinite PauseAnimation { duration: wisp.index * 600 } ParallelAnimation { NumberAnimation { target: wisp; property: "opacity"; from: 0; to: 0.55; duration: 700 } NumberAnimation { target: wisp; property: "y"; from: 8; to: 2; duration: 700 } } ParallelAnimation { NumberAnimation { target: wisp; property: "opacity"; to: 0; duration: 1000 } NumberAnimation { target: wisp; property: "y"; to: -6; duration: 1000 } } PauseAnimation { duration: 1800 - wisp.index * 600 } } } } // handle Shape { x: 28; y: 24 width: 14; height: 18 preferredRendererType: Shape.CurveRenderer ShapePath { strokeColor: "#e8e3da" strokeWidth: 3.5 capStyle: ShapePath.RoundCap fillColor: "transparent" startX: 1; startY: 2 PathCubic { control1X: 12; control1Y: 0; control2X: 12; control2Y: 14; x: 1; y: 13 } } } // mug Rectangle { x: 9; y: 20 width: 22; height: 27 radius: 4 color: "#f7f4ee" antialiasing: true Rectangle { // band x: 0; y: 13 width: parent.width height: 5 color: "#4d7ea8" } } // coffee surface Rectangle { x: 10.5; y: 19 width: 19; height: 5 radius: 2.5 color: "#4a2c17" antialiasing: true } } }