前文链接:QGraphicsView实现简易地图16『爆炸效果』
模仿水波荡漾时的涟漪效果,参考了echarts中的散点图
支持设置散点大小、颜色、涟漪线条宽度。
动态演示效果
静态展示图片
核心代码
#pragma once
#include "../AbstractGeoItem.h"
#include "DataStruct/GeoData.h"
/*
* 散点效果-静态
*/
class EffectScatterItem : public AbstractGeoItem
{
public:
explicit EffectScatterItem(const GeoCoord &geoCoord, int radius, QGraphicsItem *parent = nullptr);
~EffectScatterItem();
// 设置百分比(值:0-1)
void setPercent(double percent);
// 获取百分比
double percent();
// 设置颜色
void setColor(QColor color);
// 设置涟漪线宽
void setRippleWidth(double width);
protected:
virtual QRectF boundingRect() const override;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
private:
int m_radius; // 半径(单位:像素)
double m_percent; // 每条涟漪扩散百分比
double m_ripplesWidth; // 涟漪线宽
QColor m_color; // 颜色
};
#include "EffectScatterItem.h"
#include <QPainter>
EffectScatterItem::EffectScatterItem(const GeoCoord &geoCoord, int radius, QGraphicsItem *parent /*= nullptr*/)
: AbstractGeoItem(parent)
{
setZValue(302);
setGeoPos(geoCoord.lon, geoCoord.lat);
m_radius = radius;
m_percent = 0;
m_ripplesWidth = 1.5;
m_color = Qt::white;
}
EffectScatterItem::~EffectScatterItem()
{
}
void EffectScatterItem::setPercent(double percent)
{
m_percent = percent;
update();
}
double EffectScatterItem::percent()
{
return m_percent;
}
void EffectScatterItem::setColor(QColor color)
{
m_color = color;
update();
}
void EffectScatterItem::setRippleWidth(double width)
{
m_ripplesWidth = width;
update();
}
QRectF EffectScatterItem::boundingRect() const
{
return QRectF(-m_radius, -m_radius, 2 * m_radius, 2 * m_radius);
}
void EffectScatterItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->setPen(Qt::NoPen);
painter->setBrush(m_color);
painter->setRenderHint(QPainter::Antialiasing);
painter->drawEllipse(QPointF(0, 0), m_radius * 0.4, m_radius * 0.4);
painter->setBrush(Qt::NoBrush);
for (int i = 1; i <= 3; ++i)
{
QColor color = m_color;
color.setAlphaF((4 - i - m_percent) / 3);
painter->setPen(QPen(color, m_ripplesWidth));
double radius = m_radius * (0.4 + (i - 1 + m_percent) * 0.2);
painter->drawEllipse(QPointF(0, 0), radius, radius);
}
}