zoukankan      html  css  js  c++  java
  • 关于图片缩放 移动

    ====================================================================
    image.vue
    ====================================================================
    <template>
        <transition name="viewer-fade">
            <div ref="bigImg" class="bigImg" v-show="visible">
                <div class="back_mask"></div>
                <span class="bigImg_close" @click='closebigImg'>
                    <Icon type="md-close-circle" class="bigImg_close_Icon"/>
                </span>
                <div class="bigImg_action" v-if="zoomFlag">
                        <span @click="handleActions('zoomOut')">缩小</span>
                        <span @click="handleActions('zoomIn')">放大</span>
                        <span @click="handleActions('anticlocelise')"><Icon type="ios-undo"/></span>
                        <span @click="handleActions('clocelise')"><Icon type="ios-redo"/></span>
                </div>
                <div class="bigImg_Box">
                    <img 
                        :src="showUrl" 
                        ref="img" 
                        alt="" 
                        class="bigImg_image" 
                        :style='imgStyle'
                        @mousedown="handleMouseDown"
                        @load="handleImgLoad"
                        @error="handleImgError"
                        >
                </div>
            </div>
            
        </transition>
    </template>
    <script>
        export default {
            name:'ShowLargeImage',
            props:{
                imageList:{
                    type: Array,
                    default: () => []
                },
                initialIndex: {
                    type: Number,
                    default: 0
                },
                zoomFlag:{
                    type: Boolean,
                    default: false
                }
            },
            data(){
                return {
                    index: this.initialIndex,
                    visible: false,
                    isloading: false,
                    isGrab: false,
                    transform: {
                        scale: 1,
                        deg: 0,
                        offsetX: 0,
                        offsetY: 0,
                        enableTransition: false
                    }
                }
            },
            mounted(){
                this.bingWheelKeyBaordEvent()
                
            },
            methods:{
                handleActions(action, options = {}) {
                    if (this.loading) return;
                    const { zoomRate, rotateDeg, enableTransition } = {
                        zoomRate: 0.2,
                        rotateDeg: 90,
                        enableTransition: true,
                        ...options
                    };
                    const { transform } = this;
                    switch (action) {
                        case 'zoomOut':
                            if (transform.scale > 0.2) {
                                transform.scale = parseFloat((transform.scale - zoomRate).toFixed(3));
                            }
                            break;
                        case 'zoomIn':
                            transform.scale = parseFloat((transform.scale + zoomRate).toFixed(3));
                            break;
                        case 'clocelise':
                            transform.deg += rotateDeg;
                            break;
                        case 'anticlocelise':
                            transform.deg -= rotateDeg;
                            break;
                    }
                    transform.enableTransition = enableTransition;
                },
                bingWheelKeyBaordEvent(){
                    this._mouseWheelHandler = this.rafThrottle(e => {
                        const delta = e.wheelDelta ? e.wheelDelta : -e.detail;
                        if (delta > 0) {
                            this.handleActions('zoomIn', {
                                zoomRate: 0.03,
                                enableTransition: false
                            });
                        } else {
                            this.handleActions('zoomOut', {
                                zoomRate: 0.03,
                                enableTransition: false
                            });
                        }
                    });
                    document.addEventListener('mousewheel', this._mouseWheelHandler, false);
                },
                handleImgLoad(){
                    this.isloading = false
                },
                handleImgError(){
                    this.isloading = false;
                    console.log('图片加载出错');
                    
                },
                rafThrottle(fn) {
                    let locked = false;
                    return function(...args) {
                        if (locked) return;
                        locked = true;
                        window.requestAnimationFrame(_ => {
                            fn.apply(this, args);
                            locked = false;
                        });
                    };
                },
                closebigImg(){
                    this.visible = false
                    this.$emit('close-bigImg');
                },
                handleMouseDown(e) {
                    if (this.loading || e.button !== 0) return;
                    const { offsetX, offsetY } = this.transform;
                    const startX = e.pageX;
                    const startY = e.pageY;
                    this._dragHandler = this.rafThrottle(ev => {
                        this.transform.offsetX = offsetX + ev.pageX - startX;
                        this.transform.offsetY = offsetY + ev.pageY - startY;
                    });
                    this.isGrab = true
                    document.addEventListener('mousemove', this._dragHandler, false);
                    document.addEventListener('mouseup', ev => {
                        this.isGrab = false
                        document.removeEventListener('mousemove', this._dragHandler, false);
                    }, false);
                    e.preventDefault();
                },
            },
            computed: {
                showUrl(){
                    return this.imageList[this.index];
                },
                isfirst(){
                    return this.index === 0;
                },
                isLast(){
                    return this.index === this.imageList.length - 1;
                },
                imgStyle(){
                    const { scale, deg, offsetX, offsetY, enableTransition } = this.transform;
                    const { isGrab } = this
                    const style = {
                        transform: `scale(${scale}) rotate(${deg}deg)`,
                        transition: enableTransition ? 'transform .3s' : '',
                        'margin-left': `${offsetX}px`,
                        'margin-top': `${offsetY}px`,
                        cursor: isGrab ? 'grabbing' : 'grab'
                    };
                    // if (this.mode === Mode.CONTAIN) {
                    //     style.maxWidth = style.maxHeight = '100%';
                    // }
                    return style;
                }
            },
            watch:{
                showUrl(val){
                    this.$nextTick(() => {
                        if(!this.$refs['img'].complete){
                            this.isloading = true
                        }
                    })
                }
            },
        }
    </script>
    <style scoped>
        .bigImg {
            position: fixed;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            z-index: 20000;
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none
        }
        .bigImg_Box{
            position: absolute;
            z-index: 230;
             100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .back_mask{
            position: absolute;
             100%;
            height: 100%;
            top: 0;
            left: 0;
            opacity: .5;
            background: #000
        }
        .bigImg_image{
            max-height: 95%;
            max- 90%;
            position: absolute;
            cursor: grab;
        }
        .bigImg_close{
            position: absolute;
            top: 50px;
            right: 100px;
            height: 30px;
             30px;
            z-index: 2222;
        }
        .bigImg_close_Icon{
            font-size: 30px;
            color: white;
        }
        .bigImg_action{
            position: absolute;
            bottom: 50px;
            left: calc(50% - 100px);
             200px;
            z-index: 250;
            height: 36px;
            display: flex;
            justify-content: space-evenly;
            align-items: center;
            border-radius: 18px;
            background: #eaeaea;
            color: #333333;
        }
        .bigImg_action span{
             24%;
            display: block;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
        }
    </style>
     
     
    ================================================================
    image.js      //新建vue    将上面的子组件包裹起来      初始化的将父vue初始化   然后将子组件显示。      中心思想就是: 道生一,一生二,二生三,三生万物,
    ================================================================
     
    import ShowLargeImage from './image.vue'
    import Vue from 'vue';

    ShowLargeImage.initialization = (props) =>{
        const _props = props || {};

        const Initialization = new Vue({
            data: Object.assign({}, _props, {
                imageList: [],
                initialIndex: 0,
                zoomFlag: false,
            }),
            render(h){
                return h(ShowLargeImage, {
                    props: Object.assign({}, _props, {
                        imageList: this.imageList,
                        initialIndex: this.initialIndex,
                        zoomFlag: this.zoomFlag,
                    }),
                    on:{
                       "close-bigImg": this.closeBigImg
                    }
                })
            },
            methods:{
                closeBigImg(){
                    this.$destroy();
                    document.body.removeChild(this.$el);
                    this.onRemove();
                },
            }
        })

        const component = Initialization.$mount();
        document.body.appendChild(component.$el);
        const showLargeImage = Initialization.$children[0];
        
        return {
            show(propsFun= {}){
                if ('imageList' in propsFun){
                    showLargeImage.$parent.imageList = propsFun.imageList
                }
                if ('initialIndex' in propsFun) {
                    showLargeImage.$parent.initialIndex = propsFun.initialIndex;
                }
                
                if('zoomFlag' in propsFun){
                    showLargeImage.$parent.zoomFlag = propsFun.zoomFlag
                }
                showLargeImage.$parent.onRemove = propsFun.onRemove;
                showLargeImage.visible = true;

            },
            remove(){
                showLargeImage.visible = false;
            },
            component: showLargeImage
        }   
    }


    export default ShowLargeImage;
     
     
    ================================================================
    index.js   将组件全局化
    ================================================================
    import ShowLargeImage from './image.js'

    let newShowLargeImage

    ShowLargeImage.show = function(props= {}){
        newShowLargeImage = newShowLargeImage || ShowLargeImage.initialization({props});
        props.onRemove = function(){
            newShowLargeImage = null;
        }
        newShowLargeImage.show(props);
    }

    ShowLargeImage.remove = function(){
        if(!newShowLargeImage){
            return
        }
        newShowLargeImage = null
    }


    const IShowLargeImage = {
        install: function(Vue){
            // Vue.component('IShowLargeImage', ShowLargeImage)
            Vue.prototype.IShowLargeImage = ShowLargeImage
        }
    }


    export default IShowLargeImage;
  • 相关阅读:
    Linux查看磁盘空间大小
    Qt常见错误
    顺序查找和二分查找代码
    字典树——动态&&静态
    Linux本机和远程服务器之间文件的上传和下载 rz sz
    牛顿迭代法——C语言
    MFC之ListControl选中行删除
    MFC之登录框的问题处理
    MFC之创建多级动态菜单
    c++动态内存知识总结与疑问
  • 原文地址:https://www.cnblogs.com/HePandeFeng/p/13032456.html
Copyright © 2011-2022 走看看