This commit is contained in:
zhuzichu 2023-06-30 12:08:57 +08:00
parent 9f9e48659b
commit f13f1727af
3 changed files with 73 additions and 76 deletions

View File

@ -208,60 +208,12 @@ CustomWindow {
} }
} }
//todo
CircularReveal{ CircularReveal{
id:reveal
target:window.contentItem
anchors.fill: parent anchors.fill: parent
} onImageChanged: {
changeDark()
Image{
id:img_cache
visible: false
anchors.fill: parent
}
Canvas{
id:canvas
anchors.fill: parent
property int centerX: canvas.width / 2
property int centerY: canvas.height / 2
property real radius: 0
property int maxRadius: 0
property url imageUrl
Behavior on radius{
id:anim_radius
NumberAnimation {
target: canvas
property: "radius"
duration: 333
easing.type: Easing.OutCubic
}
}
onRadiusChanged: {
canvas.requestPaint()
}
onPaint: {
var ctx = canvas.getContext("2d");
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvasSize.width, canvasSize.height);
ctx.save()
if(img_cache.source.toString().length!==0){
try{
ctx.drawImage(img_cache.source, 0, 0, canvasSize.width, canvasSize.height, 0, 0, canvasSize.width, canvasSize.height)
}catch(e){
img_cache.source = ""
}
}
clearArc(ctx, centerX, centerY, radius)
canvas.unloadImage(img_cache.source)
ctx.restore()
}
function clearArc(ctx,x, y, radius, startAngle, endAngle) {
ctx.beginPath()
ctx.globalCompositeOperation = 'destination-out'
ctx.fillStyle = 'black'
ctx.arc(x, y, radius, 0, 2*Math.PI);
ctx.fill();
ctx.closePath();
} }
} }
@ -270,13 +222,6 @@ CustomWindow {
} }
function handleDarkChanged(button){ function handleDarkChanged(button){
var changeDark = function(){
if(FluTheme.dark){
FluTheme.darkMode = FluDarkMode.Light
}else{
FluTheme.darkMode = FluDarkMode.Dark
}
}
if(FluTools.isMacos()){ if(FluTools.isMacos()){
changeDark() changeDark()
}else{ }else{
@ -284,18 +229,16 @@ CustomWindow {
var pos = button.mapToItem(target,0,0) var pos = button.mapToItem(target,0,0)
var mouseX = pos.x var mouseX = pos.x
var mouseY = pos.y var mouseY = pos.y
canvas.maxRadius = Math.max(distance(mouseX,mouseY,0,0),distance(mouseX,mouseY,target.width,0),distance(mouseX,mouseY,0,target.height),distance(mouseX,mouseY,target.width,target.height)) var radius = Math.max(distance(mouseX,mouseY,0,0),distance(mouseX,mouseY,target.width,0),distance(mouseX,mouseY,0,target.height),distance(mouseX,mouseY,target.width,target.height))
target.grabToImage(function(result) { reveal.start(reveal.width*Screen.devicePixelRatio,reveal.height*Screen.devicePixelRatio,Qt.point(mouseX,mouseY),radius)
img_cache.source = result.url }
canvas.requestPaint() }
changeDark()
canvas.centerX = mouseX function changeDark(){
canvas.centerY = mouseY if(FluTheme.dark){
anim_radius.enabled = false FluTheme.darkMode = FluDarkMode.Light
canvas.radius = 0 }else{
anim_radius.enabled = true FluTheme.darkMode = FluDarkMode.Dark
canvas.radius = canvas.maxRadius
},canvas.canvasSize)
} }
} }

View File

@ -1,6 +1,47 @@
#include "CircularReveal.h" #include "CircularReveal.h"
#include <QGuiApplication>
#include <QQuickItemGrabResult>
#include <QPainterPath>
CircularReveal::CircularReveal() CircularReveal::CircularReveal(QQuickItem* parent) : QQuickPaintedItem(parent)
{ {
_anim = new QPropertyAnimation(this, "radius", this);
_anim->setDuration(333);
_anim->setEasingCurve(QEasingCurve::OutCubic);
connect(_anim, &QPropertyAnimation::finished,this,[=](){
setVisible(false);
});
connect(this,&CircularReveal::radiusChanged,this,[=](){
update();
});
}
void CircularReveal::paint(QPainter* painter)
{
painter->save();
painter->drawImage(QRect(0, 0, static_cast<int>(width()), static_cast<int>(height())), _source);
QPainterPath path;
path.moveTo(_center.x(),_center.y());
path.addEllipse(QPointF(_center.x(),_center.y()), _radius, _radius);
painter->setCompositionMode(QPainter::CompositionMode_Clear);
painter->fillPath(path, Qt::black);
painter->restore();
}
void CircularReveal::start(int w,int h,const QPoint& center,int radius){
_anim->setStartValue(0);
_anim->setEndValue(radius);
_center = center;
_grabResult = _target->grabToImage(QSize(w,h));
connect(_grabResult.data(), &QQuickItemGrabResult::ready, this, &CircularReveal::handleGrabResult);
}
void CircularReveal::handleGrabResult(){
_grabResult.data()->image().swap(_source);
update();
setVisible(true);
Q_EMIT imageChanged();
_anim->start();
} }

View File

@ -2,15 +2,28 @@
#define CIRCULARREVEAL_H #define CIRCULARREVEAL_H
#include <QQuickItem> #include <QQuickItem>
#include <QQuickPaintedItem>
#include <QPainter>
#include <QPropertyAnimation>
#include "src/stdafx.h"
class CircularReveal : public QQuickItem class CircularReveal : public QQuickPaintedItem
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY_AUTO(QQuickItem*,target)
Q_PROPERTY_AUTO(int,radius)
public: public:
CircularReveal(); CircularReveal(QQuickItem* parent = nullptr);
void paint(QPainter* painter) override;
signals:
Q_INVOKABLE void start(int w,int h,const QPoint& center,int radius);
Q_SIGNAL void imageChanged();
Q_SLOT void handleGrabResult();
private:
QImage _source;
QPropertyAnimation* _anim;
QPoint _center;
QSharedPointer<QQuickItemGrabResult> _grabResult;
}; };
#endif // CIRCULARREVEAL_H #endif // CIRCULARREVEAL_H