图片在canvas中自适应大小并居中。
通常图片大小与canvas的大小是不同的,分为以下几种情况
图片高或宽,超过canvas高或宽
图片高、宽,都超过canvas高宽;
图片高、宽都小于canvas高、宽
问题的本质其实是动态计算图片大小,并在canvas适合的位置画出图片,并能获取选取的坐标点
<template>
<div class="app-container">
<el-row :gutter="20">
<el-col :span="6">1</el-col>
<el-col :span="18" class="wrap" ref="wrap">
<div id="divHeight">
<canvas id="canvaxbox" ref="canvaxbox"></canvas>
<!--用来和鼠标进行交互操作的canvas-->
<canvas id="canvas" ref="canvas"> </canvas>
<!--存储已生成的点线,避免被清空-->
<canvas id="canvasSave" ref="canvasSave"></canvas>
</div>
<div id="shouPointArr">
<input
id="deleteCanvas"
ref="deleteCanvas"
type="button"
value="清空选区"
/>
<input
id="ratioPointArr"
ref="ratioPointArr"
type="text"
value=""
readonly="readonly"
/>
</div>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
name: "identifyArea",
data() {
return {
canvasHeight:""
};
},
mounted() {
this.init();
console.log("this.canvasHeight--")
console.log(this.canvasHeight)
},
methods: {
init() {
var c = document.getElementById("canvaxbox");
var canvas = c.getContext("2d");
var img = new Image();
img.onload = imgfn; //图片加载完在执行
img.src =
"https://open.ys7.com/api/lapp/mq/downloadurl?appKey=0eb63461646743bfbff8bfb642088ff3&fileKey=ISAPI_FILES/E47730522_1/20210407135016307-E47730522-1-10000$encrypt=2,2021-04-07T13:50:15,c93025e41acb6f2d1bb1567fde4b5c9d";
console.log("img");
console.log(img);
// img.src = [[${url}]];
c.width = 0;
c.height = 0;
var w = 0;
var h = 0;
var wrapWidth = this.$refs.wrap.$el.clientWidth;
function imgfn() {
var imgWidth = img.width;
var imgHeight = img.height;
var ratio = imgHeight / imgWidth;
var wrapHeight = parseInt(wrapWidth * ratio);
var outHeight = document.getElementById("divHeight");
outHeight.style.height = wrapHeight + 'px'
console.log("this.canvasHeight")
console.log(this.canvasHeight)
c.width = wrapWidth;
c.height = wrapHeight;
w = wrapWidth;
h = wrapHeight;
var iw = img.width;
var ih = img.height;
var local = calculate(iw, ih);
canvas.fillStyle = "white";
canvas.fill();
canvas.drawImage(img, local.px, local.py, local.pw, local.ph);
//绘制多边形
var can = document.getElementById("canvas");
var ctx = can.getContext("2d");
var canSave = document.getElementById("canvasSave");
var ctxSave = canSave.getContext("2d");
var pointX, pointY;
var pointArr = []; //存放坐标的数组
//设置和图片长宽 一致
can.width = wrapWidth;
can.height = wrapHeight;
canSave.width = wrapWidth;
canSave.height = wrapHeight;
ctx.strokeStyle = "rgba(102,168,255,1)"; //线条颜色
ctx.lineWidth = 4; //线条粗细
ctxSave.strokeStyle = "rgba(102,168,255,1)"; //线条颜色
ctxSave.lineWidth = 4; //线条粗细
var oIndex = -1; //判断鼠标是否移动到起始点处,-1为否,1为是
/*点击画点*/
can.addEventListener("click", function (e) {
if (e.offsetX || e.layerX) {
pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
var piX, piY;
if (oIndex > 0 && pointArr.length > 0) {
piX = pointArr[0].x;
piY = pointArr[0].y;
//画点
makearc(
ctx,
piX,
piY,
GetRandomNum(2, 2),
0,
180,
"rgba(102,168,255,1)"
);
pointArr.push({ x: piX, y: piY });
canvasSave(pointArr); //保存点线同步到另一个canvas
saveCanvas(); //生成画布
} else {
piX = pointX;
piY = pointY;
makearc(
ctx,
piX,
piY,
GetRandomNum(2, 2),
0,
180,
"rgba(102,168,255,1)"
);
pointArr.push({ x: piX, y: piY });
canvasSave(pointArr); //保存点线同步到另一个canvas
}
}
});
// 计算出图片画在canvas中的四个参数
function calculate(pw, ph) {
var px = 0;
var py = 0;
if (pw < w && ph < h) {
px = 0.5 * w - 0.5 * pw;
py = 0.5 * h - 0.5 * ph;
} else if (ph / pw > h / w) {
var uu = ph;
ph = h;
pw = (pw * h) / uu;
px = 0.5 * w - 0.5 * pw;
} else {
var uu = pw;
pw = w;
ph = (ph * pw) / uu;
py = 0.5 * h - 0.5 * ph;
}
return { px, py, pw, ph };
}
/* */
can.addEventListener("mousemove", function (e) {
if (e.offsetX || e.layerX) {
pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
var piX, piY;
/*清空画布*/
ctx.clearRect(0, 0, can.width, can.height);
/*鼠标下跟随的圆点*/
makearc(
ctx,
pointX,
pointY,
GetRandomNum(4, 4),
0,
180,
"rgba(255,109,0,1)"
);
if (pointArr.length > 0) {
if (
pointX > pointArr[0].x - 15 &&
pointX < pointArr[0].x + 15 &&
pointY > pointArr[0].y - 15 &&
pointY < pointArr[0].y + 15
) {
if (pointArr.length > 1) {
piX = pointArr[0].x;
piY = pointArr[0].y;
ctx.clearRect(0, 0, can.width, can.height);
makearc(
ctx,
piX,
piY,
GetRandomNum(4, 4),
0,
180,
"rgba(102,168,255,1)"
);
oIndex = 1;
}
} else {
piX = pointX;
piY = pointY;
oIndex = -1;
}
/*开始绘制*/
ctx.beginPath();
ctx.moveTo(pointArr[0].x, pointArr[0].y);
if (pointArr.length > 1) {
for (var i = 1; i < pointArr.length; i++) {
ctx.lineTo(pointArr[i].x, pointArr[i].y);
}
}
ctx.lineTo(piX, piY);
ctx.fillStyle = "rgba(161,195,255,1)"; //填充颜色
ctx.fill(); //填充
ctx.stroke(); //绘制
}
}
});
// 存储已生成的点线
function canvasSave(pointArr) {
ctxSave.clearRect(0, 0, ctxSave.width, ctxSave.height);
ctxSave.beginPath();
if (pointArr.length > 1) {
ctxSave.moveTo(pointArr[0].x, pointArr[0].y);
for (var i = 1; i < pointArr.length; i++) {
ctxSave.lineTo(pointArr[i].x, pointArr[i].y);
ctxSave.fillStyle = "rgba(161,195,255,1)"; //填充颜色
//ctxSave.fill();
ctxSave.stroke(); //绘制
}
ctxSave.closePath();
}
}
/*生成画布 结束绘画*/
function saveCanvas() {
ctx.clearRect(0, 0, can.width, can.height);
ctxSave.closePath(); //结束路径状态,结束当前路径,如果是一个未封闭的图形,会自动将首尾相连封闭起来
ctxSave.fill(); //填充
ctxSave.stroke(); //绘制
//计算坐标点
calPoint(pointArr);
pointArr = [];
}
/*清空选区*/
document
.getElementById("deleteCanvas")
.addEventListener("click", function (e) {
ctx.clearRect(0, 0, can.width, can.height);
ctxSave.clearRect(0, 0, canSave.width, canSave.height);
pointArr = [];
document.getElementById("ratioPointArr").value = "";
});
/*验证canvas画布是否为空函数*/
function isCanvasBlank(canvas) {
var blank = document.createElement("canvas"); //创建一个空canvas对象
blank.width = canvas.width;
blank.height = canvas.height;
return canvas.toDataURL() == blank.toDataURL(); //为空 返回true
}
/*canvas生成圆点*/
function GetRandomNum(Min, Max) {
var Range = Max - Min;
var Rand = Math.random();
return Min + Math.round(Rand * Range);
}
function makearc(ctx, x, y, r, s, e, color) {
ctx.clearRect(0, 0, 199, 202); //清空画布
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(x, y, r, s, e);
ctx.fill();
}
/*计算生成坐标比例*/
function calPoint(pointArr) {
let ratioPointArr = [];
//循环计算坐标点
for (let i = 0; i < pointArr.length - 1; i++) {
let ratioPoint = [];
//判断坐标点为负
if (pointArr[i].x < 0) {
pointArr[i].x = 0;
}
if (pointArr[i].y < 0) {
pointArr[i].y = 0;
}
ratioPoint.push(pointArr[i].x / img.width);
ratioPoint.push(pointArr[i].y / img.height);
ratioPointArr.push(ratioPoint);
}
console.log(ratioPointArr);
document.getElementById("ratioPointArr").value = ratioPointArr;
}
}
},
},
};
</script>
<style lang="scss" scoped>
.wrap {
position: relative;
padding-left: 0;
padding-right: 0;
}
#shouPointArr {
width: 100px;
margin-left: 200px;
// margin-top: 520px;
}
canvas {
// border: 1px solid #333;
display: block;
}
#canvaxbox {
position: absolute;
left: 0;
top: 0;
}
#canvas {
position: absolute;
left: 0;
top: 0;
z-index: 1;
cursor: crosshair;
}
#canvasSave {
position: absolute;
left: 0;
top: 0;
}
</style>