基于Canvas的扩大与缩小功能。其原理为:
按照上图的原理,做一个扩大缩小的功能,需要画三个canvas的窗口。可以隐藏原图(A窗口),用户看到的只有BC窗口。如图:
html 的canvas部分 应该是:
<canvas id="StageCanvas" width="682"></canvas><!-- 放大后的图(工作区 -->
<canvas id="OriginalCanvas" style="display:none;"></canvas><!-- 原图(隐藏 -->
<canvas id="AnimatedZoomCanvas" width="400"></canvas><!-- 缩小图(扩大缩小 -->
<p>拡大縮小比例:<span id="CropImage_gap">100%</span></p>
<span id="MoveUp" class="btn btn-success btn-lm" data-toggle="tooltip" title="上移動"><i class="fas fa-arrow-up"></i></span>
<span id="MoveLeft" class="btn btn-success btn-lm" data-toggle="tooltip" title="左移動"><i class="fas fa-arrow-left"></i></span>
<span id="MoveRight" class="btn btn-success btn-lm" data-toggle="tooltip" title="右移動"><i class="fas fa-arrow-right"></i></span>
<span id="MoveDow" class="btn btn-success btn-lm" data-toggle="tooltip" title="下移動"><i class="fas fa-arrow-down"></i></span>
<span id="ZoomIn" class="btn btn-indigo btn-lg" data-toggle="tooltip" title="拡大"><i class="fas fa-search-plus"></i></span>
<span id="ZoomOut" class="btn btn-indigo btn-lg" data-toggle="tooltip" title="縮小"><i class="fas fa-search-minus"></i></span>
<span id="Recover" class="btn btn-cyan btn-lg" data-toggle="tooltip" title="全体"><i class="fas fa-search"></i></span>
当然,还加入了扩大缩小功能,鼠标长按功能,滚轮控制功能,滚轮倍率功能。
JavaScript的代码:
<!-- Canvas -->
<script type="text/javascript">
$(function() {
//主显示StageCanvas
var StageCanvas = document.getElementById("StageCanvas"),
Sctx = StageCanvas.getContext("2d");
//扩大缩小canvas窗口
var AnimatedZoomCanvas = document.getElementById("AnimatedZoomCanvas"),
AZctx = AnimatedZoomCanvas.getContext("2d");
//OriginalCanvas //原图大小
var OriginalCanvas = document.getElementById("OriginalCanvas"),
Octx = OriginalCanvas.getContext("2d");
//图片的url
var BGimg = new Image();
BGimg.src = "../i-scr/0001_180402_130900_285_OK_C1.BMP"; //图片地址
//设置canvas的宽
StageCanvas.width = $("#CameraWidth").width();
//其他参数
var StageCanvas_w = StageCanvas.width, //主显示StageCanvas宽
StageCanvas_h, //主显示StageCanvas高
img_w = BGimg.width, //图片宽
img_h = BGimg.height, //图片高
StageCanvas_gap, //主显示StageCanvas和图片比率
AnimatedZoomCanvas_w = AnimatedZoomCanvas.width, //缩放画布宽
AnimatedZoomCanvas_h, //缩放画布高
AnimatedZoomCanvas_gap, //缩放画布和图片比率
CropImage_x = 0, //截取图的x
CropImage_y = 0, //截取图的y
CropImage_w, //截取宽
CropImage_h; //截取高
var CanvasX = 50,
CanvasY = 45,
CanvasW = 50,
CanvasH = 50; //canvas矩形的参数(test测试用
//当图片加载完成后,画背景图
BGimg.onload = function() {
OriginalCanvas.width = BGimg.width; //set OriginalCanvas.width
OriginalCanvas.height = BGimg.height; //set OriginalCanvas.height
StageCanvas_gap = img_w / StageCanvas_w; // get StageCanvas_gap =img(BGimg.width)/StageCanvas_w
StageCanvas_h = (img_h / StageCanvas_gap); //get StageCanvas_h
StageCanvas.height = StageCanvas_h; //set StageCanvas.height
AnimatedZoomCanvas_gap = img_w / AnimatedZoomCanvas_w; // get AnimatedZoomCanvas_gap = img(BGimg.width)/AnimatedZoomCanvas_w
AnimatedZoomCanvas_h = (img_h / AnimatedZoomCanvas_gap); //get AnimatedZoomCanvas_h
AnimatedZoomCanvas.height = AnimatedZoomCanvas_h; //set AnimatedZoomCanvas.height
CropImage_w = AnimatedZoomCanvas_w; //Set initial value of CropImage_w
CropImage_h = AnimatedZoomCanvas_h; //Set initial value of CropImage_h
BackgroundImage();
}
function BackgroundImage() {
Octx.strokeStyle = "#FF00FF";
Octx.drawImage(BGimg, 0, 0);
Octx.strokeRect(CanvasX, CanvasY, CanvasW, CanvasH);
let w1 = (CropImage_w * AnimatedZoomCanvas_gap); //截取宽 * 缩放画布和图片比率。
let h1 = (CropImage_h * AnimatedZoomCanvas_gap); //截取高 * 缩放画布和图片比率。
let x1 = (CropImage_x * AnimatedZoomCanvas_gap); //截取 x * 缩放画布和图片比率。
let y1 = (CropImage_y * AnimatedZoomCanvas_gap); //截取 y * 缩放画布和图片比率。
Sctx.drawImage(OriginalCanvas, x1, y1, w1, h1, 0, 0, StageCanvas_w, StageCanvas_h);
AZctx.drawImage(OriginalCanvas, 0, 0, AnimatedZoomCanvas_w, AnimatedZoomCanvas_h);
AnimatedZoomCanvasRect(CropImage_x, CropImage_y, CropImage_w, CropImage_h);
}
//AnimatedZoomCanvas里画图形
function AnimatedZoomCanvasRect(x, y, w, h) {
AZctx.beginPath();
AZctx.strokeStyle = "rgba(255,152,0,1)";
AZctx.rect(x, y, w, h);
AZctx.stroke();
document.getElementById("CropImage_gap").innerHTML = parseInt((AnimatedZoomCanvas_w / CropImage_w) * 100) + "%";
}
//復元
document.getElementById("Recover").onclick = Recover;
function Recover() {
CropImage_w = AnimatedZoomCanvas_w;
CropImage_h = AnimatedZoomCanvas_h;
CropImage_x = 0;
CropImage_y = 0;
BackgroundImage();
}
//放大
document.getElementById("ZoomIn").onclick = function() {
ZoomIn(1.1);
}
function ZoomIn(ZoomRatio) {
let CropImage_w_back = CropImage_w;
let CropImage_h_back = CropImage_h;
if (CropImage_x <= 0 || CropImage_y <= 0) {
CropImage_w /= ZoomRatio;
CropImage_h /= ZoomRatio;
CropImage_x += (CropImage_w_back - CropImage_w) / 2;
CropImage_y += (CropImage_h_back - CropImage_h) / 2;
} else {
CropImage_w /= ZoomRatio;
CropImage_h /= ZoomRatio;
CropImage_x += (CropImage_w_back - CropImage_w) / 2;
CropImage_y += (CropImage_h_back - CropImage_h) / 2;
}
BackgroundImage();
}
//缩小
document.getElementById("ZoomOut").onclick = function() {
ZoomOut(1.1);
}
function ZoomOut(ZoomRatio) {
let CropImage_w_back = CropImage_w;
let CropImage_h_back = CropImage_h;
let CropImage_RightDowW = CropImage_x + CropImage_w; //右下角x
let CropImage_RightDowY = CropImage_y + CropImage_h; //右下角y
if (CropImage_RightDowW >= AnimatedZoomCanvas_w || CropImage_RightDowY >= AnimatedZoomCanvas_h) {
CropImage_w *= ZoomRatio;
CropImage_h *= ZoomRatio;
let CropImage_missdistanceX = (CropImage_x + CropImage_w) - CropImage_RightDowW; //get 扩大差=扩大后右下角x-扩大前右下角x
let CropImage_missdistanceY = (CropImage_y + CropImage_h) - CropImage_RightDowY; //get 扩大差=扩大后右下角y-扩大前右下角y
if (CropImage_y <= 0) {
CropImage_y = 0;
CropImage_x -= CropImage_missdistanceX;
BackgroundImage();
} else if (CropImage_x <= 0) {
CropImage_x = 0;
CropImage_y -= CropImage_missdistanceY;
BackgroundImage();
} else {
CropImage_x -= CropImage_missdistanceX;
CropImage_y -= CropImage_missdistanceY;
if (CropImage_x <= 0) { //防止左边超出框外
CropImage_x = 0;
}
BackgroundImage();
}
} else if (CropImage_RightDowY < AnimatedZoomCanvas_h || CropImage_RightDowW < AnimatedZoomCanvas_w) {
CropImage_w *= ZoomRatio;
CropImage_h *= ZoomRatio;
CropImage_y -= (CropImage_h - CropImage_h_back) / 2;
CropImage_x -= (CropImage_w - CropImage_w_back) / 2;
if(CropImage_x<=0){
CropImage_x=0;
}
if(CropImage_y<=0){
CropImage_y=0;
}
BackgroundImage();
}
if (CropImage_w >= AnimatedZoomCanvas_w || CropImage_h >= AnimatedZoomCanvas_h) {
Recover();
}
}
//键盘
var MoveUp = false,
MoveDow = false,
MoveLeft = false,
MoveRight = false;
//长按连续事件
setInterval(function() {
if (MoveUp) {
MoveupFunction();
} else if (MoveDow) {
MoveDowFunction();
} else if (MoveLeft) {
MoveLeftFunction();
} else if (MoveRight) {
MoveRightFunction();
}
}, 50);
//按下鼠标(上下左右)
document.getElementById("MoveUp").onmousedown = function() {
MoveUp = true;
}
document.getElementById("MoveDow").onmousedown = function() {
MoveDow = true;
}
document.getElementById("MoveLeft").onmousedown = function() {
MoveLeft = true;
}
document.getElementById("MoveRight").onmousedown = function() {
MoveRight = true;
}
//松开鼠标(上下左右)
document.getElementById("MoveUp").onmouseup = function() {
MoveUp = false;
}
document.getElementById("MoveDow").onmouseup = function() {
MoveDow = false;
}
document.getElementById("MoveLeft").onmouseup = function() {
MoveLeft = false;
}
document.getElementById("MoveRight").onmouseup = function() {
MoveRight = false;
}
//移开鼠标(上下左右)
document.getElementById("MoveUp").onmouseout = function() {
MoveUp = false;
}
document.getElementById("MoveDow").onmouseout = function() {
MoveDow = false;
}
document.getElementById("MoveLeft").onmouseout = function() {
MoveLeft = false;
}
document.getElementById("MoveRight").onmouseout = function() {
MoveRight = false;
}
//上移
function MoveupFunction() {
if (CropImage_y <= 0) {
CropImage_y = 0;
} else {
CropImage_y--;
}
BackgroundImage();
}
//下移
function MoveDowFunction() {
let CropImage_Dowy = CropImage_y + CropImage_h;
if (CropImage_Dowy >= AnimatedZoomCanvas_h) {
CropImage_y = AnimatedZoomCanvas_h - CropImage_h;
} else {
CropImage_y++;
}
BackgroundImage();
}
//左移
function MoveLeftFunction() {
if (CropImage_x <= 0) {
CropImage_x = 0;
} else {
CropImage_x--;
}
BackgroundImage();
}
//右移
function MoveRightFunction() {
let CropImage_Rightx = CropImage_x + CropImage_w;
if (CropImage_Rightx >= AnimatedZoomCanvas_w) {
CropImage_x = AnimatedZoomCanvas_w - CropImage_w;
} else {
CropImage_x++;
}
BackgroundImage();
}
//scroll_Up函数
function scrollUp(scrollData) {
if (scrollData == 120) {
ZoomOut(1.1);
} else if (scrollData == 240) {
ZoomOut(1.3);
} else if (scrollData == 360) {
ZoomOut(1.5);
} else if (scrollData == 480) {
ZoomOut(1.9);
}
}
//scroll_Down函数
function scrollDown(scrollData) {
if (scrollData == -120) {
ZoomIn(1.1);
} else if (scrollData == -240) {
ZoomIn(1.3);
} else if (scrollData == -360) {
ZoomIn(1.5);
} else if (scrollData == -480) {
ZoomIn(1.9);
}
}
//滚动鼠标
AnimatedZoomCanvas.onmousewheel = function(e) {
let scrollData = e.wheelDelta;
if (CropImage_w <= AnimatedZoomCanvas_w && CropImage_h <= AnimatedZoomCanvas_w) {
scrollUp(scrollData);
scrollDown(scrollData);
} else {
Recover();
}
}
//添加鼠标按下事件
AnimatedZoomCanvas.onmousedown = function(e) {
let dmx = e.offsetX - CropImage_x;
let dmy = e.offsetY - CropImage_y;
if (AZctx.isPointInPath(e.offsetX, e.offsetY)) {
//路径正确,鼠标移动事件
AnimatedZoomCanvas.onmousemove = function(ev) {
CropImage_x = ev.offsetX - dmx;
CropImage_y = ev.offsetY - dmy;
//限制移动不能超出画布
if (CropImage_x <= 0) {
CropImage_x = 0;
}
if (CropImage_y <= 0) {
CropImage_y = 0;
}
let CropImage_Rightx = CropImage_x + CropImage_w;
if (CropImage_Rightx >= AnimatedZoomCanvas_w) {
CropImage_x = AnimatedZoomCanvas_w - CropImage_w;
}
let CropImage_Dowy = CropImage_y + CropImage_h;
if (CropImage_Dowy >= AnimatedZoomCanvas_h) {
CropImage_y = AnimatedZoomCanvas_h - CropImage_h;
}
//鼠标移动每一帧都清楚画布内容,然后重新画圆
AZctx.clearRect(0, 0, AnimatedZoomCanvas.width, AnimatedZoomCanvas.height);
BackgroundImage();
};
};
//鼠标抬起清除绑定事件
AnimatedZoomCanvas.onmouseup = function() {
AnimatedZoomCanvas.onmousemove = null;
AnimatedZoomCanvas.onmouseup = null;
};
AnimatedZoomCanvas.onmouseout = function() {
AnimatedZoomCanvas.onmouseup();
};
}
// console.log('鼠标移动坐标')
StageCanvas.onmousemove = function mouseMoveAction(e) {
document.getElementById("mouse_x").innerHTML = e.offsetX;
document.getElementById("mouse_y").innerHTML = e.offsetY;
};
})
</script>