vue+div.canvas图像标注功能实现
main.js
import Vue from 'vue'
import 'vueui-widgets/dist/index.css'
import VueUI from 'vueui-widgets'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.use(VueUI) Vue.config.productionTip = false new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
组件.vue
<template>
<div class="mycanvas-container">
<div class="left">
<p>展示视口</p>
<div class="myshow">
<img :src="mysrc" alt width="100%" />
<!-- <div id="canvas" style="width:100%;height:100%" class="mycanvas"></div> -->
</div>
</div>
<div class="center">
<p>操作视口</p>
<div class="myedit" ref="myedit" @mousedown.prevent="onMousedown" @mousemove="onMousemove" @contextmenu.prevent="">
<!-- <img src="@/assets/jia.svg" alt=""> -->
<img :src="mysrc" />
<span
class="myedit-span"
v-for="(item, index) in mydata"
:key="index"
:style="getSpanStyle(item)"
@contextmenu.prevent="onContextmenu(item, $event)"
></span>
<!-- <div id="canvas" style="width:100%;height:100%" class="mycanvas"></div> -->
</div>
</div>
<div class="right">
<img src alt class="mybutton" />
<input v-show="0" ref="file" type="file" class="mybutton" @change="onChange" />
<button class="mybutton" @click="selectFile">导入图片</button>
<button class="mybutton">新增标注</button>
<button class="mybutton">修改标注</button>
<button class="mybutton">删除</button>
<button class="mybutton">保存</button>
</div>
<div class="myMenu" v-show="mymenu.current" :style="mymenu.style">
<!-- <button @click="onRemoveItem">删除</button> -->
<ui-button type="primary" @click="onRemoveItem">删除</ui-button>
<ui-select></ui-select>
<select name="" id="">
<option value="1">ceshi</option>
</select>
</div>
</div>
</template> <script>
import jiaIcon from "./jia.svg";
export default {
data() {
return {
mysrc: "",
mydata: [],
mymenu: { current: null, style: { left: 0, top: 0 } }
};
},
mounted() {
document.addEventListener('mouseup', this.onMouseup)
},
beforeDestroy() {
document.removeEventListener('mouseup', this.onMouseup)
},
methods: {
getXY(e) {
let rect = this.$refs.myedit.getBoundingClientRect()
return {
x: e.clientX - rect.left,
y: e.clientY - rect.top
}
},
// 上传图片1
onChange(e) {
this.mysrc = window.URL.createObjectURL(e.target.files[0]);
e.target.value = ''
},
// 上传图片2,
selectFile() {
this.$refs.file.click();
},
onMousedown(e) {
this.mymenu.current = null
let { x, y } = this.getXY(e)
this.currentItem = { x, y, w: 0, h: 0, now: Date.now() }
this.startPos = { x, y }
this.mydata.push(this.currentItem)
},
onMousemove(e) {
if (!this.currentItem) return;
let { x, y } = this.getXY(e)
this.currentItem.w = Math.abs(x - this.startPos.x)
this.currentItem.h = Math.abs(y - this.startPos.y)
},
onMouseup(e) {
this.currentItem = this.startPos = null;
this.mydata = this.mydata.filter(_ => _.w > 10 && _.h > 10)
},
onContextmenu(item, e) {
this.mymenu = {
current: item,
style: {
top: e.clientY + 'px',
left: e.clientX + 'px'
}
}
},
onRemoveItem() {
this.mydata.splice(this.mydata.indexOf(this.mymenu.current), 1)
this.mymenu = { ...this.mymenu, current: null }
},
getSpanStyle(item) {
return {
width: `${item.w}px`,
height: `${item.h}px`,
top: `${item.y}px`,
left: `${item.x}px`
};
}
}
};
</script>
<style lang="less" scoped>
// 设置绘图样式1
body {
user-select: none;
} .myMenu {
position: fixed;
top: 400px;
left: 400px;
width: 100px;
padding: 8px 0;
background-color: #fff;
> * {
width: 100%;
}
} #canvas > div {
/* border: 2px solid green; */
position: absolute;
background-color: transparent;
} #canvas > div > span {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-family: simsun;
font-size: 9pt;
} // 设置绘图样式2 .mycanvas-container {
display: flex;
justify-content: center;
align-items: center; .left,
.center,
.right {
width: 300px;
// height: 520px;
margin: 20px; p {
text-align: center;
} .myshow,
.myedit {
width: 300px;
// height: 500px;
border: 1px solid #000;
position: relative;
.myedit-span {
position: absolute;
border: 1px dashed #fff;
background: url("./jia.svg") no-repeat center center;
background-size: contain;
} .mycanvas {
border: 1px solid pink;
position: absolute;
top: 0;
left: 0;
} img {
width: 100%;
}
}
} .right {
width: 150px;
display: flex;
justify-content: center;
align-items: left;
flex-direction: column; .mybutton {
margin-top: 20px;
display: block;
}
}
}
</style>
vue+div.canvas图像标注功能实现的更多相关文章
- 如何实现Canvas图像的拖拽、点击等操作
上一篇Canvas的博文写完后,有位朋友希望能对Canvas绘制出来的图像进行点击.拖拽等操作,因为Canvas绘制出的图像能很好的美化.好像是想做炉石什么的游戏,我也没玩过. Canvas在我的理解 ...
- 【百度地图API】情人节求爱大作战——添加标注功能
原文:[百度地图API]情人节求爱大作战--添加标注功能 任务描述: 2月2日是除夕,2月14立马来!即将到来的情人节,你想送TA一份什么礼物呢? 不如,在你们居住的地方,画个大大的桃心,表达你对TA ...
- OpenCV探索之路(二十五):制作简易的图像标注小工具
搞图像深度学习的童鞋一定碰过图像数据标注的东西,当我们训练网络时需要训练集数据,但在网上又没有找到自己想要的数据集,这时候就考虑自己制作自己的数据集了,这时就需要对图像进行标注.图像标注是件很枯燥又很 ...
- 【开源】canvas图像裁剪、压缩、旋转
前言 前段时间遇到了一个移动端对图像进行裁剪.压缩.旋转的需求. 考虑到已有各轮子的契合度都不高,于是自己重新造了一个轮子. 关于图像裁剪.压缩 在HTML5时代,canvas的功能已经非常强大了,可 ...
- Vue (二) --- Vue对象提供的属性功能
--------------------------------------------不是井里没有水,而是你挖的不够深. 3. Vue对象提供的属性功能 3.1 过滤器 过滤器,就是vue允许开发者 ...
- vue 对象提供的属性功能、通过axio请求数据(2)
1 Vue对象提供的属性功能 1.1 过滤器 过滤器,就是vue允许开发者自定义的文本格式化函数,可以使用在两个地方:输出内容和操作数据中. 1.1.1 使用Vue.filter()进行全局定义(全局 ...
- vue 使用canvas仿芝麻分信用表
如图所示: 画布组件:dashboard.vue <template> <div> <canvas ref="canvas" v-if="c ...
- canvas图像裁剪、压缩、旋转
转载于:http://www.cnblogs.com/dailc/p/7843204.html 前言 前段时间遇到了一个移动端对图像进行裁剪.压缩.旋转的需求.考虑到已有各轮子的契合度都不高,于是自己 ...
- vue教程2-07 微博评论功能
vue教程2-07 微博评论功能 <!doctype html> <html> <head> <meta charset="utf-8"& ...
- PHP《将画布(canvas)图像保存成本地图片的方法》
用PHP将网页上的Canvas图像保存到服务器上的方法 2014年6月27日 歪脖骇客 发表回复 8 在几年前HTML5还没有流行的时候,我们的项目经理曾经向我提出这样一个需求:让项目评审专家们在评审 ...
随机推荐
- 重新整理 .net core 实践篇 ———— linux 上线篇 [外篇]
前言 简单整理一个linux 简单上线. 这个是该系列的外篇,该系列继续更新.献给刚学的人. 正文 安装实例 dotnet new webapp -n AspNetCoreDemo -o firstw ...
- nrf9160做主控连接阿里云——(mqtt_simple例程)
简介:基本每一个云都支持MQTT,这种轻量级协议在数据量不大的应用上是一个很好的选择.上一篇博客使用SLM例程去连接了阿里云,本次使用mqtt_simple去连接云进行测试,关于一些已近在前面文章中演 ...
- OpenMP 入门
OpenMP 入门 简介 OpenMP 一个非常易用的共享内存的并行编程框架,它提供了一些非常简单易用的API,让编程人员从复杂的并发编程当中释放出来,专注于具体功能的实现.openmp 主要是通过编 ...
- 研发效能|DevOps 已死平台工程永存带来的焦虑
最近某位大神在推特上发了一个帖子,结果引来了国内众多卖课机构.培训机构的狂欢,开始贩卖焦虑,其实「平台工程」也不是什么特别高深莫测的东西.闲得无聊,把这位大神的几个帖子薅了下来,你看过之后就会觉得没啥 ...
- 将java装进u盘指南
将java装入u盘指南 idea 将下载好的idea的文件夹移动到u盘中.在idea的bin目录里找到idea.properties文件,在最后添加以下两行 idea.config.path=U:/I ...
- 2022春每日一题:Day 25
题目:青蛙的约会 读完题,显然可以的到下同余方程:x+mk≡y+nk (mod L) 移项变成 (m-n)k+aL=y-x 只有k,L是未知的,而这题要求非负整数k的最小值,显然拓展欧几里得算法. 然 ...
- Android Studio运行Failed to find Build Tools revision 30.0.3
问题 第一次安装好Android Studio2022.5的版本之后开启虚拟机运行文件报错提示 Failed to find Build Tools revision 30.0.3 打开SDK已经安装 ...
- 前后端结合解决Excel海量公式计算的性能问题
背景 在数据密集的业务领域,尤其是金融,保险,税务等行业中,经常需要利用Excel模型,来对业务进行分析和处理.例如: 1.金融投资: 根据模型进行估值计算,并对投资风险进行评估,通过测算出投资的内部 ...
- python进阶(29)单例模式
初识单例模式 单例模式含义 单例模式,也叫单子模式,是一种常用的软件设计模式.在应用这个模式时,单例对象的类必须保证只有一个实例存在.许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整 ...
- <十>关于菱形继承
代码1 #include <iostream> using namespace std; class A{ public: A(int _a):ma(_a){ cout<<&q ...