利用PyQt5模拟实现网页鼠标移动特效
作者:Vertira 时间:2022-11-17 10:46:01
核心代码:
from random import random
from time import time
from PyQt5.QtCore import QPropertyAnimation, QObject, pyqtProperty, QEasingCurve,\
Qt, QRectF, pyqtSignal
from PyQt5.QtGui import QColor, QPainterPath, QPainter
from PyQt5.QtWidgets import QWidget
__Author__ = """By: Irony
QQ: 892768447
Email: 892768447@qq.com"""
__Copyright__ = 'Copyright (c) 2018 Irony'
__Version__ = 1.0
try:
import pointtool # @UnusedImport @UnresolvedImport
getDistance = pointtool.getDistance
findClose = pointtool.findClose
except:
import math
def getDistance(p1, p2):
return math.pow(p1.x - p2.x, 2) + math.pow(p1.y - p2.y, 2)
def findClose(points):
plen = len(points)
for i in range(plen):
closest = [None, None, None, None, None]
p1 = points[i]
for j in range(plen):
p2 = points[j]
dte1 = getDistance(p1, p2)
if p1 != p2:
placed = False
for k in range(5):
if not placed:
if not closest[k]:
closest[k] = p2
placed = True
for k in range(5):
if not placed:
if dte1 < getDistance(p1, closest[k]):
closest[k] = p2
placed = True
p1.closest = closest
class Target:
def __init__(self, x, y):
self.x = x
self.y = y
class Point(QObject):
valueChanged = pyqtSignal()
def __init__(self, x, ox, y, oy, *args, **kwargs):
super(Point, self).__init__(*args, **kwargs)
self.__x = x
self._x = x
self.originX = ox
self._y = y
self.__y = y
self.originY = oy
# 5个闭合点
self.closest = [0, 0, 0, 0, 0]
# 圆半径
self.radius = 2 + random() * 2
# 连线颜色
self.lineColor = QColor(156, 217, 249)
# 圆颜色
self.circleColor = QColor(156, 217, 249)
def initAnimation(self):
# 属性动画
if not hasattr(self, 'xanimation'):
self.xanimation = QPropertyAnimation(
self, b'x', self, valueChanged=self.valueChanged.emit,
easingCurve=QEasingCurve.InOutSine)
self.yanimation = QPropertyAnimation(
self, b'y', self, valueChanged=self.valueChanged.emit,
easingCurve=QEasingCurve.InOutSine,
finished=self.updateAnimation)
self.updateAnimation()
def updateAnimation(self):
self.xanimation.stop()
self.yanimation.stop()
duration = (1 + random()) * 1000
self.xanimation.setDuration(duration)
self.yanimation.setDuration(duration)
self.xanimation.setStartValue(self.__x)
self.xanimation.setEndValue(self.originX - 50 + random() * 100)
self.yanimation.setStartValue(self.__y)
self.yanimation.setEndValue(self.originY - 50 + random() * 100)
self.xanimation.start()
self.yanimation.start()
@pyqtProperty(float)
def x(self):
return self._x
@x.setter
def x(self, x):
self._x = x
@pyqtProperty(float)
def y(self):
return self._y
@y.setter
def y(self, y):
self._y = y
class Window(QWidget):
def __init__(self, *args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
self.setMouseTracking(True)
self.resize(800, 600)
self.points = []
self.target = Target(self.width() / 2, self.height() / 2)
self.initPoints()
def paintEvent(self, event):
super(Window, self).paintEvent(event)
painter = QPainter()
painter.begin(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.fillRect(self.rect(), Qt.black)
self.animate(painter)
painter.end()
def mouseMoveEvent(self, event):
super(Window, self).mouseMoveEvent(event)
# 鼠标移动时更新xy坐标
self.target.x = event.x()
self.target.y = event.y()
self.update()
def initPoints(self):
t = time()
self.points.clear()
# 创建点
stepX = self.width() / 20
stepY = self.height() / 20
for x in range(0, self.width(), int(stepX)):
for y in range(0, self.height(), int(stepY)):
ox = x + random() * stepX
oy = y + random() * stepY
point = Point(ox, ox, oy, oy)
point.valueChanged.connect(self.update)
self.points.append(point)
print(time() - t)
t = time()
# 每个点寻找5个闭合点
findClose(self.points)
print(time() - t)
def animate(self, painter):
for p in self.points:
# 检测点的范围
value = abs(getDistance(self.target, p))
if value < 4000:
# 其实就是修改颜色透明度
p.lineColor.setAlphaF(0.3)
p.circleColor.setAlphaF(0.6)
elif value < 20000:
p.lineColor.setAlphaF(0.1)
p.circleColor.setAlphaF(0.3)
elif value < 40000:
p.lineColor.setAlphaF(0.02)
p.circleColor.setAlphaF(0.1)
else:
p.lineColor.setAlphaF(0)
p.circleColor.setAlphaF(0)
# 画线条
if p.lineColor.alpha():
for pc in p.closest:
if not pc:
continue
path = QPainterPath()
path.moveTo(p.x, p.y)
path.lineTo(pc.x, pc.y)
painter.save()
painter.setPen(p.lineColor)
painter.drawPath(path)
painter.restore()
# 画圆
painter.save()
painter.setPen(Qt.NoPen)
painter.setBrush(p.circleColor)
painter.drawRoundedRect(QRectF(
p.x - p.radius, p.y - p.radius, 2 * p.radius, 2 * p.radius), p.radius, p.radius)
painter.restore()
# 开启动画
p.initAnimation()
if __name__ == '__main__':
import sys
import cgitb
sys.excepthook = cgitb.enable(1, None, 5, '')
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())
运行结果如下:
来源:https://blog.csdn.net/Vertira/article/details/123555880
标签:PyQt5,鼠标,特效
0
投稿
猜你喜欢
python进阶教程之循环相关函数range、enumerate、zip
2022-07-24 04:04:37
不知道这5种下划线的含义,你就不算真的会Python!
2021-02-03 14:38:26
python字典排序浅析介绍
2022-01-30 17:45:00
Python中缓存lru_cache的基本介绍和讲解
2021-09-30 08:23:08
Python datetime模块的使用示例
2022-10-20 22:33:39
ie7空格的间距要比ie6/firefox/opera的都要大
2008-05-24 16:54:00
PyTorch上搭建简单神经网络实现回归和分类的示例
2022-08-02 04:49:42
sql server如何利用开窗函数over()进行分组统计
2024-01-16 01:55:36
python 实时遍历日志文件
2021-03-30 09:26:20
使用python爬取微博数据打造一颗“心”
2022-05-28 22:30:09
python 实现两个npy档案合并
2022-08-20 13:29:55
Python实现PING命令的示例代码
2022-01-10 09:19:15
非常酷炫的Bootstrap图片轮播动画
2024-04-23 09:16:34
Echarts基本入门之柱状图、折线图通用配置
2024-04-28 09:37:10
python爬取微信公众号文章图片并转为PDF
2021-02-02 06:53:31
Python打工人必备之windows倒计时锁屏功能的实现
2021-01-18 04:21:21
Python爬虫Scrapy框架CrawlSpider原理及使用案例
2023-12-23 07:41:55
SQL中的开窗函数(窗口函数)
2024-01-24 09:59:43
typescript常见高级技巧总结
2024-05-08 10:10:10
python实现定时发送qq消息
2021-08-17 00:10:34