I want to dynamically generate or remove GradientStops, and I also want to dynamically change it's colors using a NumberAnimation. I have a NumberAnimation to change a variety "idxx" to form a animation like below:
NumberAnimation {
target: thiz
property: "idxx"
duration: settings.cycleTime ?? 500
from: settings.cycleColorFrom ?? 0
to: settings.cycleColorTo ?? 15 }
by using a function to change colors:
function getColor(index){
var hueIndex = (15 - (((idxx + index) > 15) ? idxx - 15 + index : idxx + index));
var hue = (hueIndex * cycleEnd / 255) + (cycleStart / 255);
return Qt.hsva(hue, cycleSaturation, cycleValue, cycleOpacity); }
It works well when I use Gradient like:
Gradient {
id: gradientRainbow
GradientStop { position: 0.000; color: getColor(15) }
GradientStop { position: 0.067; color: getColor(14) }
GradientStop { position: 0.133; color: getColor(13) }
GradientStop { position: 0.200; color: getColor(12) }
GradientStop { position: 0.267; color: getColor(11) }
GradientStop { position: 0.333; color: getColor(10) }
GradientStop { position: 0.400; color: getColor(9) }
GradientStop { position: 0.467; color: getColor(8) }
GradientStop { position: 0.533; color: getColor(7) }
GradientStop { position: 0.600; color: getColor(6) }
GradientStop { position: 0.667; color: getColor(5) }
GradientStop { position: 0.733; color: getColor(4) }
GradientStop { position: 0.800; color: getColor(3) }
GradientStop { position: 0.867; color: getColor(2) }
GradientStop { position: 0.933; color: getColor(1) }
GradientStop { position: 1.000; color: getColor(0) }
}
I tried to use:
property list<GradientStop> gsl: [GradientStop { position: 0.000; color: getColor(15) },
GradientStop { position: 0.067; color: getColor(14) },
GradientStop { position: 0.133; color: getColor(13) },
GradientStop { position: 0.200; color: getColor(12) },
GradientStop { position: 0.267; color: getColor(11) },
GradientStop { position: 0.333; color: getColor(10) },
GradientStop { position: 0.400; color: getColor(9) },
GradientStop { position: 0.467; color: getColor(8) },
GradientStop { position: 0.533; color: getColor(7) },
GradientStop { position: 0.600; color: getColor(6) },
GradientStop { position: 0.667; color: getColor(5) },
GradientStop { position: 0.733; color: getColor(4) },
GradientStop { position: 0.800; color: getColor(3) },
GradientStop { position: 0.867; color: getColor(2) },
GradientStop { position: 0.933; color: getColor(1) },
GradientStop { position: 1.000; color: getColor(0) }]
Gradient {
id: gradientRainbow
stops: gsl
}
It dosen't change colors when the NumberAnimation is running and I can't dynamically add or remove GradientStops in gsl which will lead to Unexpected token ]', Expected token {' or Expected a qualified name id. When I use (How to dynamically add stops in a Gradient):
Gradient {
id: gradientRainbow
Component.onCompleted: {
var stops = [];
for (var i = 15; i >= 0; i--) {
var position = (15 - i) / 15.0;
stops.push(gradientStopComponent.createObject(base, { "position": position, "color": getColor(i)}));
}
gradientRainbow.stops = stops;
}
}
Component{
id: gradientStopComponent
GradientStop {}
}
It also will not change the colors when the NumberAnimation running
The following is a generalization of the Gradient
example in https://doc.qt.io/qt-6/qml-qtquick-gradient.html and it illustrates how to dynamically create a list<GradientStop>
array by using array.map
on an existing array to make iterative calls to gradientStopComponent.createObject
.
property int index: 0
property var stopdefs1: [{ position: 0.0, color: "red" }, { position: 0.33, color: "yellow" }, { position: 1.00, color: "green" } ]
property var stopdefs2: [{ position: 0.0, color: "green" }, { position: 0.66, color: "yellow" }, { position: 1.00, color: "red" } ]
Rectangle {
width: 100; height: 100
gradient: makeGradient(index == 0 ? stopdefs1 : stopdefs2)
TapHandler { onTapped: index = 1 - index }
}
function makeGradient(stopdefs) { return gradientComponent.createObject(null, {stopdefs}); }
Component {
id: gradientComponent
Gradient {
property var stopdefs
stops: stopdefs.map( d => gradientStopComponent.createObject(null, d) );
}
}
Component { id: gradientStopComponent; GradientStop { } }
You can Try it Online!