How to implement 3D depth and shadow in Qt / QML?

I make a watch for the Ubuntu Touch platform and get the projects that I need to implement. The necessary implementation is shown below in Figure 1. I made the basic implementation, as shown in Figure 2. Currently, they are two rectangles with a radius attached to each other with a colored background. If you need a starting point (code wise), see http://bazaar.launchpad.net/~ubuntu-clock-dev/ubuntu-clock-app/trunk/view/head:/common/AnalogFaceBase.qml

What Qt / QML effects should I use to achieve depth and shadow? I can adjust the values โ€‹โ€‹myself if I know what effects are needed.

Note 1: Ignore the clock marks and color difference between the two images. This is what I know how to handle.

Note 2: Please provide links to the documentation so that I can read the documentation in order to customize it to fit the required design.

Required implementationCurrent implementation

+8
qt touch qml
source share
2 answers

This is not a repeated 3D depth, but only a small highlight / shadow that can be easily achieved. Here is an example of a simple ring:

import QtQuick 2.0; import QtGraphicalEffects 1.0; Rectangle { id: window; width: 400; height: 400; gradient: Gradient { // UbuntuTouch-like background GradientStop { position: 0.0; color: "#c05c7c"; } GradientStop { position: 1.0; color: "#d56a59"; } } property int offset : 2; property int size : 50; Item { // outter circle id: circleOutter; width: 250; height: width; anchors.centerIn: parent; Canvas { // draws the ring opacity: 0.35; antialiasing: true; contextType: "2d"; anchors.fill: parent; onPaint: { if (context) { context.reset (); context.globalCompositeOperation = "source-over"; context.fillStyle = "black"; context.beginPath (); context.ellipse (0, 0, width, height); context.fill (); context.globalCompositeOperation = "xor"; context.fillStyle = "black"; context.beginPath (); context.ellipse (circleInner.x, circleInner.y, circleInner.width, circleInner.height); context.fill (); } } onWidthChanged: { requestPaint (); } onHeightChanged: { requestPaint (); } } Rectangle { // draws the outter shadow/highlight id: sourceOutter; radius: (width / 2); antialiasing: true; gradient: Gradient { GradientStop { position: 0.0; color: "black"; } GradientStop { position: 0.5; color: "transparent"; } GradientStop { position: 1.0; color: "white"; } } anchors { fill: parent; margins: -offset; } } Rectangle { // mask for outer 3D effect id: maskOutter; color: "transparent"; radius: (width / 2); antialiasing: true; border { width: offset; color: "black"; } anchors.fill: sourceOutter; } OpacityMask { // outter effect opacity: 0.65; source: ShaderEffectSource { sourceItem: sourceOutter; hideSource: true; } maskSource: ShaderEffectSource { sourceItem: maskOutter; hideSource: true; } anchors.fill: sourceOutter; } Item { // inner circle id: circleInner; anchors { fill: parent; margins: size; } Rectangle { // draws the inner highlight / shadow id: sourceInner; radius: (width / 2); antialiasing: true; gradient: Gradient { GradientStop { position: 0.0; color: "white"; } GradientStop { position: 0.5; color: "transparent"; } GradientStop { position: 1.0; color: "black"; } } anchors { fill: parent; margins: -offset; } } Rectangle { // mask for inner 3D effect id: maskInner; color: "transparent"; radius: (width / 2); antialiasing: true; border { width: offset; color: "black"; } anchors.fill: sourceInner; } OpacityMask { // inner effect opacity: 0.65; source: ShaderEffectSource { sourceItem: sourceInner; hideSource: true; } maskSource: ShaderEffectSource { sourceItem: maskInner; hideSource: true; } anchors.fill: sourceInner; } } } } 

The trick is to draw black-transparent-white gradients and mask them to show only a thin line around the circles.

Here is the result

+20
source share

Depth does not exist. You can use the shadow from the graphic effects: http://qt-project.org/doc/qt-5.0/qtgraphicaleffects/graphicaleffects.html#drop-shadow

+1
source share

All Articles