html+jquery实现简单图片裁剪

        有了上一篇图片放大镜的铺垫,今天的这个例子是缩小镜,因为裁剪的原图往往很大,不能在工作区域看到全部图片,所以,要有缩小镜来显示,当前裁剪的区域是原图的哪个部分.按照惯例首先看下效果图:

        功能一:载入默认图片

        功能二:选择本地图片

       功能三:拖拽(鼠标直接拖动工作区视窗)     

 

           功能四:放大,缩小(点击按钮放大/缩小0.5倍,鼠标滚轮图片缩放)

            功能五:利用canvas绘图裁剪图片

            以下是源码,分享下,防止忘记:

            html

<div id="workplace">
    <div id="workplacewrap">
        <div id="operateplace">
            <div class="showinfo">
            <span class="mouseposition">
                坐标(px):
                x:<span class="mouseposition-x">0</span>
                y:<span class="mouseposition-y">0</span>
            </span>
            </div>
            <div id="sourceImage">
                <img src="./images/show-window/timgjpg" alt="" draggable="false">
            </div>
            <div id="clipregion"></div>
            <div class="operation">
                <input id="fileselector" type="file" hidden style="">
                <label class="btn" for="fileselector">选择文件</label>
                <span id="btn-ResizeUp" class="btn">放大</span>
                <span id="btn-ResizeDown" class="btn">缩小</span>
                <span id="btn-Clip" class="btn">裁剪</span>
            </div>
        </div>
        <div id="showwindow">
            <div class="showinfo">
            <span class="mouseposition">
                坐标(px):
                x: <span class="mouseposition-x">0</span>
                y:<span class="mouseposition-y">0</span>
            </span>
            </div>
            <div style="position: absolute;">
                <div id="pologen"></div>
            </div>
            <div id="previewwindow">
                <img src="" alt="" draggable="false">
            </div>
            <div class="operation">
                <span class="btn">保存</span>
            </div>

        </div>
    </div>
</div>

         css

        * {
            font-size: 14px;
            letter-spacing: 1px;
            color: #000;
            -ms-text-justify: auto;
            text-justify: auto;
            font-size: 12px;
        }

        #workplace {
            width: 100%;
            height: auto;
            background: #f4f4f4;

        }

        #workplacewrap {
            margin: 0px auto;
            width: 1200px;
            display: flex;
            flex-direction: row;
            align-items: flex-start;
            justify-content: flex-start;
            border-right: 1px solid #f0f0f0;
            border-left: 1px solid #f0f0f0;
            background: #f4f4f4;
            font-family: "微软雅黑 Light";
            padding: 5px;
        }

        #operateplace {
            padding: 4px;
            border: 1px solid #bababa;

        }

        #sourceImage {
            width: 500px;
            height: 300px;
            border: 1px solid #bababa;
            background: none;
            margin-bottom: -1px;
            overflow: hidden;
        }

        #sourceImage img {
            position: relative;
            top: 0;
            left: 0;
        }

        .btn {
            background: #aa0000;
            border: #F8F8F8;
            color: white;
            padding: 5px;
        }

        .btn:hover {
            cursor: pointer;
            background: #cc1234;
        }

        .operation {
            display: flex;
            flex-direction: row;
            align-items: center;
            justify-content: space-around;
            height: 50px;
        }

        .showinfo {

            margin-bottom: -1px;
            font-size: 12px;
        }

        #showwindow {
            justify-self: flex-end;
            align-items: flex-end;
            width: 500px;
            height: auto;
            border: #baabba 1px solid;
            margin-left: 5px;
            padding: 5px;
            overflow: hidden;
            position:relative;
        }

        #previewwindow {
            border: 1px solid #bababa;
            width: 500px;
            height: 300px;
        }
        #pologen
        {
            border:1px solid red;
            position:relative;
            display:none;
        }

               javascript:

 class ClipTools {
        constructor() {
            this.workview = $('#sourceImage');
            this.showview = $('#previewwindow');

            this.workviewimg=$('#sourceImage>img');
            this.showviewimg = $('#previewwindow>img');
            this.workvwidth = 0;
            this.workvheight = 0;
            this.showvwidth = $('#sourceImage').width();
            this.showvheight = $('#sourceImage').height();

            //右侧显示区图片缩放后的高度
            this.showvimgheight=0;
            //右侧显示区图片缩放后的宽度
            this.showvimgwidth=0;
            this.resizeRate = 0.5;
            this.isScrollMouseResize = false;
            this.isClip=false;

            this.isMouseDown=false;

            this.workpos_x = 0;
            this.workpos_y = 0;

            //图片顶点位置
            this.sourceimg_l=0;
            this.sourceimg_t=0;

            this.lastMouse_x=0;
            this.lastMouse_y=0;

            this.sourceimg_w = 0;
            this.sourceimg_h = 0;

            this.enlargeratio = 1.0;

            //显示区图片和显示区域的比例
            this.showToSourceWidthRatio=0.1;
            this.showToSouceHeightRatio=0.1;

            this.Init = this.Init.bind(this);
            this.ImgInputFileChanged = this.ImgInputFileChanged.bind(this);
            this.ResizeUp = this.ResizeUp.bind(this);
            this.ResizeDown = this.ResizeDown.bind(this);
            this.ShowWorkPos = this.ShowWorkPos.bind(this);
            this.DrawClipRegionTosShow=this.DrawClipRegionTosShow.bind(this);
        }
        ShowWorkPos(x, y) {
            $('.mouseposition-x').text(this.workpos_x);
            $('.mouseposition-y').text(this.workpos_y);
            //console.log(`asdfa:${this.workpos_x}`);
            this.DrawClipRegionTosShow();
        }

        Init() {
            //如果工作区域有默认图片
            this.sourceimg_h = this.workviewimg.height();
            this.sourceimg_w = this.workviewimg.width();

            this.workvwidth = this.sourceimg_w;
            this.workvheight = this.sourceimg_h;

            this.showToSouceHeightRatio=this.showvheight/this.sourceimg_h;
            this.showToSourceWidthRatio=this.showvwidth/this.sourceimg_w;

            //右侧展示区域,展示当前工作区处于图片的区域
            //按照最小比例对图片进行缩放

            if (this.showToSouceHeightRatio<this.showToSourceWidthRatio)
            {
                this.showvimgheight=this.showvheight;
                this.showvimgwidth=this.showToSouceHeightRatio*this.sourceimg_w;
            }
            else
            {
                this.showvimgheight=this.sourceimg_h*this.showToSourceWidthRatio;
                this.showvimgwidth=this.showvwidth;
            }
            this.showviewimg.attr('src',this.workviewimg.attr('src')).width(this.showvimgwidth).height(this.showvimgheight);

            $('#btn-Clip').click(()=>{
                //if (!avatorImg.src) return;
                let _cropCanvas = document.createElement('canvas');
                // 计算边长
                //let _side = (showSide / avatorImg.offsetWidth) * primitiveLength.width;

                // 计算截取时从原图片的原始长度的坐标
                // 因为图片有可能会被放大/缩小,这时候,初始化时记录下来的primitiveLength信息就有用处了
                let _sy =-this.sourceimg_t/ (this.workvheight/this.sourceimg_h);
                let _sx=-this.sourceimg_l/(this.workvwidth/this.sourceimg_w);
                let _swidth=this.workview.width()/(this.workvwidth/this.sourceimg_w);
                let _sheight=this.workview.height()/(this.workvheight/this.sourceimg_h);
                let width=this.workview.width();
                let height=this.workview.height();
                //工作区域视窗就是图片的大小
                _cropCanvas.width = width;
                _cropCanvas.height = height;
                // 绘制图片
                _cropCanvas.getContext('2d').drawImage(this.workviewimg[0], _sx, _sy, _swidth, _sheight, 0, 0, width, height);
                // 保存图片信息
                let _lastImageData = _cropCanvas.toDataURL('image/png');
                // 将裁剪出来的信息展示
                this.showviewimg.attr({"src": _lastImageData,"width":width+"px","height":height+"px"});
                // imageShow.style.width = showSide + 'px';
                // imageShow.style.height = showSide + 'px';
                $('#pologen').css('display',"none");
                alert("裁剪成功");
            });
            $('#fileselector').on("change", this.ImgInputFileChanged);
            $("#btn-ResizeUp").click(this.ResizeUp);
            $("#btn-ResizeDown").click(this.ResizeDown);
            //this.DrawClipRegionTosShow();
            this.workviewimg.mousemove((e) => {

                if(this.isMouseDown)
                {
                    if (this.workviewimg)
                    var left_s= e.offsetX- this.lastMouse_x;
                    var top_s=e.offsetY-this.lastMouse_y;

                    this.sourceimg_l+=left_s;
                    this.sourceimg_t+=top_s;
                    this.workviewimg.css({"left":this.sourceimg_l+"px","top":this.sourceimg_t+"px"});
                }
                this.workpos_x = e.offsetX+this.sourceimg_l;
                this.workpos_y = e.offsetY+this.sourceimg_t;
                this.ShowWorkPos(e.offsetX,e.offsetY);
                //this.DrawClipRegionTosShow();
                return false;
            });
            //工作区滚轮事件,调整图片缩放
            this.workviewimg.on("mousewheel DOMMouseScroll",(e)=> {
                this.isScrollMouseResize=true;
                var delta = (e.originalEvent.wheelDelta && (e.originalEvent.wheelDelta > 0 ? 1 : -1)) ||  // chrome & ie
                    (e.originalEvent.detail && (e.originalEvent.detail > 0 ? -1 : 1));              // firefox

                if(delta>0)//向上滚
                {
                    if(this.enlargeratio>=1)
                    {
                        return;
                    }
                    this.workvwidth += 1;
                    this.workvheight +=this.sourceimg_h/this.sourceimg_w;
                }
                else if(delta<0)
                {
                    this.workvwidth -= 1;
                    this.workvheight -=this.sourceimg_h/this.sourceimg_w;
                }
                this.workviewimg.width(this.workvwidth);
                this.workviewimg.height(this.workvheight);
                //this.DrawClipRegionTosShow();
            });

            //工作区图片拖拽
            this.workviewimg.mousedown((e)=>{
                this.isMouseDown=true;
                 if(!this.isClip)
                 {
                     this.workviewimg.css({"cursor":"move"});
                 }
                 this.lastMouse_x=e.offsetX;
                 this.lastMouse_y=e.offsetY;
            });
            this.workviewimg.mouseleave((e)=>{
                this.isMouseDown=false;
                if(!this.isClip)
                {
                    this.workviewimg.css({"cursor":"default"});
                }
            });
            $('body').mouseup((e)=>{
                this.isMouseDown=false;
                if(!this.isClip)
                {
                    this.workviewimg.css({"cursor":"default"});
                }
            });
        }
        //在展示区域,标识出被截图的范围
        DrawClipRegionTosShow()
        {
            //1.首先将工作区左上角的位置还原到原图的位置,因为有滚轮的放大和缩小,所以原本定义在放大或者缩小按钮上的缩放比例不能再使用,要重新计算
            //不管是放大缩小按钮,还是滚轮缩放的比例在工作区都是一样的
               let rate= this.workvheight/this.sourceimg_h;
               let sourceLeft=this.sourceimg_l/rate;
               let sourceTop=this.sourceimg_t/rate;
               //计算在右侧展示区,缩放后投影裁剪区域的位置
            this.showToSouceHeightRatio=this.showvheight/this.workvheight;
            this.showToSourceWidthRatio=this.showvwidth/this.workvwidth;
            let showLeft=0;
            let showTop=0;
            let showWidth=0;
            let showHeight=0;
            if (this.showToSouceHeightRatio<this.showToSourceWidthRatio)
            {
                showWidth=this.workview.width()*this.showToSouceHeightRatio;
                showHeight=this.workview.height()*this.showToSouceHeightRatio;
                showLeft=-sourceLeft*this.showToSouceHeightRatio;
                showTop=-sourceTop*this.showToSouceHeightRatio;
            }
            else
            {
                showWidth=this.workview.width()*this.showToSourceWidthRatio;
                showHeight=this.workview.height()*this.showToSourceWidthRatio;
                showLeft=-sourceLeft*this.showToSourceWidthRatio;
                showTop=-sourceTop*this.showToSourceWidthRatio;
            }
            $('#pologen').css({"display":"block","top":showTop+"px","left":showLeft+"px","width":showWidth+"px","height":showHeight+"px"});

        }
        ResizeDown(e) {
            this.sourceimg_t=0;
            this.sourceimg_l=0;
            this.workviewimg.css({"left":this.sourceimg_l+"px","top":this.sourceimg_t+"px"});
            //鼠标滑轮调整过尺寸,则将图复原
            if (this.isScrollMouseResize) {
                this.enlargeratio = 1.0;
                this.workvwidth=this.sourceimg_w;
                this.workvheight=this.sourceimg_h;
                this.workviewimg.width(this.sourceimg_w);
                this.workviewimg.height(this.sourceimg_h);
            }
            this.isScrollMouseResize = false;
            if (this.workvheight < this.showvheight && this.workvwidth < this.showvwidth) {
                return;
            }
            else {
                this.enlargeratio *= this.resizeRate;
                this.workvwidth = this.sourceimg_w * this.enlargeratio;
                this.workvheight = this.sourceimg_h * this.enlargeratio;
                this.workviewimg.width(this.workvwidth);
                this.workviewimg.height(this.workvheight);
            this.DrawClipRegionTosShow();
            }
        }

        ResizeUp(e) {
            this.sourceimg_t=0;
            this.sourceimg_l=0;
            this.workviewimg.css({"left":this.sourceimg_l+"px","top":this.sourceimg_t+"px"});
            //鼠标滑轮调整过尺寸,则将图复原
            if (this.isScrollMouseResize) {
                this.enlargeratio = 1.0;
                this.workvwidth=this.sourceimg_w;
                this.workvheight=this.sourceimg_h;
                this.workviewimg.width(this.sourceimg_w);
                this.workviewimg.height(this.sourceimg_h);
            }
            this.isScrollMouseResize = false;
            if (this.enlargeratio >= 1) {
                return;
            }
            else {
                this.enlargeratio /= this.resizeRate;
                this.workvwidth = this.sourceimg_w * this.enlargeratio;
                this.workvheight = this.sourceimg_h * this.enlargeratio;
                this.workviewimg.width(this.workvwidth);
                this.workviewimg.height(this.workvheight);
            }
            this.DrawClipRegionTosShow();
        }
        ImgInputFileChanged(e) {
            let file = e.target.files[0];
            let reader = new FileReader();
            reader.onload = (e) => {
                this.workviewimg.attr('src', e.target.result);
            }
            reader.readAsDataURL(file);
            this.sourceimg_h = this.workviewimg.height();
            this.sourceimg_w = this.workviewimg.width();


            this.showToSouceHeightRatio=this.showvheight/this.sourceimg_h;
            this.showToSourceWidthRatio=this.showvwidth/this.sourceimg_w;

            //右侧展示区域,展示当前工作区处于图片的区域
            //按照短边的比例对图片进行缩放
            if (this.showToSouceHeightRatio<this.showToSourceWidthRatio)
            {
                this.showvimgheight=this.showvheight;
                this.showvimgwidth=this.showToSouceHeightRatio*this.sourceimg_w;
            }
            else
            {
                this.showvimgheight=this.sourceimg_h*this.showToSourceWidthRatio;
                this.showvimgwidth=this.showvwidth;
            }
            this.showviewimg.attr('src',this.workviewimg.attr('src')).width(this.showvimgwidth).height(this.showvimgheight);

            this.DrawClipRegionTosShow();

        }
    }

    $(function () {
        let clip = new ClipTools();
        clip.Init();
    })

          有问题,希望指正,本人刚接触前端不久,谢谢!

猜你喜欢

转载自www.cnblogs.com/andayhou/p/9380404.html