利用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_())

运行结果如下:

利用PyQt5模拟实现网页鼠标移动特效

来源: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
  • asp之家 网络编程 m.aspxhome.com