Canvas_ZoomIn_ZoomOut

基于Canvas的扩大与缩小功能。其原理为:

file

按照上图的原理,做一个扩大缩小的功能,需要画三个canvas的窗口。可以隐藏原图(A窗口),用户看到的只有BC窗口。如图:

file

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>

当然,还加入了扩大缩小功能,鼠标长按功能,滚轮控制功能,滚轮倍率功能。

file

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>

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注