【sgDragMoveTile】自定义组件:拖拽瓦片图、地图、大图,滚动条对应同步滚动

简介: 【sgDragMoveTile】自定义组件:拖拽瓦片图、地图、大图,滚动条对应同步滚动


特性:

  1. 可以自定义拖拽过程鼠标样式
  2. 可以禁止拖拽
  3. 动态设置拖拽和滚动区域元素

sgDragMoveTile源码

<template>
    <div :class="$options.name"> </div>
</template>
<script>
export default {
    name: 'sgDragMoveTile',
    data() {
        return {
            scrollContainer: null,
            dragContainer: null,
        }
    },
    props: [
        "data",
        /*data格式:{
            scrollContainer:滚动条容器的element,
            dragContainer:拖拽的element,
        }*/
        "disabled",//是否禁用
        "cursor",//鼠标样式
        /*cursor格式说明:{
            grab:'default',//移入可拖拽区域的鼠标样式
            grabbing:'default',//拖拽过程中鼠标样式
        }*/
    ],
    watch: {
        data: {
            handler(newValue, oldValue) {
                if (newValue && Object.keys(newValue).length) {
                    newValue.scrollContainer && (this.scrollContainer = newValue.scrollContainer);
                    newValue.dragContainer && (this.dragContainer = newValue.dragContainer);
                    this.addEvents();
                } else {
                    this.removeEvents();
                }
            },
            deep: true,//深度监听
            immediate: true,//立即执行
        },
        disabled: {
            handler(newValue, oldValue) {
                newValue ? this.removeEvents() : this.addEvents();
            }, deep: true, immediate: true,
        },
    },
    mounted() {
        this.$parent.$el.style.setProperty("--sgDragMoveTile-grab", (this.cursor || {}).grab || 'grab'); //js往css传递局部参数
        this.$parent.$el.style.setProperty("--sgDragMoveTile-grabbing", (this.cursor || {}).grabbing || 'grabbing'); //js往css传递局部参数
    },
    methods: {
        addEvents(d) {
            this.removeEvents();
            if (this.dragContainer) {
                this.dragContainer.setAttribute('sgDragMoveTile_grab', 'ready');
                this.dragContainer.addEventListener('mousedown', this.mousedown);
            }
        },
        removeEvents(d) {
            if (this.dragContainer) {
                this.dragContainer.removeAttribute('sgDragMoveTile_grab');
                this.dragContainer.removeEventListener('mousedown', this.mousedown);
            }
            removeEventListener('mouseup', this.mouseup);
        },
        mousedown(e) {
            this.$emit(`dragStart`, e);
            if (!this.isNotAllowedDrag()) return;
            this.dragContainer.setAttribute('sgDragMoveTile_grab', 'down');
            let scrollContainer = this.scrollContainer;
            let dragContainer = this.dragContainer;
            //鼠标按下那一刻,滚动条的位置
            let mouseDownScrollPosition = {
                scrollLeft: scrollContainer.scrollLeft,
                scrollTop: scrollContainer.scrollTop
            };
            //鼠标按下的位置坐标
            let mouseDownPoint = {
                x: e.clientX,
                y: e.clientY
            };
            dragContainer.onmousemove = e => {
                //鼠标滑动的实时距离
                let dragMoveDiff = {
                    x: mouseDownPoint.x - e.clientX,
                    y: mouseDownPoint.y - e.clientY
                };
                scrollContainer.scrollLeft = mouseDownScrollPosition.scrollLeft + dragMoveDiff.x;
                scrollContainer.scrollTop = mouseDownScrollPosition.scrollTop + dragMoveDiff.y;
                this.$emit(`dragMove`, e);
            };
            addEventListener('mouseup', this.mouseup);
        },
        mouseup(e) {
            this.dragContainer.onmousemove = null;
            removeEventListener('mouseup', this.mouseup);
            this.isNotAllowedDrag();
            this.$emit(`dragEnd`, e);
        },
        isNotAllowedDrag(d) {
            let scrollContainer = this.scrollContainer, rect_scrollContainer = scrollContainer.getBoundingClientRect();
            let dragContainer = this.dragContainer, rect_dragContainer = dragContainer.getBoundingClientRect();
            // 滚动区域不小于拖拽区域
            if (rect_scrollContainer.width >= rect_dragContainer.width && rect_scrollContainer.height >= rect_dragContainer.height) {
                this.dragContainer.setAttribute('sgDragMoveTile_grab', 'not-allowed');
                return false;
            } else {
                this.dragContainer.setAttribute('sgDragMoveTile_grab', 'ready');
                return true;
            }
        },
    },
    destroyed() {
        this.removeEvents();
    },
};
</script>
<style lang="scss" >
[sgDragMoveTile_grab="ready"] {
    /*禁止选中文本*/
    user-select: none;
    cursor: var(--sgDragMoveTile-grab); //css获取js传递的参数
    * {
        cursor: var(--sgDragMoveTile-grab); //css获取js传递的参数
    }
}
[sgDragMoveTile_grab="down"] {
    /*禁止选中文本*/
    user-select: none;
    cursor: var(--sgDragMoveTile-grabbing); //css获取js传递的参数
    * {
        cursor: var(--sgDragMoveTile-grabbing); //css获取js传递的参数
    }
}
[sgDragMoveTile_grab="not-allowed"] {
    /*禁止选中文本*/
    user-select: none;
    cursor: not-allowed;
    * {
        cursor: not-allowed;
    }
}
</style>

用例

<template>
  <div :class="$options.name">
    <div class="sg-ctrl">
      <label>缩放百分比</label>
      <el-input-number style="width: 150px;" v-model.trim="scaleValue" :precision="0" :step="10" :min="10" :max="100"
        :controls-position="`left`" />
    </div>
    <div class="sg-tile-img" ref="scrollContainer">
      <div ref="dragContainer" :style="{ width: `${tileSize * colCount}px` }">
        <img v-for="(a, i) in tiles" :key="i" :loading="a.loading" :width="tileSize" :height="tileSize">
      </div>
    </div>
    <sgDragMoveTile :data="dragMoveTileData" />
  </div>
</template>
<script>
import sgDragMoveTile from "@/vue/components/admin/sgDragMoveTile";
export default {
  name: 'sgTileImage',
  components: {
    sgDragMoveTile
  },
  data() {
    return {
      dragMoveTileData: {},
      scaleValue: 100,
      orginTileSize: 0,
      tileSize: 0,
      colCount: 0,
      rowCount: 0,
      tiles: [],//瓦片图数组
    }
  },
  watch: {
    data: {
      handler(newValue, oldValue) {
        let len = 144;//瓦片图数量
        this.tiles = [...Array(len)].map(v => ({
          loading: false,
        }));
        this.orginTileSize = 500
        this.colCount = Math.sqrt(len)
        this.rowCount = Math.sqrt(len)
        console.log(this.tiles)
      },
      deep: true,//深度监听
      immediate: true,//立即执行
    },
    scaleValue: {
      handler(newValue, oldValue) {
        this.tileSize = this.orginTileSize * newValue / 100;
      },
      deep: true,//深度监听
      immediate: true,//立即执行
    },
  },
  mounted() {
    this.dragMoveTileData = {
      scrollContainer: this.$refs.scrollContainer,
      dragContainer: this.$refs.dragContainer,
    }
  },
};
</script>
<style lang="scss" scoped> 
.sgTileImage {  
   .sg-ctrl {
     position: absolute;
     right: 0;
     top: 0;
     z-index: 1;
     box-sizing: border-box;
     padding: 10px 20px;
     background-color: white;
     box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
     border-radius: 4px;
     display: flex;
     align-items: center;
     justify-content: flex-end;
     label {
       margin-right: 10px;
     }
   }
   .sg-tile-img {
     position: absolute;
     left: 0;
     top: 0;
     overflow: auto;
     width: 100%;
     height: 100%;
     div {
       display: flex;
       flex-wrap: wrap;
       img {
         border: none;
       }
     }
   }
 }
</style>

关联文章

image.png


相关文章
|
定位技术
百度地图:监听地图缩放自动显示和隐藏的富文本标签
百度地图:监听地图缩放自动显示和隐藏的富文本标签
206 0
|
5月前
|
前端开发
Canvas之拖拽方块并实时重绘
Canvas之拖拽方块并实时重绘
|
7月前
|
索引
【sgPhotoPlayer】自定义组件:图片预览,支持点击放大、缩小、旋转图片
【sgPhotoPlayer】自定义组件:图片预览,支持点击放大、缩小、旋转图片
|
7月前
Echarts图表设置x轴y轴均随滚轮滚动缩+放 区域缩放
Echarts图表设置x轴y轴均随滚轮滚动缩+放 区域缩放
605 0
|
7月前
【sgDragMove】自定义组件:自定义拖拽组件,仅支持拖拽、设置吸附屏幕边界距离。
【sgDragMove】自定义组件:自定义拖拽组件,仅支持拖拽、设置吸附屏幕边界距离。
|
7月前
|
测试技术
【sgTileImage】自定义组件:瓦片图拖拽局部加载、实现以鼠标为中心缩放
【sgTileImage】自定义组件:瓦片图拖拽局部加载、实现以鼠标为中心缩放
|
图形学
|
JavaScript 前端开发 UED
vue实现一个鼠标滑动预览视频封面组件(精灵图版本)
vue实现一个鼠标滑动预览视频封面组件(精灵图版本)
295 0
|
定位技术
echarts. registerMap选项specialAreas将地图中的部分区域缩放到合适的位置,可以使得整个地图的显示更加好看
echarts. registerMap选项specialAreas将地图中的部分区域缩放到合适的位置,可以使得整个地图的显示更加好看
161 0
图片和文件预览组件(部分源码),可拖动,缩小,放大。 #41
图片和文件预览组件(部分源码),可拖动,缩小,放大。 #41
152 0
下一篇
DataWorks