一、接到新需求:图片可放大、缩小、拖拽且能在图片上画区域块,将画出的区块数据传给后端。
产品原型图: 小众:站在前人的肩膀上造轮子或者直接应用到项目中--高效。
vue2-drawboard:
demo效果图: 引入组件:
js
<template>
<div class="pic-draw-box">
<div class="middle">
<span class="button-tip" v-show="!openDetail && noShowDrag">再次点击第一个点时结束标记</span>
<div class="button" v-show="!openDetail">
<el-button @click="cancel" icon="el-icon-delete" size="mini">
清空
</el-button>
</div>
<el-tooltip effect="dark" content="移动" placement="bottom">
<i class="el-icon-drag" @click="changeToMove"></i>
</el-tooltip>
<span class="icon-line" v-show="!openDetail && !isDrawing"></span>
<el-tooltip effect="dark" content="多边形" placement="right" v-show="!openDetail && !isDrawing">
<i class="el-icon-polygon" @click="changeTool('polygon')"></i>
</el-tooltip>
<drawboard
:url="fileUrl+mapUrl"
:class="{'detail':openDetail,'drawing':isDrawing,'no-show-drag':noShowDrag}"
@updateData="updateData"
@drawEventDone="drawEventDone"
:labelDataOrigin="labelDataOrigin"
style="width: 100%; height: 100%;"
ref="myDrawBoard"
@mouseup="canvasMouseup"
>
</drawboard>
</div>
</div>
</template>
出现放大图片后分辨率下降的问题: 传入vue2-drawboard组件的图片url在canvas上渲染导致,客户提出问题=》如何解决,看源码。
canvas绘图不清晰:www.cnblogs.com/chrissong/p...
我们知道img标签缩放分辨率没影响。
将要缩放拖拽画区块的图放img标签,作为背景图片,传组件一张透明图作隔层图。
img图片作为透明图下的背景,跟透明图大小保持一致。
js
<template>
<div class="pic-draw-box">
<div class="middle">
<span class="button-tip" v-show="!openDetail && noShowDrag">再次点击第一个点时结束标记</span>
<div class="button" v-show="!openDetail">
<el-button @click="cancel" icon="el-icon-delete" size="mini">
清空
</el-button>
</div>
<el-tooltip effect="dark" content="移动" placement="bottom">
<i class="el-icon-drag" @click="changeToMove"></i>
</el-tooltip>
<span class="icon-line" v-show="!openDetail && !isDrawing"></span>
<el-tooltip effect="dark" content="多边形" placement="right" v-show="!openDetail && !isDrawing">
<i class="el-icon-polygon" @click="changeTool('polygon')"></i>
</el-tooltip>
<img :src="fileUrl+mapUrl" ref="imgMapUrl" alt="" style="width: 100%; height: 100%;position: absolute;bottom: 1000px;">
<drawboard
:url="transparentBg"
:class="{'detail':openDetail,'drawing':isDrawing,'no-show-drag':noShowDrag}"
@updateData="updateData"
@drawEventDone="drawEventDone"
:labelDataOrigin="labelDataOrigin"
style="width: 100%; height: 100%;"
ref="myDrawBoard"
@mouseup="canvasMouseup"
>
</drawboard>
</div>
</div>
</template>
<script>
import { getPlantBaseMapById } from '@/api/link/soli/show';
let transparentBg = require('./transparent-bg.png');
export default {
mounted(){
let that = this;
setTimeout(()=>{
let board = this.$refs.myDrawBoard.image;
let myDrawBoard = this.$refs.myDrawBoard;
console.log('myDrawBoard', myDrawBoard);
board.style.backgroundImage = `url(${encodeURI(that.fileUrl + that.mapUrl)})`
board.style.backgroundSize = `${board.width}px ${board.height}px`;
board.style.backgroundRepeat = `no-repeat`;
board.style.backgroundOrigin = `center center`;
board.style.backgroundPosition = `center center`;
},500)
},
methods: {
//编辑图片拿到画图的边框数据
updateData(data,flag) {
console.log('data',data);
let hasValue = true;
if(!data || (data && data.length ==0)) {
hasValue = false;
}
//flag为father时是回显 不进入下面代码
if(data[0] && flag != 'father'){
//占位底图片
let {imgMapUrl} = this.$refs;
let numX = imgMapUrl.naturalWidth / 880;
let numY = imgMapUrl.naturalHeight / 439;//880 x 439 px
//父亲保存时取labelData值
this.labelData = [{
points:multiplyPropertyInArray(data, numX, numY),
type:"polygon",
}]
}
function multiplyPropertyInArray(obj, numX, numY) {
return obj[0].points.map(function(element) {
element.x *= numX;
element.y *= numY;
return element;
});
}
//markFlag为2说明出现了红色提示请画出地块范围,当前有值时候让父亲取消当前红色提示
if(this.markFlag == '2' && hasValue){
this.$emit('closeMarkTip',true);
}
},
}
};
</script>
二、uniapp微信小程序 uniapp.dcloud.net.cn/ svg、polygon、canvas
js
init() {
// let context = uni.createCanvasContext("firstCanvas",this);
const query = wx.createSelectorQuery();
query.select("#firstCanvas").fields({ node: true, size: true }).exec((res) => {
const canvas = res[0].node;
if(canvas){
const context = canvas.getContext("2d");
const dpr = wx.getSystemInfoSync().pixelRatio;
canvas.width = this.imgWidth;
canvas.height = this.imgHeight;
// context.scale(dpr, dpr);
context.scale(1, 1);
this.context = context;
context.fillStyle = "rgba(255, 229, 128, 0.60)";
//context.. 开始canvas画
}
});
},
//只有点在了地块内部才开始切换高亮地块
context.clearRect(0,0,this.imgWidth,this.imgHeight);
this.plotData.forEach((v, k) => {
if (this.isInPolygon([x, y], v.points)) {
this.hoverIndex = k;
console.log("开始点击,点到里面啦");
context.fillStyle = "#ffe580";
context.strokeStyle = "#ffe580";
this.soliId = v.key;
//通过地块id查数据
this.getPlantStatusBySoil();
this.selectDeviceInfoBySoilId();
}else {
context.fillStyle = "rgba(255, 229, 128, 0.60)";
context.strokeStyle = "rgba(255, 229, 128, 0.60)";
}
context.beginPath();
v.points.forEach((v2,k2)=>{
if(k2 == 0) {
context.moveTo(v2[0], v2[1]);
}else {
context.lineTo(v2[0], v2[1]);
}
//再回到第一个点
if(k2 == v.points.length -1){
context.lineTo(v.points[0][0], v.points[0][1]);
}
})
context.closePath();
context.stroke();
context.fill();
});