仿IOS桌面悬浮球(支持拖拽、自动吸附、自动改变透明度与点击、兼容PC端与移动端)
使用 pointerdown/pointermove/pointerup 实现仿IOS桌面悬浮球效果,支持拖拽、指定拖拽选对容器,指定拖拽安全区、自动吸附、自动改变透明度与点击,兼容PC端与移动端。
效果展示

https://code.juejin.cn/pen/7423757568268304421
代码实现
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>* {margin: 0;padding: 0;box-sizing: border-box;}#app {width: 40px;height: 40px;background-color: rgba(0, 0, 0, 0.15);position: absolute;left: 50px;top: 50px;cursor: pointer;user-select: none;/** 处理移动端只能小范围拖动 */touch-action: none;border-radius: 50%;/** 处理移动端点击蓝色背景 */-webkit-tap-highlight-color: transparent;}#app::before,#app::after {content: '';display: block;width: 120%;height: 120%;border-radius: 50%;background-color: rgba(0, 0, 0, 0.15);position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);}#app::after {width: 80%;height: 80%;}.parent {width: 50vw;height: 50vh;background-color: #f1f1f1;}</style>
</head><body><div class="parent"><div id="app"></div></div><script>const initDrag = (app, options = {}) => {if (!app) returnconst {gaps = [10, 10], // 左右间距和上下间距(安全区)relative = 'window', // 相对容器 window | parentautoAdsorb = true, // 是否自动吸附autoAlpha = true, // 是否自动改变透明度onClick // 点击事件} = optionslet isPointerDown = falseconst parentRect = app.parentElement.getBoundingClientRect()const parentWidth = parentRect.widthconst parentHeight = parentRect.heightlet maxLeft = 0let maxTop = 0if (relative === 'parent') {maxLeft = ((parentWidth || window.innerWidth) - app.clientWidth) - gaps[0]maxTop = ((parentHeight || window.innerHeight) - app.clientHeight) - gaps[1]} else {maxLeft = window.innerWidth - app.clientWidth - gaps[0]maxTop = window.innerHeight - app.clientHeight - gaps[1]}let startLeft, startTop; // 记录开始位置app.addEventListener('pointerdown', function (e) {isPointerDown = trueapp.style.transition = 'none'app.style.opacity = 1startLeft = e.clientX;startTop = e.clientY;});app.addEventListener('pointermove', function (e) {app.setPointerCapture(e.pointerId)if (isPointerDown) {const left = app.getBoundingClientRect().leftconst top = app.getBoundingClientRect().toplet newLeft = e.clientX - leftlet newTop = e.clientY - toplet movedLeft = newLeft + left - app.clientWidth / 2let movedTop = newTop + top - app.clientHeight / 2// 限制上、左移出边界(默认边界为窗口宽高)movedLeft = Math.max(gaps[0], movedLeft)movedTop = Math.max(gaps[0], movedTop)// 限制下、右移出边界(默认边界为窗口宽高)movedLeft = Math.min(movedLeft, maxLeft)movedTop = Math.min(movedTop, maxTop)app.style.left = movedLeft + 'px'app.style.top = movedTop + 'px'}});// 自动降低透明度let autoAlphaTimer = nullconst handleAutoAlpha = () => {autoAlphaTimer && clearTimeout(autoAlphaTimer)autoAlphaTimer = setTimeout(() => {app.style.opacity = 0.7}, 1000)}// 自动吸附let autoAdsorbTimer = nullconst handleAutoAdsorb = () => {autoAdsorbTimer && clearTimeout(autoAdsorbTimer)autoAdsorbTimer = setTimeout(() => {const left = app.getBoundingClientRect().leftconst movedLeft = left > maxLeft / 2 ? maxLeft : gaps[0]app.style.transition = 'all 300ms ease-in-out'app.style.left = movedLeft + 'px'autoAlpha && handleAutoAlpha()}, 100)}app.addEventListener('pointerup', function (e) {isPointerDown = false// 判断是否为点击事件const endX = e.clientX;const endY = e.clientY;const distance = Math.sqrt((endX - startLeft) ** 2 + (endY - startTop) ** 2);// 如果移动距离小于 5 像素,则认为是点击if (distance < 5) {app.style.transition = 'none';app.style.opacity = 1;app.style.left = startLeft - app.clientWidth / 2 + 'px'app.style.top = startTop - app.clientHeight / 2 + 'px'onClick && onClick()} else {if (autoAdsorb) {handleAutoAdsorb()} else if (autoAlpha) {handleAutoAlpha()}}});}initDrag(document.getElementById('app'), {onClick: () => {alert('click')}})</script>
</body></html>
相关文章:
仿IOS桌面悬浮球(支持拖拽、自动吸附、自动改变透明度与点击、兼容PC端与移动端)
使用 pointerdown/pointermove/pointerup 实现仿IOS桌面悬浮球效果,支持拖拽、指定拖拽选对容器,指定拖拽安全区、自动吸附、自动改变透明度与点击,兼容PC端与移动端。 效果展示 https://code.juejin.cn/pen/7423757568268304421 代码实现 …...
智谱开放平台API调用解析
一、什么是智谱AI 智谱AI成立于2019年,由清华大学计算机系知识工程实验室的技术成果转化而来,是一家致力于人工智能技术研发和应用的公司。智谱致力于打造新一代认知智能大模型,专注于做大模型的中国创新。 二、智谱开放平台API调用 官方文…...
Linux中定时删除10天前的日志文件
例如:删除/data/log/目录下所有10天前的.log文件 find /data/log/ -type f -name "*.log" -mtime 10 -exec rm -f {} \;只查看要删除的文件有哪些,不真正删除文件 logfiles$(find /data/log/ -type f -name "*.log" -mtime 10) ec…...
贝壳Android面试题及参考答案
详细说Final关键字 在编程语言中,final关键字具有重要的作用。以下为你详细介绍final关键字: 一、final关键字的主要作用 修饰变量 当final修饰基本数据类型变量时,该变量的值一旦被初始化就不能再被改变。例如:final int num = 10;num = 20; // 这会导致编译错误当final修…...
基于vue的酒店预订管理系统(源码+定制+开发)
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...
FreeRTOS——TCB任务控制块、任务句柄、任务栈详解
任务控制块结构体 任务控制块是 FreeRTOS 中用于描述和管理任务的数据结构,包含了任务的状态、优先级、堆栈等信息。 TCB_t的全称为Task Control Block,也就是任务控制块,这个结构体包含了一个任务所有的信息,它的定义以及相关变…...
【STM32单片机_(HAL库)】4-5-2【定时器TIM】【感应开关盖垃圾桶项目】HC-SR04超声波模块实验
1.硬件 STM32单片机最小系统HC-SR04超声波模块 2.软件 hcsr04驱动文件添加main.c程序 #include "sys.h" #include "delay.h" #include "led.h" #include "uart1.h" #include "hcsr04.h"int main(void) {HAL_Init(); …...
安全网络架构
网络安全解决方案是指通过一系列技术和措施来保护网络系统和数据的安全。它涉及多个方面,包括网络设备的防护、数据的加密和备份、安全策略的制定和执行等。以下是一些常见的网络安全解决方案: 防火墙:防火墙是一种硬件或软件设备,…...
【万字长文】Word2Vec计算详解(二)Skip-gram模型
【万字长文】Word2Vec计算详解(二)Skip-gram模型 写在前面 本篇介绍Word2Vec中的第二个模型Skip-gram模型 【万字长文】Word2Vec计算详解(一)CBOW模型 markdown行 9000 【万字长文】Word2Vec计算详解(二)S…...
随机掉落的项目足迹:解决TypeError: Cannot read properties of undefined (reading ‘push‘)报错
问题引入 下面是request.js中请求拦截器相关的代码 但是运行时却出现了报错 问题解决 useRouter() 是 Vue Router 提供的组合式 API,它只能在 Vue 组件的 setup() 函数中有效。如果在其他地方(例如 Axios 的拦截器中)调用它,可…...
ChatTTS 本地安装和测试
Ubuntu 22服务器,3.9/3.10都可以,但是 3.11不可以 sudo apt install python3.10 apt install python3.10 python3.10-dev #ubuntu 22 安装python3.10对应的pip3.10 # 下载 get-pip.py curl -sS https://bootstrap.pypa.io/get-pip.py -o get-pip.py # 使…...
[Leetcode] 560 Subarray Sum Equals K
题意:给定一个数组求连续的子数组的和为k的有几个 Input: nums [1,1,1], k 2 Output: 2 https://leetcode.com/problems/subarray-sum-equals-k/description/ 首先思考1.因为是subarray sum前缀和很容易想到,那问题就转化成preSum[i] preSum[j] - k…...
TCL Android面试题大全及参考答案
能谈谈Jetpack组件吗? Jetpack 是一套用于 Android 开发的工具和组件库,它可以帮助开发者更高效地构建高质量的 Android 应用。 一、主要组件分类 架构组件: ViewModel:负责存储和管理与界面相关的数据,当屏幕旋转或配置发生变化时,ViewModel 可以帮助保存数据,避免数据…...
JVM错误:OutOfMemoryError: GC overhead limit exceeded
OutOfMemoryError: GC overhead limit exceeded 在Window服务器上跑一个项目,无意中出现服务访问不了,查看日志文档,第一次遇到了这个异常信息。 1. 错误含义 OutOfMemoryError: GC overhead limit exceeded 是 JVM 中的一种错误ÿ…...
Unity网络开发 - C#开源网络通信库PESocket的使用
概述 在现代多人在线游戏中,稳定且高效的网络通信是确保游戏体验的关键。本文将探讨如何利用C#开源网络通信库PESocket来构建一个简单的Unity客户端与.NET控制台服务器之间的实时消息传递系统。通过本例,读者不仅能够了解PESocket的基本用法,…...
【完-网络安全】Shell与脚本
文章目录 1.CLI与GUI2.终端和Shell2.1 Shell 壳层2.2 终端2.3 终端和Shell区别3.标准流 4.PowerShell4.1 管理员与非管理员4.2 指令4.3 重定向4.4 管道 5.环境变量5.1 影响范围5.2环境变量的作用5.3 常见的环境变量 6.脚本 1.CLI与GUI CLI命令行界面(CLl,Command Line Interfa…...
磁盘标签和分区标签
在Windows中,我们为分区命名,那个名字就是「分区标签」。所以说“分区标签”是给分区的一个名字。 「磁盘标签」其实是我们经常说的「分区表」,比如MBR、GPT等等。而「分区标签」,虽然叫做“分区”标签,但它则是文件系…...
关于摩托车一键启动无钥匙进入、智能科技创新
摩托车一键启动无钥匙进入功能 一、工作原理 摩托车的一键启动无钥匙进入功能采用了世界最先进的RFID无线射频技术和最先进的车辆身份编码识别系统,率先应用小型化、小功率射频天线的开发方案,并成功融合了遥控系统和无钥匙系统,沿用了传统…...
怎么找矩阵系统,怎么源码搭建,源头技术开发需要哪些支持
一、引言 在进行矩阵系统源码搭建时,选择合适的工具至关重要。正确的工具选择不仅可以提高开发效率,还能确保系统的稳定性、可扩展性和性能。本文将探讨在矩阵系统源码搭建过程中如何选择合适的工具。 二、前端开发工具选择 前端框架 React:由…...
云原生化 - 工具镜像(简约版)
在微服务和云原生环境中,容器化的目标之一是尽可能保持镜像小型化以提高启动速度和减少安全风险。然而,在实际操作中,有时候需要临时引入一些工具来进行调试、监控或问题排查。Kubernetes提供了临时容器(ephemeral containers&…...
RWKV7-1.5B-g1a参数详解:为何默认top_p=0.3更适合中文生成?语言分布实证
RWKV7-1.5B-g1a参数详解:为何默认top_p0.3更适合中文生成?语言分布实证 1. 模型概述 rwkv7-1.5B-g1a是基于RWKV-7架构的多语言文本生成模型,特别适合中文场景下的基础问答、文案续写和简短总结任务。作为1.5B参数量的轻量级模型,…...
【限时公开】20年农业AI工程师压箱底的17条精度校验铁律:从田间采集到模型上线零容错实践手册
第一章:农业图像识别精度校验的底层逻辑与行业特殊性农业图像识别并非通用计算机视觉任务的简单迁移,其精度校验需直面田间场景固有的复杂性:光照剧烈波动、作物生长阶段连续变化、病斑形态高度异质、背景杂草与土壤纹理干扰显著。这些因素共…...
国产操作系统安全实战:用银河麒麟KYSEC防护关键文件的5种典型场景
国产操作系统安全实战:银河麒麟KYSEC防护关键文件的5种典型场景 在数字化转型浪潮中,企业核心数据资产的安全防护已成为技术团队的头等大事。想象一下:财务系统的敏感账目被误删、研发代码遭恶意篡改、数据库凭证意外泄露...这些场景轻则造成…...
Cursor Free VIP:突破AI编程助手限制的完整解决方案
Cursor Free VIP:突破AI编程助手限制的完整解决方案 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your trial…...
泛微E9流程表单转PDF/HTML实战:手把手教你集成档案系统(附完整代码)
泛微E9流程表单转PDF/HTML全流程开发指南:从原理到实战 在企业管理数字化转型的浪潮中,OA系统与档案系统的无缝对接已成为提升组织效能的刚需。作为国内主流的协同办公平台,泛微E9的流程表单承载着企业核心业务流程数据,如何将这些…...
节水灌溉物联网监控管理系统方案
对于部分水资源匮乏的地区,节水灌溉系统的应用对农业发展具有重要意义。该系统通过实时监测农田土壤湿度和气象条件,结合预设的灌溉计划和作物生长需求,精准控制灌溉设备的开启或关闭,有效避免了水资源浪费,显著提高了…...
OpenClaw技能开发入门:为nanobot镜像编写第一个插件
OpenClaw技能开发入门:为nanobot镜像编写第一个插件 1. 为什么需要自定义技能 当我第一次接触OpenClaw时,最让我惊喜的是它能够像人类一样操作电脑完成各种任务。但很快我发现,内置的基础技能并不能完全满足我的个性化需求。比如我需要定期…...
CentOS7快速部署Golang 1.22.2开发环境全攻略
1. 为什么选择CentOS7部署Golang 1.22.2 最近在帮团队搭建新的开发环境时,我发现很多同事还在用老旧的Golang版本。作为目前最稳定的Linux发行版之一,CentOS7依然是企业级开发环境的首选。而Golang 1.22.2作为2024年发布的最新稳定版,带来了不…...
Spatial Audio(空间音频)与多声道环绕声:从5.1到7.1的沉浸式体验升级
1. 从立体声到环绕声:音频技术的进化之路 记得我第一次在朋友家体验5.1声道家庭影院时,那种子弹从耳边呼啸而过的感觉让我彻底震撼了。这完全颠覆了我对"好音质"的认知——原来声音可以如此立体、如此真实。要理解现代的空间音频技术…...
【嵌入式Linux】Libmodbus RTU从源码到实战:基于i.MX6UL的工业通信移植指南
1. 为什么选择Libmodbus RTU在i.MX6UL上做工业通信? 在工业自动化领域,Modbus协议就像设备之间的"普通话",而RTU模式则是其中最省流量、最抗干扰的方言。我去年给一家工厂做设备改造时,发现他们的老式PLC和传感器清一色…...
