Search code examples
qtqmldropshadowripple-effect

I faced a conflict in using DropShadow and Ripple


I wrote a Ripple item in a Rectangle Item and enabled clip property of the Rectangle to prevent the Ripple drawing get out of that Rectangle.

without DropShadow:

without DropShadow

Everything works fine until I add a DropShadow to that Rectangle. Although it is outside the Rectangle item, but it neutralizes the clip effect in left and right side of the Rectangle.

with DropShadow:

with DropShadow

Here is my code:

import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtGraphicalEffects 1.12
import QtQuick.Controls.Material.impl 2.12

Item{
                    width: 400
                    height: 100

                    DropShadow {
                        anchors.fill: itemRect
                            horizontalOffset: 0
                            verticalOffset: 0
                            radius: 12.0
                            samples: 17
                            color: "#50000000"
                            source: itemRect
                        }

                    Rectangle{
                        id:itemRect
                        anchors.fill: parent;
                        anchors.margins: 8;
                        border.width: 1
                        radius: 5;
                        clip: true;


                        MouseArea{
                            id: button
                            anchors.fill: parent
                            onPressed: {
                                ripple.x=mouseX-(ripple.width/2);
                                ripple.y=mouseY-(ripple.height/2);
                            }


                            Ripple {
                                id: ripple
                                clipRadius: 2
                                x:40
                                width: itemRect.width*2
                                height: itemRect.height*2
                                pressed: button.pressed
                                active:  false
                                color: "#10000000"
//                                layer.enabled: true
//                                layer.effect: OpacityMask {
//                                            maskSource: Rectangle
//                                            {
//                                                width: ripple.height
//                                                height: ripple.height
//                                                radius: ripple.height
//                                            }
//                                        }
                            }
                        }
                    }

                }

I tested OpacityMask for layer.effect of Ripple Item. But it didn't have any effects.


Solution

  • Finaly i wrote my own Ripple. It can be used anywhere without any issues.

    https://github.com/mmjvox/Another-Ripple

    here is my code:

    import QtQuick 2.12
    import QtQuick.Layouts 1.12
    import QtGraphicalEffects 1.12
    import AnotherRipple 1.0
    
    Item{
                        width: 400
                        height: 100
    
                        DropShadow {
                            anchors.fill: itemRect
                                horizontalOffset: 0
                                verticalOffset: 0
                                radius: 12.0
                                samples: 17
                                color: "#50000000"
                                source: itemRect
                            }
    
                        Rectangle{
                            id:itemRect
                            anchors.fill: parent;
                            anchors.margins: 8;
                            border.width: 1
                            radius: 5;
                            clip: true;
                            
                            SimpleRipple{
                                id: ripple
                                anchors.fill: parent;
                                color: "#50ffa070"
                            }
    
                            MouseArea{
                                id: button
                                anchors.fill: parent
                                onClicked: {
    
                                    // In this example MouseArea accepts pressed event to provide clicked(released) event.
                                    // Ripple can't sense pressed event, so I called pressed method of Ripple.
                            
                                    ripple.pressed(mouse.x,mouse.y);
                                    
                                    // Some Other Operations
                                }
    
                            }
                        }
    
                    }