QGraphicsView实现简易地图19『迁徙图』

模仿echarts的迁徙图效果
用到了前2篇制作的散点(涟漪效果)和两年前的路径动画类;然尾迹效果未依附路径,有待优化。
动态演示效果

静态展示图片
在这里插入图片描述

核心代码

#pragma once
#include "Item/AbstractGeoItem.h"
#include "DataStruct/GeoData.h"

/*
 * 迁徙图-移动图元
 */

class QWHAnimationPath;

class MigrationMoveItem : public AbstractGeoItem
{
public:
	explicit MigrationMoveItem(const GeoCoord &center, const GeoCoord &target, QGraphicsItem *parent = nullptr);
	~MigrationMoveItem();

	// 更新地理位置
	virtual void updateGeoPos();
	// 设置路径位置百分比
	void setPercent(qreal percent);

protected:
	virtual QRectF boundingRect() const override;
	virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;

private:
	void updatePath();

private:
	GeoCoord m_targetPos;
	QWHAnimationPath *m_animatePath;
};
#include "MigrationMoveItem.h"
#include <QPainterPath>
#include <QPainter>
#include <QtMath>
#include <QLinearGradient>
#include "Utility/QWHAnimationPath.h"

MigrationMoveItem::MigrationMoveItem(const GeoCoord &center, const GeoCoord &target, QGraphicsItem *parent /*= nullptr*/)
	: AbstractGeoItem(parent)
{
	setZValue(302);
	m_lon = center.lon;
	m_lat = center.lat;
	m_targetPos = target;

	m_animatePath = new QWHAnimationPath(false);
	m_animatePath->setType(QWHAnimationPath::SLOPE);
	m_animatePath->setTarget(QWHAnimationPath::ITEM);
	m_animatePath->setItem(this);
	updatePath();
}

MigrationMoveItem::~MigrationMoveItem()
{

}

void MigrationMoveItem::updateGeoPos()
{
	updatePath();
}

void MigrationMoveItem::setPercent(qreal percent)
{
	m_animatePath->setCurPercent(percent);
}

QRectF MigrationMoveItem::boundingRect() const
{
	return QRectF(-20, -20, 40, 100);
}

void MigrationMoveItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
	// 飞机
	QPainterPath path;
	path.moveTo(0, -20);
	path.lineTo(-4, -16);
	path.lineTo(-4, -4);
	path.lineTo(-20, 4);
	path.lineTo(-4, 4);
	path.lineTo(-4, 16);
	path.lineTo(-8, 20);
	
	path.lineTo(8, 20);
	path.lineTo(4, 16);
	path.lineTo(4, 4);
	path.lineTo(20, 4);
	path.lineTo(4, -4);
	path.lineTo(4, -16);
	path.closeSubpath();

	painter->setPen(Qt::NoPen);
	painter->setBrush(Qt::green);
	painter->drawPath(path);

	// 尾迹
	QPainterPath path2;
	path2.moveTo(-4, 20);
	path2.lineTo(0, 60);
	path2.lineTo(0, 60);
	path2.lineTo(4, 20);

	QLinearGradient lg(0, 20, 0, 60);
	lg.setColorAt(0, Qt::white);
	lg.setColorAt(1, Qt::transparent);
	painter->setBrush(lg);
	painter->drawPath(path2);
}

void MigrationMoveItem::updatePath()
{
	QPainterPath path;

	QPointF centerPos = sceneCoordFromGeoCoord(m_lon, m_lat);
	QPointF targetPos = sceneCoordFromGeoCoord(m_targetPos.lon, m_targetPos.lat);
	QPointF pos = targetPos - centerPos;

	double k = qAtan2(-pos.y(), pos.x());
	double cx = 0.5 * (centerPos.x() + targetPos.x());
	double cy = 0.5 * (centerPos.y() + targetPos.y());
	double ctrlx = cx - qCos(M_PI / 2 - k) * 70;
	double ctrlY = cy - qSin(M_PI / 2 - k) * 70;

	path.moveTo(centerPos);
	path.quadTo(QPointF(ctrlx, ctrlY), targetPos);
	m_animatePath->setPath(path);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮生卍流年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值