Closed cppdev123 closed 8 months ago
What you ask doesn't seem easy to do right now...
I've come up with a hack
Wow := Rectangle {
property <float> controler: 0;
animate controler { duration: 1s; }
background: #33d;
touch := TouchArea {
pointer-event(e) => {
if (e.kind == PointerEventKind.down) {
controler = controler + 2;
}
}
}
circle := Rectangle {
width: 0;
height: width;
opacity: 1.;
border-radius: width/2;
background: #0005;
x: touch.pressed-x - width/2;
y: touch.pressed-y - width/2;
states [
pressed when mod(ceil(root.controler), 2) != 0 : {
circle.width: root.width * 2 * 1.4142;
circle.opacity: 0.;
}
]
transitions [
in pressed : {
animate circle.width { duration: 1s; easing: ease; }
animate circle.opacity { delay: 0.5s; duration: 300ms; easing: ease; }
}
out pressed : {
}
]
}
}
export _ := Window {
width: 300px;
height: 300px;
Wow {
}
}
We definitievly should add some feature to our animation system so such things can be easier to do.
Found that clip restricts the visible part to the parent and using your hack I tried to make many circles to display one on each press if the previous is still running (a hack too) but the macro proc panicked due to unreachable code !
export struct SPoint := {
x: float,
y: float,
}
export global RadiusCalc := {
callback calc-radius(SPoint, float, float) -> float; // mouse pos, parent pos, width, height
}
export RipplCircle := Rectangle {
property <length> radius: 0;
property <length> mx: 0;
property <length> my: 0;
property <float> fwidth: 0;
property <float> fheight: 0;
property <bool> running: false;
width: radius * 2;
height: radius * 2;
x: mx - width / 2;
y: my - height / 2;
background: rgba(0,0,0, 0.5);
border-radius: width / 2;
property <float> counter: 0;
animate counter { duration: 800ms; }
states [
ripple when counter > 0 && counter < 0.1 : {
radius: RadiusCalc.calc_radius({ x: mx / 1px, y: my / 1px }, fwidth, fheight) * 1px;
opacity: 0.;
running: true;
}
]
transitions [
in ripple: {
animate radius { duration: 800ms; }
animate opacity { duration: 800ms; }
}
]
}
export InkEffect := Rectangle {
preferred-width: 200px;
preferred-height: 200px;
background: white;
clip: true;
circle1 := RipplCircle {}
// un commenting the next line causes macro proc panick
//circle2 := RipplCircle { background: green; }
tch := TouchArea {
width: parent.width;
height: parent.height;
pointer-event(ev) => {
if (ev.kind == PointerEventKind.down && ev.button == PointerEventButton.left) {
if (!circle1.running) {
circle1.mx = mouse-x;
circle1.my = mouse-y;
circle1.fwidth = parent.width / 1px;
circle1.fheight = parent.height / 1px;
circle1.counter = circle1.counter == 0 ? 0.1 : 0;
}
}
}
}
}
What is needed is a method to create objects dynamically and destroy them on animation end as qml does
I think sequence of state would solve this issue: https://github.com/slint-ui/slint/issues/2255 So closing as a duplicate
I'm trying to implement an ink ripple like effect for buttons. It consists of a circular rectangle (the ripple) and a mouse area to received the mouse clicks to start animations on the radius of the circle and its opacity. what I want to do: when the mouse is pressed (not clicked !) the ripple will start from radius 0 until it reaches the furthest corner of the parent (cover the whole parent) and then it disappears when opacity reaches 1 then circle returns to size 0 again and during all of this the circle should not be visible outside of its parent
what I did so far: first try: circle is initially 0 in size and when the mouse is clicked (not pressed !) animation starts from the point of mouse until it covers the parent then it disappears when opacity reaches 0 and I can't restore it to its original state to start animation again !
second try: used states with transitions to run the animation as long as the TouchArea is pressed and hide it immediately when the mouse button is released, not what I want but animation can be restarted
third try: tried to create the ripple rectangle inside if block when the touch is pressed but I can't animate here !
in all tries the circle is visible outside its parent which is not desired
Any help how to overcome these issues ?