javascript QML圆形图像“波效应”伪影

vwkv1x7d  于 2022-12-10  发布在  Java
关注(0)|答案(1)|浏览(126)

我正在建立一个qml应用程序,我想实现一个圆圈,里面有一个“波”的效果。我或多或少成功了,除了结果是这个图形伪像...有人能帮助我吗?
问题在于:

来源影像:

工作示例不带圆:

我声明我从来没有使用过qml在我的生活,这是第三天我一直在它的工作,当然我试图阅读文档等,但我不知道发生了什么,这是代码:

//QT PK
import QtQuick 2.2
import QtQuick.Window 2.0
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtGraphicalEffects 1.0
//JS PK
import "componentCreation.js" as MyScript

ApplicationWindow 
{
    id: window
    flags: Qt.FramelessWindowHint
    visible: true
    title: qsTr("window")
    width: 1600
    height: 900
    x: (Screen.width - width) / 2
    y: (Screen.height - height) / 2
    color: "transparent"

    property real slideValue
    signal onSlide(real value)

    Image 
    {
        id: img
        source: '/home/patan/code/QML/pic/contents/images/Waves.png'
        property bool rounded: true
        property bool adapt: true

        //MAKE IMAGE CIRCULAR
        layer.enabled: rounded
        layer.effect: OpacityMask 
        {
            maskSource: Item 
            {
                width: img.width
                height: img.height
            
                Rectangle 
                {
                    anchors.centerIn: parent
                    width: img.adapt ? img.width : Math.min(img.width, img.height)
                    height: img.adapt ? img.height : width
                    radius: Math.min(width, height)
                }
            }
        }
        //WAVE EFFECT
        ShaderEffect 
        {
            anchors.fill: parent
            property variant source: img
            property real frequency: 1
            property real amplitude: 0.1
            property real time: 0.0
            NumberAnimation on time 
            {
                from: 0; to: Math.PI*2; duration: 10000; loops: Animation.Infinite
            }
            fragmentShader: "
                            varying highp vec2 qt_TexCoord0;
                            uniform sampler2D source;
                            uniform lowp float qt_Opacity;
                            uniform highp float frequency;
                            uniform highp float amplitude;
                            uniform highp float time;
                            void main() {
                                highp vec2 texCoord = qt_TexCoord0;
                                texCoord.y = amplitude * sin(time * frequency + texCoord.x * 6.283185) + texCoord.y;
                                gl_FragColor = texture2D(source, texCoord) * qt_Opacity;
                            }"
        }
    }
}

请原谅我,如果这是可怕的代码质量,如果任何人可以帮助我得到它的工作,我将不胜感激

cyej8jka

cyej8jka1#

我对你的解决方案采取了不同的方法。
我创建了一个应用了波浪效果的SVG图标。然后我拉伸SVG图标以填充屏幕。然后我使用Image.Tile重复填充波浪,然后我使用NumberAnimation移动SVG图标x
然后,我应用OpacityMask剪切出一个圆:

import QtQuick
import QtQuick.Controls
import Qt5Compat.GraphicalEffects
Page {
    id: window
    
    property real slide: 0.0
    
    Item {
        id: waveEffect
        anchors.fill: parent
        Image {
            height: window.height
            width: window.width + 4 * window.height
            x: -window.height * 2 + slide
            source: `data:image/svg+xml;utf8,<svg width="32" height="32">
<rect width="32" height="32" fill="#0F325B"/>
<path d="M ${wave()} 32 16 32 32 0 32" fill="#5294E2"/>
</svg>`
            sourceSize: Qt.size(height, height)
            fillMode: Image.Tile
        }
        visible: false
    }

    Item {
        id: circleEffect
        anchors.fill: parent
        Rectangle {
            width: Math.min(window.height, window.width)
            height: width
            radius: width / 2
            color: "red"
        }
        visible: false
    }
    
    NumberAnimation {
        target: window
        property: "slide"
        from: window.height
        to: 0
        loops: Animation.Infinite
        running: true
        duration: 8000
    }

    OpacityMask {
        anchors.fill: waveEffect
        source: waveEffect
        maskSource: circleEffect
    }

    function wave() {
        let str = [ ];
        for (let j = 0; j<32; j++) {
            let a = j * 2 * Math.PI / 32;
            let i = Math.sin(a) * 2 + 16;
            str.push(`${j} ${i.toFixed(2)} `);
        }
        return str.join(" ");
    }
}

您可以Try it Online!

相关问题