2022-09-13 使用QML实现文字雨

前言

前两天看到有人拿js做了一个文字雨特效,使用的是 Canvas,QML也一样可以用它来实现

一、效果图

二、代码

qml 代码

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15

Window {
    id:root
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    property int frameCount: 0


    Canvas{
        id: canvas
        anchors.fill: parent
        property int columnWidth : 20;
        property int columnCount : width / columnWidth;
        property var columnNextIndexs : new Array(columnCount).fill(1);

        onPaint: {
            var ctx = getContext("2d");
            ctx.fillStyle = 'rgba(240,240,240,0.1)';
            ctx.fillRect(0,0,width,height);
            ctx.fillStyle = getRandomColor();
            ctx.font = '20px Arial';
            for(let i = 0; i < columnCount;i++)
            {
                const x = i * columnWidth;
                const y = 20 * columnNextIndexs[i];
                ctx.fillText(getRandomChar(),x,y)
                if(y > height && Math.random() > 0.99){
                    columnNextIndexs[i] = 0;
                }else{
                    columnNextIndexs[i]++;
                }
            }
            root.frameCount ++;
        }
        // 使用requestAnimationFrame() 来启用循环,
        function draw(){
            var ctx = getContext("2d");
            ctx.fillStyle = 'rgba(240,240,240,0.1)';
            ctx.fillRect(0,0,width,height);
            ctx.fillStyle = getRandomColor();
            ctx.font = '20px Arial';
            for(let i = 0; i < columnCount;i++)
            {
                const x = i * columnWidth;
                const y = 20 * columnNextIndexs[i];
                ctx.fillText(getRandomChar(),x,y)
                if(y > height && Math.random() > 0.99){
                    columnNextIndexs[i] = 0;
                }else{
                    columnNextIndexs[i]++;
                }
            }
            root.frameCount ++;
            requestAnimationFrame(draw);
        }
        Component.onCompleted: {
            // 使用requestAnimationFrame() 来启用循环,
            //            requestAnimationFrame(draw);
        }
        Timer{
            id : timera
            interval: 1
            running: true
            repeat: true
            onTriggered: {
                canvas.requestPaint();
            }
        }


    }
    Text {
        id: fps
        property int ffs: 0
        text: qsTr("fps: ") + ffs;
        font.pointSize: 20
    }
    Timer{
        id : timer
        interval: 1000
        running: true
        repeat: true
        onTriggered: {
            fps.ffs = root.frameCount;
            root.frameCount = 0;
        }
    }
    function getRandomColor(){
        const fontColor = ["#3385E5","#0099CC","#AA66CC","#9933CC","#99CC00","#669900","#FFBB33","#FF8800","#FF4444","#CC0000"];
        return fontColor[Math.floor(Math.random()* fontColor.length)];
    }

    function getRandomChar(){
        const str = "hello world,This function schedules callback to be invoked before composing the Qt Quick scen";
        return str[Math.floor(Math.random()* str.length)];
    }

}

说明一点:建议使用requestAnimationFrame来递归,触发循环,此时会根据系统来自行决定fps。
也可以使用定时器来触发循环,测试了一下,定时器1ms触发时,最大也就是requestAnimationFrame能实现的fps。

你可能感兴趣的:(qml,QT,日常记录,javascript,qt)