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

javascript 复制代码
<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

相关推荐
惜.己16 分钟前
Jmeter中的配置原件(四)
java·前端·功能测试·jmeter·1024程序员节
EasyNTS17 分钟前
无插件H5播放器EasyPlayer.js网页web无插件播放器vue和react详细介绍
前端·javascript·vue.js
老码沉思录22 分钟前
React Native 全栈开发实战班 - 数据管理与状态之Zustand应用
javascript·react native·react.js
老码沉思录27 分钟前
React Native 全栈开发实战班 :数据管理与状态之React Hooks 基础
javascript·react native·react.js
guokanglun41 分钟前
Vue.js动态组件使用
前端·javascript·vue.js
Go4doom44 分钟前
vue-cli3+qiankun迁移至rsbuild
前端
-seventy-1 小时前
Ajax 与 Vue 框架应用点——随笔谈
前端
我认不到你1 小时前
antd proFromSelect 懒加载+模糊查询
前端·javascript·react.js·typescript
集成显卡1 小时前
axios平替!用浏览器自带的fetch处理AJAX(兼容表单/JSON/文件上传)
前端·ajax·json
scc21401 小时前
spark的学习-06
javascript·学习·spark