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

news2024/9/21 10:32:28

<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

 

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

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

相关文章

Linux线程库封装

一 MyThread.hpp #pragma once #include<pthread.h> #include<iostream> #include<unistd.h> #include<string> #include<ctime>typedef void (*callback_t)(); static int num 1; //任务和线程绑定 class Thread {static void* Routine(void …

Qt 字符串类应用与常用基本数据类型

目录 操作字符串 查询字符串 Qt 常见数据类型 操作字符串 创建一个控制台项目 &#xff08;1&#xff09;QString提供一个二元的 “” 操作符&#xff0c;主要用于组合两个字符串。QString str1 "Hello World 传递给QString一个 const char* 类型的ASCII字符串 “He…

计算机网络基本知识(一)

文章目录 概要速率带宽、吞吐量带宽吞吐量 时延发送&#xff08;传输&#xff09;时延传播时延排队时延处理时延时延带宽积 利用率 概要 速率、带宽、吞吐量、时延、利用率 速率 记忆要点&#xff1a;10的三次方 记忆要点&#xff1a;2的10次方 带宽、吞吐量 带宽 单位&…

Linux开发:PAM1 介绍

PAM(Pluggable Authentication Modules )是Linux提供的一种通用的认证方式,他可以根据需要动态的加载认证模块,从而减少认证开发的工作量以及提供认证的灵活度。 1.PAM的框架 PAM的框架由一下几个部分构成 1)应用程序,即需要使用认证服务的程序,这些应用程序是使用抽象…

【pip】本地和Anaconda的pip冲突时如何指定安装位置

输入指令&#xff1a; where pip 显示如下&#xff1a; D:\LenovoSoftstore\Anaconda\Scripts\pip.exe C:\python\python3.8\Scripts\pip.exe 可以看到有两个位置的pip&#xff0c;一个Anaconda下的pip&#xff0c;一个是本地的pip。 当我们使用pip安装的时候&#xff0c;系…

百家cms代审

环境搭建 源码链接如下所示 https://gitee.com/openbaijia/baijiacms 安装至本地后 直接解压到phpstudy的www目录下即可 接下来去创建一个数据库用于存储CMS信息。&#xff08;在Mysql命令行中执行&#xff09; 接下来访问CMS&#xff0c;会默认跳转至安装界面 数据库名称和…

初始web服务器(并基于idea来实现无需下载的tomcat)

前言 前面学习了对应的http协议&#xff0c;我们知道了他是在网络层进行数据传输的协议&#xff0c;负责相应数据以及接收数据的规则&#xff0c;但是在人员开发后端的时候不仅仅需要你写io流进行数据传输&#xff0c;还需要你进行对应的tcp协议来进行数据打包发送http协议-CSD…

[疑难杂症2024-001] java多线程运行时遇到java.util.ConcurrentModificationException的解决方案

本文由Markdown语法编辑器编辑完成。 1.背景 由于近日在改进一个医学图像的收图服务。之前的版本&#xff0c;我们采用了pynetdicom的服务。 https://pydicom.github.io/pynetdicom/stable/ 它的介绍为: pynetdicom is a pure Python package that implements the DICOM net…

(2024,仅高频分量的蓝噪声与高斯噪声线性插值,时变噪声)扩散模型的蓝噪声

Blue noise for diffusion models 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 1. 简介 2. 相关工作 3. 方法 3.1 相关噪声 3.2 具有时变噪声的扩散模型 3.3 利用矫正…

Unity3d Shader篇(六)— BlinnPhong高光反射着色器

文章目录 前言一、BlinnPhong高光反射着色器是什么&#xff1f;1. BlinnPhong高光反射着色器的工作原理2. BlinnPhong高光反射着色器的优缺点优点缺点 3. 公式 二、使用步骤1. Shader 属性定义2. SubShader 设置3. 渲染 Pass4. 定义结构体和顶点着色器函数5. 片元着色器函数 三…

Nginx限流设置

1.反向代理(建议先看正向代理,反向代理则是同样你要与对方服务器建立连接,但是,代理服务器和目标服务器在一个LAN下,所以我们需要与代理服务器先建交,再由他获取与目标服务器的交互,好比一个带刀侍卫守护着目标服务器) 屏蔽目标服务器的真实地址&#xff0c;相对安全性较好&am…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之StepperItem组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之StepperItem组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、StepperItem组件 用作Stepper组件的页面子组件。 子组件 无。 接口 St…

Kafka 生产调优

Kafka生产调优 文章目录 Kafka生产调优一、Kafka 硬件配置选择场景说明服务器台数选择磁盘选择内存选择CPU选择 二、Kafka Broker调优Broker 核心参数配置服役新节点/退役旧节点增加副本因子调整分区副本存储 三、Kafka 生产者调优生产者如何提高吞吐量数据可靠性数据去重数据乱…

如何写一个其他人可以使用的GitHub Action

前言 在GitHub中&#xff0c;你肯定会使用GitHub Actions自动部署一个项目到GitHub Page上&#xff0c;在这个过程中总要使用workflows工作流&#xff0c;并在其中使用action&#xff0c;在这个使用的过程中&#xff0c;总会好奇怎么去写一个action呢&#xff0c;所以&#xff…

无人机图像识别技术研究及应用,无人机AI算法技术理论,无人机飞行控制识别算法详解

在现代科技领域中&#xff0c;无人机技术是一个备受瞩目的领域。随着人们对无人机应用的需求在不断增加&#xff0c;无人机技术也在不断发展和改进。在众多的无人机技术中&#xff0c;无人机图像识别技术是其中之一。 无人机图像识别技术是利用计算机视觉技术对无人机拍摄的图像…

Project 2010下载安装教程,保姆级教程,附安装包和工具

前言 Project是一款项目管理软件&#xff0c;不仅可以快速、准确地创建项目计划&#xff0c;而且可以帮助项目经理实现项目进度、成本的控制、分析和预测&#xff0c;使项目工期大大缩短&#xff0c;资源得到有效利用&#xff0c;提高经济效益。软件设计目的在于协助专案经理发…

6、5 门关于 AI 和 ChatGPT 的免费课程,带您从 0-100

5 门关于 AI 和 ChatGPT 的免费课程,带您从 0-100 想在 2024 年免费了解有关 AI 和 ChatGPT 的更多信息吗? 图片由 DALLE 3 提供 活着是多么美好的时光啊。还有什么比现在更适合了解生成式人工智能(尤其是 ChatGPT)等人工智能元素的呢!许多人对这个行业感兴趣,但有些…

一文读懂:MybatisPlus从入门到进阶

快速入门 简介 在项目开发中&#xff0c;Mybatis已经为我们简化了代码编写。 但是我们仍需要编写很多单表CURD语句&#xff0c;MybatisPlus可以进一步简化Mybatis。 MybatisPlus官方文档&#xff1a;https://www.baomidou.com/&#xff0c;感谢苞米豆和黑马程序员。 Mybat…

表单标记(html)

前言 发现input的type属性还是有挺多的&#xff0c;这里把一些常用的总结一下。 HTML 输入类型 (w3school.com.cn)https://www.w3school.com.cn/html/html_form_input_types.asp text-文本 文本输入,如果文字太长&#xff0c;超出的部分就不会显示。 定义供文本输入的单行…

C语言操作符超详细总结

文章目录 1. 操作符的分类2. 二进制和进制转换2.1 2进制转10进制2.1.1 10进制转2进制数字 2.2 2进制转8进制和16进制2.2.1 2进制转8进制2.2.2 2进制转16进制 3. 原码、反码、补码4.移位操作符4.1 左移操作符4.2 右移操作符 5. 位操作符&#xff1a;&、|、^、~6. 逗号表达式…