Qt动画之鼠标水滴点击效果

一、简述

前几天在群里看见有个小伙伴用的一款gif录屏软件有一个类似水滴的点击效果。于是想了想,便开始了Code。思路也很简单,就是借助Qt的动画类QVariantAnimation然后不断重绘达到点击的动画效果,先看一下效果图。

Qt动画之鼠标水滴点击效果_第1张图片

Qt动画之鼠标水滴点击效果_第2张图片

二、代码之路

WaterDrop.h

#include 
#include 

class WaterDrop : public QWidget
{
    Q_OBJECT

public:
    WaterDrop(QWidget *parent = Q_NULLPTR);
    ~WaterDrop();
    void show();
    void move(const QPoint &point);
    void setColor(QColor color);

private:
    void paintEvent(QPaintEvent *event);
public slots:
    void onRaduisChanged(QVariant value);

private:
    QVariantAnimation* m_waterDropAnimation;
    // 水滴变化的半径;
    int m_animationRadius;
    // 水滴的颜色;
    QColor m_waterDropColor;
};

WaterDrop.cpp

#include "WaterDrop.h"
#include 

// 水滴的半径;
#define WATER_DROP_RADIUS 15

WaterDrop::WaterDrop(QWidget *parent)
    : QWidget(parent)
    , m_waterDropAnimation(NULL)
    , m_animationRadius(0)
    , m_waterDropColor(QColor(255, 120, 0, 150))    // 默认为橘黄色;
{
    this->setFixedSize(QSize(WATER_DROP_RADIUS * 2, WATER_DROP_RADIUS *2));
    this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
    this->setAttribute(Qt::WA_TranslucentBackground);

    // 控件显示完关闭后自动删除;
    this->setAttribute(Qt::WA_DeleteOnClose);

    m_waterDropAnimation = new QVariantAnimation(this);
}

WaterDrop::~WaterDrop()
{
}

void WaterDrop::move(const QPoint &point)
{
    // 这里要把鼠标点击的点转换为圆心点坐标;
    QPoint translatePoint = point - QPoint(WATER_DROP_RADIUS, WATER_DROP_RADIUS);
    __super::move(translatePoint);
}

void WaterDrop::show()
{
    __super::show();
    // 通过动画类不断进行重绘;
    m_waterDropAnimation->setStartValue(0);
    m_waterDropAnimation->setEndValue(WATER_DROP_RADIUS);
    m_waterDropAnimation->setDuration(350);

    connect(m_waterDropAnimation, &QVariantAnimation::valueChanged, this, &WaterDrop::onRaduisChanged);
    connect(m_waterDropAnimation, &QVariantAnimation::finished, this, &WaterDrop::close);
    m_waterDropAnimation->start();

}
// 设置水滴的颜色;
void WaterDrop::setColor(QColor color)
{
    m_waterDropColor = color;
}
// 绘制鼠标的水滴点击效果;
void WaterDrop::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::NoPen);
    painter.setBrush(QBrush(m_waterDropColor));

    // 思路就是先绘制一个固定大小的圆A,然后绘制同一圆心的透明的圆B,然后通过动画类是圆B的半径从0增长到WATER_DROP_RADIUS,以致覆盖固定的圆A;
    QPainterPath waterDropPath;
    waterDropPath.addEllipse(QPoint(WATER_DROP_RADIUS, WATER_DROP_RADIUS), WATER_DROP_RADIUS, WATER_DROP_RADIUS);
    QPainterPath hidePath;
    hidePath.addEllipse(QPoint(WATER_DROP_RADIUS, WATER_DROP_RADIUS), m_animationRadius, m_animationRadius);

    waterDropPath -= hidePath;
    painter.drawPath(waterDropPath);
}

void WaterDrop::onRaduisChanged(QVariant value)
{
    // 不断增加圆B的半径值,并重绘;
    m_animationRadius = value.toInt();
    update();
}

测试代码

// 新建一窗口类,重写mousePressEvent事件即可;
void MyWidget::mousePressEvent(QMouseEvent *event)
{
    QPoint cursorPos = event->pos();
    qDebug() << "mousePressEvent" << cursorPos;

    WaterDrop* waterDrop = new WaterDrop();
    waterDrop->move(this->mapToGlobal(cursorPos));
    waterDrop->setColor(Qt::green);
    waterDrop->show();
}

后续会继续分享Qt动画类做出的一些动画特效,敬请期待哈O(∩_∩)O!

支持一下,请点个赞吧!!!

代码下载

Qt动画之鼠标水滴点击效果

你可能感兴趣的:(Qt)