react移动端svg等图片拖拽缩放

react移动端图片缩放拖拽

 

使用es6类的方法实现



/**
 *定义svg,png,jpeg图片移动端缩放功能
 * 
 * 可拖拽,看缩放
    let zoomEl = document.getElementById('zoomEl');
    let zoom = new Zoom({
        el:zoomEl,
        options:{'top': zoomEl.offsetTop+50, 'left': zoomEl.offsetLeft+50, 'width': 400, 'height': 400 }
    });
    zoom.setScale(1)
 * @class Zoom
 */
class Zoom{
    
    /**
     *Creates an instance of Zoom.
     * @param {el,options:{top,left,width,height}} ops 参数配置
     * @memberof Zoom
     */
    constructor(ops){
        //参数配置
        this.ops = Object.assign({
            minScale:1,
            maxScale:3,
            top:50,
            left:50,
        },ops.options)
        //展示的存放容器
        this.el = ops.el;

        this.lastSapce = 0;
        this.touchState = 0;
        this.lastPoint = null;
        this.targetPoint = null;
        //放大缩小的倍数 当前缩放倍数
        this.minScale = this.ops.minScale || 1;
        this.maxScale = this.ops.maxScale || 10;

        // dom 的尺寸参数
        this.width = this.ops.width;
        this.height = this.ops.height;
        this.top = this.ops.top;
        this.left = this.ops.left;
        this.scale = 1;

        // 初始位置以及初始宽高
        this.originTop = this.ops.top;
        this.originLeft = this.ops.left;
        this.originW = this.width;
        this.originH = this.height;
        
        // 图片中心点
        this.centerX = this.left + this.originW/2;
        this.centerY = this.top  + this.originH/2;
        this.el.style.position = "absolute";
        this.init();
    }

    /**
     *初始化数据
     *
     * @memberof Zoom
     */
    init(){
        this.el.addEventListener('touchmove',this.touchmoveHandler);
        this.el.addEventListener('touchstart',this.touchmoveHandler);
        this.el.addEventListener('touchend',this.touchEndHandler);
        this.el.addEventListener('touchcancel',this.touchEndHandler);
        this.el.addEventListener('touchstart',this.dbclickHandler);
        this.el.zoom = this;
    }

    getTouches(event){
        let touches = event.touches;
        if(!touches){
            touches = event.originalEvent.touches;
        }
        return touches;
    }

    getTouchsDistance(t1,t2){
        let dx = parseInt(t1.pageX - t2.pageX);
        let dy = parseInt(t1.pageY - t2.pageY);

        let d = Math.pow((dx*dx+dy+dy),0.8);
        return d.toFixed(5); 
    }

    restView(){
        this.el.style.width = this.width +"px";
        this.el.style.height = this.height +"px";
        this.el.style.top = this.top +"px";
        this.el.style.left = this.left +"px";
    }

    dbclickHandler(event){
        event.stopPropagation();
        event.preventDefault();

        let el = event.currentTarget;
        let zoom = el.zoom;
        let time = new Date(event.timeStamp).getTime();
        let touchs = zoom.getTouches(event);
        if (touchs.length == 1) {
            if (!el.lastClickTime) {
                el.lastClickTime = time;
            }else{
                if (time - el.lastClickTime < 300) {
                    el.lastClickTime = 0;
                    if (zoom.scale != 1) {
                        zoom.setScale(1);
                    }else if(zoom.scale == 1){
                        zoom.setScale(2);
                    }
                }else{
                    el.lastClickTime = time;
                }
            }
        }
        zoom.touchStartTime = new Date().getTime();
        return false;
    }

    drage(touch){
        if (this.lastPoint == null) {
            this.lastPoint = {
                x:touch.pageX,
                y:touch.pageY,
            }
        }else{
            let dx = parseInt(touch.pageX - this.lastPoint.x);
            let dy = parseInt(touch.pageY - this.lastPoint.y);


            this.lastPoint.x = touch.pageX;
            this.lastPoint.y = touch.pageY;

            this.left += dx;
            this.top += dy;

            this.setTransform(false);
        } 
    }

    zoom(touchs){
        this.lastPoint = null;
        let t1 = touchs[0];
        let t2 = touchs[1];

        let x1 = t1.pageX;
        let x2 = t2.pageX;
        let y1 = t1.pageY;
        let y2 = t2.pageY;

        let d = this.getTouchsDistance(t1,t2);

        if (this.touchState == 0) {
            this.lastSapce = d;
            this.touchState = 1;

            this.pointX = (x2 + (x1 - x2) / 2 - this.left)/this.scale;
            this.pointY = (y2 + (y1 - y2) / 2 - this.top)/this.scale;
        }else if(this.touchState == 1){

            let scaleChange = ((d / this.lastSapce) - 1) * 2;

            let scale = this.scale + scaleChange / 2;

            this.setScale(scale,this.pointX,this.pointY);

            this.lastSapce = d;
        }
    }

    touchmoveHandler(event){
        event.stopPropagation();
        event.preventDefault();
        let el = event.currentTarget;
        let zoom = el.zoom;
        let touchs = zoom.getTouches(event);
        if (touchs.length == 1) {
            zoom.drage(touchs[0]);//拖动处理
        }else if (touchs.length >= 2) {
            zoom.lastPoint = null;//终止拖动事件
            zoom.zoom(touchs);//缩放处理

        }
        return false;
    }

    touchEndHandler(event){
        let zoom = event.currentTarget.zoom;

        zoom.touchState = 0;
        zoom.lastPoint = null;
        zoom.lastSapce = 0;

        let minSpace = 20;
        let parentWidth = zoom.el.parentElement.offsetWidth;
        let parentHight =zoom.el.parentElement.offsetHeight;
        let scale = zoom.scale;

        if(scale < zoom.minScale){
            scale = zoom.minScale;
        }
        if(scale > zoom.maxScale){
            scale = zoom.maxScale;
        }

        if(scale != zoom.scale){
            zoom.preSetScale(scale,zoom.lastPointX,zoom.lastPointY);
        }

        if((zoom.left + zoom.width) < minSpace){
                zoom.left = - zoom.width + minSpace;
        }
        if(zoom.left >= (parentWidth - minSpace)){
                zoom.left = parentWidth - minSpace;
        }

        if((zoom.top + zoom.height) < minSpace){
            zoom.top = - zoom.height + minSpace;
        }
        if(zoom.top >= (parentHight - minSpace)){
            zoom.top = parentHight - minSpace;
        }
        zoom.setTransform(true);
        return;  
    }

    setTransform(needAnimation,originX,originY){
        let distanceX = this.left - this.originLeft;
        let distanceY = this.top - this.originTop;
        let scale = this.scale;
        originX = originX == undefined ? (this.originTop + 'px') : originX;
        originY = originY == undefined ? (this.originLeft + 'px') : originY;
        this.el.style.transformOrigin = 'left top';
        this.el.style.transform = 'matrix('+scale+',0,0,'+scale+','+distanceX+','+distanceY+')';
        if(needAnimation == true){
            this.el.style.transition = 'all .3s ease-in-out 0s'
        }else{
            this.el.style.transition = ''
        }
    }

    destroy(){
        this.el.removeEventListener('touchmove',this.touchmoveHandler);
        this.el.removeEventListener('touchstart',this.touchmoveHandler);
        this.el.removeEventListener('touchend',this.touchEndHandler);
        this.el.removeEventListener('touchcancel',this.touchEndHandler);

        this.el.zoom = null;
    }

    setScale(scale,pointX,pointY){
        this.preSetScale(scale,pointX,pointY);
        this.setTransform(false);
    }

    preSetScale(scale,pointX,pointY){
        if (scale < 0.5) {
            scale = 0.5;
        }

        if (pointX ==undefined) {
            this.left = this.centerX - this.originW / 2 - this.originW/2*(scale - 1);
            this.top = this.centerY - this.originH / 2 - this.originH/2*(scale - 1);
            this.width = scale * this.originW;
            this.height = scale * this.originH;
            this.scale = scale;
        }else{
            this.width = scale * this.originW;
            this.height = scale * this.originH;
            this.left = this.left - pointX * (scale - this.scale);
            this.top = this.top - pointY * (scale - this.scale);
            this.lastPointX = pointX;
            this.lastPointY = pointY;
            this.scale = scale;
        }
    }
}
export default Zoom;

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

随风小薇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值