ConicalGradient escaping curved OpacityMask
-
Hi, looking for some guidance back in the right direction please.
I'm creating a curved gauge where the centre is "filled" with a bar to indicate progress. To achieve this I'm attempting to use a ConicalGradient and an OpacityMask together.
This works, but my ConicalGradient is showing outside the curved object that I'm trying to mask. As I have a transparent background (and this is intended to be a component of a larger project) this is not good.
How do I achieve what I have with the OpacityMask without going out of bounds?
I thought about using a RadialGradient to mask it off but that seems like the wrong solution.FocusScope { id: root width: 1205 height: 1205 visible: true scale: 1 Image { id: base x: 0 y: 0 width: 1205 height: 1205 source: "images/Base.png" z: 0 visible: true opacity: 100 / 100 } Image { id: rightTicks x: 746 y: 64 width: 99 height: 1070 source: "images/RightTicks.png" z: 14 //9 visible: true opacity: 100 / 100 } Image { id: rightBar x: 745 y: 60 width: 432 height: 1078 source: "images/RightBar.png" z: 16 //11 visible: true opacity: 100 / 100 } Item { Image { id: rightGaugeFill x: 767 y: 77 width: 400 height: 1044 source: "images/RightGaugeFill.png" z: 13 visible: true opacity: 100 / 100 } OpacityMask { source: rightGaugeFillMask maskSource: rightGaugeFill } ConicalGradient { id: rightGaugeFillMask anchors.fill: rightGaugeFill anchors.leftMargin: -725 z: 14 visible: true property double fillPct: 0.25 gradient: Gradient { GradientStop { position: 0.501 color: "transparent" } GradientStop { position: 0.5 color: "transparent" } GradientStop { position: rightGaugeFillMask.fillPct + 0.001 // Position 1 for adjustment color: "transparent" } GradientStop { position: rightGaugeFillMask.fillPct - 0.001 // Position 2 for adjustment color: "#333333" } GradientStop { position: 0.0 color: "#333333" } } } } }
Thank you
-
No problem at all and I appreciate the help you have given. You went to more effort than I expected in the first instance, thank you.
You also did happen to put me in the right direction and I learned a bit more than I started.The missing piece in the ConicalGradient is "source". If I use that and point it to the base image (the base circle) I can keep everything contained and get the transparency effect I'm looking for. Now I can vary (and animate) rightGaugeFillMask.fillPct and get a smooth gauge action.
Final codeItem { Image { id: rightGaugeFill x: 767 y: 77 width: 400 height: 1044 source: "images/RightGaugeFill.png" z: 13 visible: true opacity: 100 / 100 } OpacityMask { source: rightGaugeFill maskSource: rightGaugeFillMask } ConicalGradient { id: rightGaugeFillMask height: base.height width: base.width z: 14 source: base property double fillPct: 0.1 gradient: Gradient { GradientStop { position: 0.501 color: "transparent" } GradientStop { position: rightGaugeFillMask.fillPct + 0.001 // Position 1 for adjustment color: "transparent" } GradientStop { position: rightGaugeFillMask.fillPct - 0.001 // Position 2 for adjustment color: "#333333" } GradientStop { position: 0.0 color: "#333333" } } } }
-
Just a thought, have you tried applying "clip: true" to the base image?... (no, it does nothing, ignore that!)
I took your image, cleaned it up in photoshop so I could mock the gauge up, here's what I came up with;
Image { id: img width: 1060 height: width anchors.centerIn: parent fillMode: Image.PreserveAspectFit source: "../images/baseimage.png" property bool rounded: true property bool adapt: true ConicalGradient { z: -1 id: gradient width: 1060 height: width gradient: Gradient { GradientStop { position: 0.0; color: "red" } GradientStop { position: 0.1; color: "grey" } } SequentialAnimation on angle { NumberAnimation { from: 20 to: 170 duration: 1000 } NumberAnimation { from: 170 to: 30 duration: 1000 } } } // image masking layer.enabled: rounded layer.effect: OpacityMask { maskSource: Rectangle { anchors.centerIn: parent color: "orangered" width: img.adapt ? img.width : Math.min(img.width, img.height) height: img.adapt ? img.height : width radius: Math.min(width, height) } } }
-
Thanks for your suggestion!
I wasn't quite able to replicate your effect the way I wanted. I think the main difference being my "fill" is another image and you are using the "rounded rectangle" to achieve that?
I was able to use the rounded rectangle to stop anything going out of the bounds of my base image (which is great!) but I'm now not getting the needed transparency effect anymore. I think I have all the right tools and techniques now just applying them in the wrong way. Setting the Rectange "test" color to transparent looks like the right result initially, and then QT Design Studio renders it a second time and it's no good.I was wondering if you had my source images whether you could provide any further suggestions please?
https://filebin.net/jq42k3hclx25xy2t
Thanks -
To be honest and respectful, I struggle to do anything with your code as it stands even with the images. That is partly why I presented an alternative rather than adapting your code. I would strongly consider learning a better way to create this gauge, but I appreciate we all gain different understanding of how code works and what is best/logical and easy to understand in human readable format. I can't make head nor tail of your code, sorry.
In the meantime, consider taking a look at ways to animate gauges using Circular Slider from ArunPK; https://github.com/arunpkqt/CircularSlider - his code can be adapted to make some wonderful gauges, I use CircularSlider a lot.
-
No problem at all and I appreciate the help you have given. You went to more effort than I expected in the first instance, thank you.
You also did happen to put me in the right direction and I learned a bit more than I started.The missing piece in the ConicalGradient is "source". If I use that and point it to the base image (the base circle) I can keep everything contained and get the transparency effect I'm looking for. Now I can vary (and animate) rightGaugeFillMask.fillPct and get a smooth gauge action.
Final codeItem { Image { id: rightGaugeFill x: 767 y: 77 width: 400 height: 1044 source: "images/RightGaugeFill.png" z: 13 visible: true opacity: 100 / 100 } OpacityMask { source: rightGaugeFill maskSource: rightGaugeFillMask } ConicalGradient { id: rightGaugeFillMask height: base.height width: base.width z: 14 source: base property double fillPct: 0.1 gradient: Gradient { GradientStop { position: 0.501 color: "transparent" } GradientStop { position: rightGaugeFillMask.fillPct + 0.001 // Position 1 for adjustment color: "transparent" } GradientStop { position: rightGaugeFillMask.fillPct - 0.001 // Position 2 for adjustment color: "#333333" } GradientStop { position: 0.0 color: "#333333" } } } }
-