使用npm包js-web-screen-shot做网页截图,可以对截图加文字,箭头等等,类似于微信截图

<template>
  <div class="m-feedback-wrap" :style="{ top: `${feedbackHeight}px` }">
    <div class="m-feedback-icon-wrap">
      <el-tooltip
        class="item"
        effect="dark"
        content="内容"
        placement="left-end"
      >
        <span
          :class="[`icon iconfont icon-xiaoxi m-feedback-icon`]"
          @click="handleOpen"
          @mousedown="handleFeedbackDrag"
        ></span>
      </el-tooltip>
    </div>

    <el-dialog
      title="标题"
      :visible.sync="visible"
      width="1000px"
      append-to-body
      class="m-dialog m-dialog-feedback"
    >
      <div>
        <el-form ref="form" :model="form" :rules="rules" label-width="100px">
          <div class="m-feedback-row-wrap">
            <el-row>
              <el-col :span="24">
                <el-form-item label="问题描述" prop="describe">
                  <el-input type="textarea" :rows="5" v-model="form.describe" />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="24">
                <el-form-item label="附件" prop="attachment">
                  <el-upload
                    class="upload-demo m-feedback-upload"
                    action="https://jsonplaceholder.typicode.com/posts/"
                    :on-preview="handlePreview"
                    :on-remove="handleRemove"
                    :before-remove="beforeRemove"
                    multiple
                    :on-exceed="handleExceed"
                    :file-list="fileList"
                    list-type="picture"
                  >
                    <el-button size="small" type="primary">点击上传</el-button>
                    <el-button
                      size="small"
                      type="primary"
                      @click.stop="handleCapture2"
                      >截图</el-button
                    >

                    <div slot="tip" class="el-upload__tip">
                      只能上传jpg/png文件,且不超过5M
                    </div>
                  </el-upload>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
        </el-form>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handleSubmit">提交</el-button>
        <el-button @click="handleClose">取消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  Button,
  Tooltip,
  Dialog,
  Form,
  Row,
  Col,
  FormItem,
  Upload,
  Link,
  Input,
} from 'element-ui'

import html2canvas from 'html2canvas'
import ScreenShot from 'js-web-screen-shot'
import temp from './images/m-temp.jpg'
// import temp from '../../../bizapp/m-biz.jpg'
import temp2 from './images/m-temp2.jpg'

import './font/iconfont.css'
import './index.css'

let defaultFileList = [
  {
    name: 'food.jpg',
    url: temp,
  },
  {
    name: 'food2.jpg',
    url: temp2,
  },
]
export default {
  name: 'Feedback-Index',
  data() {
    return {
      visible: false,
      fileList: [...defaultFileList],
      form: {},
      // 表单校验
      rules: {
        title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
      },
      feedbackMouseY: 0,
      feedbackDragging: false,
      feedbackHeight: 200,
    }
  },
  components: {
    [Button.name]: Button,
    [Tooltip.name]: Tooltip,
    [Dialog.name]: Dialog,
    [Form.name]: Form,
    [Row.name]: Row,
    [Col.name]: Col,
    [FormItem.name]: FormItem,
    [Upload.name]: Upload,
    [Link.name]: Link,
    [Input.name]: Input,
  },
  mounted() {
    document.addEventListener('mousemove', this.handleMouseMove)
    document.addEventListener('mouseup', this.handleMouseUp)
  },
  methods: {
    handleCapture() {
      html2canvas(document.body).then(function (canvas) {
        document.body.appendChild(canvas)
      })
    },
    convertBase64UrlToBlob(urlData) {
      let bytes = window.atob(urlData.split(',')[1]) //去掉url的头,并转换为byte
      //处理异常,将ascii码小于0的转换为大于0
      let ab = new ArrayBuffer(bytes.length)
      let ia = new Uint8Array(ab)
      for (var i = 0; i < bytes.length; i++) {
        ia[i] = bytes.charCodeAt(i)
      }

      return new Blob([ab], {
        type: 'image/jpg',
      })
    },
    async handleCapture2() {
      this.visible = false
      setTimeout(() => {
        try {
          new ScreenShot({
            enableWebRtc: false,
            completeCallback: this.callback,
            triggerCallback: this.triggerCallback,
          })
        } catch (error) {
          console.log(error)
        }
      }, 500)
    },
    callback(value) {
      this.visible = true
      console.log(value)
      let file = this.convertBase64UrlToBlob(value.base64)
      console.log(file)
      this.fileList = [
        ...this.fileList,
        {
          name: `${Date.now()}.png`,
          //url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100',
          url: value.base64,
        },
      ]
    },
    triggerCallback() {
      this.visible = false
    },
    handleSubmit() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          console.log(this.form)
          this.visible = false

          this.$message({
            message: '成功',
            type: 'success',
          })
          this.$refs['form'].resetFields()
          this.fileList = [...defaultFileList]
        }
      })
    },
    handleClose() {
      this.visible = false
      this.$refs['form'].clearValidate()
      this.$refs['form'].resetFields()
      this.fileList = [...defaultFileList]
    },
    handleOpen() {
      this.visible = true
    },
    handleRemove(file, fileList) {
      console.log(file, fileList)
      this.fileList = [...fileList]
    },
    handlePreview(file) {
      console.log(file)
    },
    handleExceed(files, fileList) {
      this.$message.warning(
        `当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${
          files.length + fileList.length
        } 个文件`
      )
    },
    beforeRemove(file, fileList) {
      return this.$confirm(`确定删除这张图片吗?`, '提示', {
        type: 'warning',
        customClass: 'm-confirm',
      })
    },

    //#region 拖拽
    handleMouseMove(event) {
      if (this.feedbackDragging) {
        event.preventDefault()
        const deltaY = event.clientY - this.feedbackMouseY
        this.feedbackMouseY = event.clientY
        let tempFeedbackHeight = this.feedbackHeight + deltaY
        if (tempFeedbackHeight < 0) {
          tempFeedbackHeight = 0
        } else if (tempFeedbackHeight > window.innerHeight - 30) {
          tempFeedbackHeight = window.innerHeight - 30
        }

        this.feedbackHeight = tempFeedbackHeight
      }
    },
    handleMouseUp() {
      this.feedbackDragging = false
    },

    handleFeedbackDrag(event) {
      this.feedbackDragging = true
      this.feedbackMouseY = event.clientY
    },
    //#endregion
  },
}
</script>

<style></style>

我开发的chatgpt项目:

https://chat.xutongbao.top

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据分享】1929-2023年全球站点的逐年平均风速(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、能见度等指标&#xff0c;说到气象数据&#xff0c;最详细的气象数据是具体到气象监测站点的数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全球气象站…

文心一言 VS 讯飞星火 VS chatgpt (196)-- 算法导论14.3 4题

四、用go语言&#xff0c;给定一棵区间树 T 和一个区间 i &#xff0c;请描述如何在 O(min(n&#xff0c;klgn)) 时间内列出 T 中所有与 i 重叠的区间&#xff0c;其中 k 为输出的区间数。(提示:一种简单的方法是做若干次查询&#xff0c;并且在这些查询操作中修改树&#xff0…

springboot164党员教育和管理系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

初识NodeJS

本文主要基于极客时间《Nodejs开发实战》课程。 本篇&#xff08;一&#xff09;为课程的第二篇——技术预研篇。 什么是Nodejs? 来源官网&#xff1a; Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型&#x…

【网络技术】【Kali Linux】Nmap嗅探(二)多设备扫描

上期实验博文&#xff1a;&#xff08;一&#xff09;简单扫描 一、实验环境 本次实验进行Nmap多设备扫描&#xff0c;实验使用 Kali Linux 虚拟机&#xff08;扫描端&#xff09;、Ubuntu 22.04虚拟机&#xff08;被扫描端1&#xff09;、Ubuntu 18.04虚拟机&#xff08;被扫…

金融信贷风控业务详解

前言 Hi&#xff0c;大家好。今天我要根据以往的工作经验做一个全新的业务——金融风控、信贷风控等风控场景。带大家以全新的角度了解风控&#xff0c;包括风控信贷业务讲解、风控决策树、风控决策流、特征工程、三方数据对比和风控系统搭建等一系列知识。 早期的信贷风控做…

代码随想录算法训练营第30天| 51. N皇后、总结

51. N皇后 完成 思路&#xff1a; 如何用回溯法搜索二维棋盘是这道题目和之前不一样的地方&#xff0c;也是题目的难点。 在树形结构中&#xff0c;同层取同一行棋盘的不同列遍历。每递归一次就往下遍历一行。 代码 class Solution {List<List<String>> res n…

platform tree架构下i2c应用实例(HS3003)

目录 概述 1 探究platform tree下的i2c 1.1 platform tree下的i2c驱动 1.2 查看i2c总线下的设备 1.3 使用命令读写设备寄存器 2 认识HS3003 2.1 HS3003特性 2.2 HS3003寄存器 2.2.1 温湿度数据寄存器 2.2.2 参数寄存器 2.2.3 一个参数配置Demo 2.3 温湿度值转换 2.…

FANUC机器人外部远程启动的相关参数设置示例

FANUC机器人外部远程启动的相关参数设置示例 如下图所示,在MENU---设置---选择程序中,设置程序选择模式:RSR(这个根据自己实际使用的自动启动方式来决定,你用RSR选RSR,用PNS就选PNS), 自动运行开始方法:选择UOP,即RSR1-RSR8的启动信号分别对应UI9-UI16, 最后,点击…

一个 SpringBoot 项目能同时处理多少请求?

目录 1 问题分析 2 Demo 3 答案 4 怎么来的&#xff1f; 5 标准答案及影响参数一Tomcat配置 6 影响参数二 Web容器 7 影响参数三 Async 1 问题分析 一个 SpringBoot 项目能同时处理多少请求&#xff1f; 不知道你听到这个问题之后的第一反应是什么&#xff1f; 我大概…

从零开始手写mmo游戏从框架到爆炸(十)— 集成springboot-jpa与用户表

导航&#xff1a;从零开始手写mmo游戏从框架到爆炸&#xff08;零&#xff09;—— 导航-CSDN博客 集成springboot-jpa&#xff0c;不用mybatis框架一个是方便对接不同的数据源。第二个目前规划的游戏内容可能对数据库的依赖不是很大&#xff0c;jpa应该肯定能满足要求了…

redis之布隆过滤

目录 1、redis之布隆过滤 2、布隆过滤器原理 3、布隆过滤器使用步骤 初始化bitmap 添加占坑位 判断是否存在圜 1、redis之布隆过滤 布隆过滤&#xff1a;有一个初值都为0的bit数组和多个哈希函数构成&#xff0c;用来快速判断集合中是否存在某个元素。目的&#xff1a;减…

【STL】list模拟实现

vector模拟实现 一、接口大框架函数声明速览二、结点类的模拟实现1、构造函数 三、迭代器类的模拟实现1、迭代器类存在的意义2、迭代器类的模板参数说明3、构造函数4、运算符的重载&#xff08;前置和后置&#xff09;&#xff08;1&#xff09;前置&#xff08;2&#xff09;后…

Java实现网上药店系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 药品类型模块2.3 药品档案模块2.4 药品订单模块2.5 药品收藏模块2.6 药品资讯模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 角色表3.2.2 药品表3.2.3 药品订单表3.2.4 药品收藏表3.2.5 药品留言表…

嵌入式学习之Linux入门篇笔记——18,makefile基本语法(下)

配套视频学习链接&#xff1a;http://【【北京迅为】嵌入式学习之Linux入门篇】 https://www.bilibili.com/video/BV1M7411m7wT/?p4&share_sourcecopy_web&vd_sourcea0ef2c4953d33a9260910aaea45eaec8 1.wildcard 函数 格式&#xff1a;$&#xff08;wildcard PAT…

Oracle11g安装配置详细教程

Oracle Database 11g是一款广泛使用的关系型数据库管理系统&#xff0c;它为企业级的应用提供了强大的数据管理功能。本文将详细介绍如何在Windows环境下安装和配置Oracle 11g。 准备工作 系统要求&#xff1a;确保你的系统满足安装Oracle 11g的最低要求。对于Oracle 11g Rele…

mac电脑flutter环境配置,解决疑难问题

准备工作 首先搭建flutter的环境需要使用到flutter的sdk&#xff0c;可以直接跳去官网下载&#xff1a;Choose your first type of app - Flutter 中文文档 - Flutter 中文开发者网站 - Flutter&#xff0c;下载时要注意你电脑所使用的芯片是Intel的还是苹果的芯片。 下载好的…

C语言之自定义类型:联合和枚举

目录 1. 联合体类型的声明2. 联合体的特点3. 联合体大小的计算联合的一个练习 4. 枚举类型的声明5. 枚举类型的优点6. 枚举类型的使用 1. 联合体类型的声明 像结构体一样&#xff0c;联合体也是由一个或者多个成员构成&#xff0c;这些成员可以不同的类型 但是编译器只为最大…

【JavaWeb】头条新闻项目实现 基本增删改查 分页查询 登录注册校验 业务功能实现 第二期

文章目录 一、为什么使用token口令二、登录注册功能2.1 登录表单提交后端代码&#xff1a; 2.2 根据token获取完整用户信息代码实现&#xff1a; 2.3 注册时用户名占用校验代码实现&#xff1a; 2.4 注册表单提交代码实现&#xff1a; 三、头条首页功能3.1 查询所有头条分类3.2…

HTTP协议笔记

HTTP协议笔记 参考&#xff1a; &#xff08;建议精读&#xff09;HTTP灵魂之问&#xff0c;巩固你的 HTTP 知识体系 《透视 HTTP 协议》——chrono 目录&#xff1a; 1、说说你对HTTP的了解吧。  1. HTTP状态码。  2. HTTP请求头和响应头&#xff0c;其中包括cookie、跨域响…