可移动框 弹窗 可拖拽的组件

news2024/11/24 5:53:19

电脑端:

<template>
  <div
    v-if="show"
    ref="infoBox"
    @mousedown.stop="mouseDownHandler"
    class="info-box"
    :style="styleObject"
  >
    <slot></slot>
  </div>
</template>
<script>
export default {
  name: "InfoBox",
  props: {
    width: {
      type: String,
      required: false,
      default: "29.9rem"
    },
    height: {
      type: String,
      required: false,
      default: "20.8rem"
    },
    show: {
      type: Boolean,
      // required: false,
      default: false
    }
  },
  data() {
    return {
      styleObject: {
        width: "400px",
        height: "300px"
      },
      // show: true,
      isMove: false
    };
  },
  mounted() {
    this.styleObject = {
      height: this.$props.height,
      width: this.$props.width
    };
  },
  methods: {
    mouseDownHandler(e) {
      const currentPosition = {
        x: this.$refs.infoBox.offsetLeft,
        y: this.$refs.infoBox.offsetTop
      };
      const startPosition = { x: e.clientX, y: e.clientY }; //获取当前点击位置
      console.log(currentPosition, startPosition);
      this.isMove = true;
      //注册鼠标移动事件
      document.addEventListener("mousemove", event_move => {
        if (!this.isMove) return;
        const offsetX = event_move.clientX - startPosition.x,
          offsetY = event_move.clientY - startPosition.y;
        // console.log(offsetX, offsetY);
        //修改弹框位置
        this.$refs.infoBox.style.left = `${currentPosition.x + offsetX}px`;
        this.$refs.infoBox.style.top = `${currentPosition.y + offsetY}px`;
      });
      //注册鼠标抬起事件
      document.addEventListener("mouseup", () => {
        this.isMove = false;
      });
    },
    mousemoveHandler() {},
    mouseUpHandler() {}
  }
};
</script>
<style lang="scss" scoped>
.info-box {
  // .box-size(400px,300px);
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  // background: red;
  // border: 1px solid #3374ac;
  z-index: 999999;
  .nav {
    padding: 5px 10px;
    height: 35px;
    justify-content: space-between;
    .title {
      user-select: none; //禁止选中标题文字
      padding: 0px 5px;
      font-family: "AliMaMa";
      font-style: italic;
      font-size: 18px;
      color: #cee9f5;
      background-image: linear-gradient(to top, #00c6ff, #8affd2);
      /* 线性渐变背景,方向向上 */
      -webkit-background-clip: text;
      /* 背景被裁剪成文字的前景色 */
      -webkit-text-fill-color: transparent;
      /* 文字填充颜色变透明 */
    }

    .close {
      font-size: 20px;
      cursor: pointer;

      &:hover {
        color: rgb(0, 201, 252);
      }
    }
  }
}
</style>

移动端:

<template>
  <div
    ref="drawable"
    :style="{left: left, top: top}"
    class="draggable-box"
    @touchstart="touchstart"
    @touchend="touchend"
    @touchmove="mousemove"
  >
    <slot />
    <!-- <div style="width:30px;height:30px;border:1px solid red;background:red">11111111111111111111</div> -->
  </div>
</template>
<script>
export default {
  name: "DrawableBox",
  props: {
    top: String,
    left: String,
    isOnlyLeft: Boolean,
    isOnlyRight: Boolean
  },
  data() {
    return {
      flag: false
    };
  },
  methods: {
    touchstart() {
      this.flag = true;
      // 禁用页面滚动条
      document.getElementById("app").style = "overflow: hidden;";
      this.$refs.drawable.style.transition = "none";
    },

    touchend() {
      this.flag = false;
      this.$refs.drawable.style.transition = "all 0.2s";
      document.getElementById("app").style = "overflow: auto;";
      let left = this.$refs.drawable.offsetLeft;
      let screenWidth = window.screen.width;
      let oWidth = this.$refs.drawable.offsetWidth;
      // 判断是回到左边还是右边
      // if (left + oWidth / 2 <= screenWidth / 2) {
      //   this.$refs.drawable.style.left = "0px";
      // } else {
      //   this.$refs.drawable.style.left = screenWidth - oWidth + "px";
      // }
    },

    mousemove(e) {
      // 禁止默认行为,防止在微信上打开和下拉冲突
      e.preventDefault();
      if (this.flag) {
        let clientY = e.targetTouches[0].clientY;
        let clientX = e.targetTouches[0].clientX;
        let offsetHeight = this.$refs.drawable.offsetHeight;
        let offsetWidth = this.$refs.drawable.offsetWidth;
        let top = clientY - offsetHeight / 2;
        let left = clientX - offsetWidth / 2;
        // 屏幕得宽度
        let screenWidth = window.screen.width;
        let screenHeight = window.screen.height;
        let maxTop = screenHeight - offsetHeight;
        let maxLeft = 0;
        const halfWidth = screenWidth / 2;
        if (this.isOnlyLeft) {
          maxLeft = halfWidth - offsetWidth / 2;
        } else {
          maxLeft = screenWidth - offsetWidth;
        }
        if (top <= 0) {
          top = 0;
        }
        if (top > maxTop) {
          top = maxTop;
        }
        if (this.isOnlyRight) {
          if (left <= halfWidth) {
            left = halfWidth;
          }
        } else {
          if (left <= 0) {
            left = 0;
          }
        }

        console.log(left, "left");
        console.log(maxLeft, "maxLeft maxLeft");

        left = left > maxLeft ? maxLeft : left;

        console.log(left, "left 后");
        this.$refs.drawable.style.top = top + "px";
        this.$refs.drawable.style.left = left + "px";
      }
    }
  }
};
</script>
<style lang="scss" scoped>
.draggable-box {
  position: fixed;
  z-index: 3000;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1258778.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring 中存储 Bean 的相关注解

Bean的存 IoC控制反转&#xff0c;就是将对象的控制权交给Spring的IOC容器&#xff0c;由IOC容器创建及管理对象。 也就是bean的存储 类注解:五大注解 Controller&#xff08;控制器存储&#xff09; Service&#xff08;服务存储&#xff09; Component&#xff08;组件存储…

Spring第二课响应的完全,如何理解前后端互联

目录 一、响应 Control,RestController 1.Controller的源码&#xff0c;代表什么意思 2.返回数据 Responsebody 3.返回HTML片段 4.返回JSON 5.那么假如我们使用集合会怎么样呢 设置状态码&#xff0c;虽然不影响展示&#xff0c;但是确实显示起来也就是401的情况。 2.我…

ECShop 4.x collection_listSQL注入

漏洞描述 ECShop是一款B2C独立网店系统&#xff0c;适合企业及个人快速构建个性化网上商店。系统是基于PHP语言及MYSQL数据库构架开发的跨平台开源程序 影响版本&#xff1a;ecshop4.0.7及以下 漏洞环境及利用 docker环境搭建 访问8080端口&#xff0c;数据库主机为mysql&a…

Spark---Master启动及Submit任务提交

一、Spark Master启动 1、Spark资源任务调度对象关系图 2、集群启动过程 Spark集群启动之后&#xff0c;首先调用$SPARK_HOME/sbin/start-all.sh&#xff0c;start-all.sh脚本中调用了“start-master.sh”脚本和“start-slaves.sh”脚本&#xff0c;在start-master.sh脚本中可…

LLM之Agent(二):BabyAGI的详细教程

BabyAGI是一个 AI 支持的任务管理系统&#xff08;Python脚本&#xff09;&#xff0c;使用 OpenAI 和 Pinecone API 创建, 优先级排序和执行任务。该系统背后的主要思想是基于先前任务的结果和预定义的目标创建任务。脚本然后使用 OpenAI 的自然语言处理&#xff08;NLP&#…

文献速递:超声影像人工智能专题文献分享

文献速递&#xff1a;超声影像人工智能专题文献分享 01 文献速递介绍 本文综述了超声影像组学在甲状腺疾病研究中的应用及其局限性。近年来&#xff0c;甲状腺疾病的发病率逐渐增加&#xff0c;传统超声是最关键的甲状腺成像方法之一&#xff0c;但仍存在一定局限性。超声影…

Syncovery Mac/win中文版:快速、方便的数据备份和同步工具

备份和同步数据是现代生活中不可或缺的任务。无论是个人用户还是企业用户&#xff0c;都需要一款可靠的工具来保护和同步他们的数据。Syncovery是一款备份数据和同步工具&#xff0c;它能够提供全面的数据保护和灵活的数据同步功能。 首先&#xff0c;Syncovery具有强大的备份…

每日一练:简易计算器

1.设计思路 创建一个简单的用户界面&#xff0c;可以使用 Python 的 Tkinter模块。在界面上放置按钮&#xff0c;每个按钮代表一个数字、运算符或其他功能。使用变量来追踪用户输入的表达式。在用户点击按钮时&#xff0c;更新表达式并在界面上显示。 当用户点击“”按钮时&am…

window关于下载anaconda 2023年以后的版本,jupyter notebook闪退,没有内核的问题

这种问题的解决办法&#xff1a; 下载anaconda较早版本&#xff0c;比如我下载的是&#xff1a;2022年5月的版本。 下载之后&#xff0c;打开jupyter好像也会没有内核和闪退。 下面解决步骤&#xff1a; 1.注意&#xff1a;打开anaconda powershell prompt 2.重点来了&#xf…

漏洞复现--致远 M3 反序列化 mobile_portal RCE

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

Uni-app智慧工地可视化信息云平台源码

智慧工地的核心是数字化&#xff0c;它通过传感器、监控设备、智能终端等技术手段&#xff0c;实现对工地各个环节的实时数据采集和传输&#xff0c;如环境温度、湿度、噪音等数据信息&#xff0c;将数据汇集到云端进行处理和分析&#xff0c;生成各种报表、图表和预警信息&…

支持向量机:Python实践

支持向量机&#xff08;Support Vector Machine&#xff0c;简称SVM&#xff09;是机器学习领域中一种常用的分类算法&#xff0c;其在处理线性可分和线性不可分问题上表现出色。Python作为一种广泛应用的编程语言&#xff0c;提供了众多强大的机器学习库和工具&#xff0c;使得…

Mysql数据库多表数据查询问题

1、背景 线上某个业务数据分表存储在10个子表中&#xff0c;现在需要快速按照条件&#xff08;比如时间范围&#xff09;筛选出所有的数据&#xff0c;主要是想做一个可视化的数据查询工具&#xff0c;给产研团队使用。 2、实践 注意&#xff1a;不要在线上真实数据库操作&am…

【JavaEE初阶】 博客系统项目--前端页面设计实现

文章目录 &#x1f332;主要内容&#x1f38d;预期效果&#x1f6a9;博客列表页效果&#x1f6a9;博客详情页&#x1f6a9;博客登录页&#x1f6a9;博客编辑页 &#x1f340;实现博客列表页&#x1f6a9;实现导航栏&#x1f388;页面主体部分 &#x1f384;实现博客详情页&…

无公网IP环境如何实现远程访问连接家里内网的威联通QNAP NAS

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

JAVA进阶之路JVM-1:jvm基本组成、java程序执行过程、java程序的跨平台、静态编译器、jvm执行方式

JVM基本组成 当线上系统突然宕机&#xff0c;系统无法访问&#xff0c;甚至直接OOM&#xff1b; 线上系统响应速度太慢&#xff0c;优化系统性能过程中发现CPU占用过高&#xff0c;原因也许是因为JVM的GC次数过于频繁 因此&#xff0c;新项目上线&#xff0c;需要设置JVM的各…

高精度基准电压源测试方法有哪些

高精度基准电压源是一种能够产生稳定、可控的电压信号的设备&#xff0c;广泛应用于科学研究、工业检测和仪器仪表校准等领域。为了保证电压信号的准确性和可靠性&#xff0c;在使用高精度基准电压源进行测试时&#xff0c;需要采取一系列的测试方法和技术手段。 校准和验证是使…

软著项目推荐 深度学习 植物识别算法系统

文章目录 0 前言2 相关技术2.1 VGG-Net模型2.2 VGG-Net在植物识别的优势(1) 卷积核&#xff0c;池化核大小固定(2) 特征提取更全面(3) 网络训练误差收敛速度较快 3 VGG-Net的搭建3.1 Tornado简介(1) 优势(2) 关键代码 4 Inception V3 神经网络4.1 网络结构 5 开始训练5.1 数据集…

AIGC文生图及工具产品简介

AIGC&#xff0c;全称是人工智能生成内容&#xff08;Artificial Intelligence Generated Content&#xff09;是继UGC&#xff08;用户生成内容&#xff09;&#xff0c;PGC&#xff08;平台生成内容&#xff09;后&#xff0c;利用人工智能技术&#xff0c;自动生成内容的生产…

无mac电脑生成uniapp云打包私钥证书的攻略

uniapp顾名思义是一个跨平台的开发工具&#xff0c;大部分uniapp的开发者&#xff0c;其实并没有mac电脑来开发&#xff0c;但是生成ios的证书&#xff0c;官网的教程却是需要mac电脑的&#xff0c;那么有没有办法无需mac电脑即可生成uniapp云打包的私钥证书呢&#xff1f; 下…