前言
前两天看到有人拿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。