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


    特性

    1. 可以自定义拖拽过程鼠标样式
    2. 可以禁止拖拽
    3. 动态设置拖拽和滚动区域元素
    4. 支持监听滚动条@scroll事件

    sgDragMoveTile源码

    1. <template>
    2. <div :class="$options.name">div>
    3. template>
    4. <script>
    5. export default {
    6. name: "sgDragMoveTile",
    7. data() {
    8. return {
    9. scrollContainer: null,
    10. dragContainer: null,
    11. };
    12. },
    13. props: [
    14. "data",
    15. /*data格式:{
    16. scrollContainer:滚动条容器的element,
    17. dragContainer:拖拽的element,
    18. }*/
    19. "disabled", //是否禁用
    20. "cursor", //鼠标样式
    21. /*cursor格式说明:{
    22. grab:'default',//移入可拖拽区域的鼠标样式
    23. grabbing:'default',//拖拽过程中鼠标样式
    24. }*/
    25. ],
    26. watch: {
    27. data: {
    28. handler(newValue, oldValue) {
    29. if (newValue && Object.keys(newValue).length) {
    30. newValue.scrollContainer && (this.scrollContainer = newValue.scrollContainer);
    31. newValue.dragContainer && (this.dragContainer = newValue.dragContainer);
    32. this.addEvents();
    33. } else {
    34. this.removeEvents();
    35. }
    36. },
    37. deep: true, //深度监听
    38. immediate: true, //立即执行
    39. },
    40. disabled: {
    41. handler(newValue, oldValue) {
    42. newValue ? this.removeEvents() : this.addEvents();
    43. },
    44. deep: true,
    45. immediate: true,
    46. },
    47. },
    48. mounted() {
    49. this.$parent.$el.style.setProperty(
    50. "--sgDragMoveTile-grab",
    51. (this.cursor || {}).grab || "grab"
    52. ); //js往css传递局部参数
    53. this.$parent.$el.style.setProperty(
    54. "--sgDragMoveTile-grabbing",
    55. (this.cursor || {}).grabbing || "grabbing"
    56. ); //js往css传递局部参数
    57. },
    58. methods: {
    59. addEvents(d) {
    60. this.removeEvents();
    61. if (this.dragContainer) {
    62. this.dragContainer.setAttribute("sgDragMoveTile_grab", "ready");
    63. this.dragContainer.addEventListener("mousedown", this.mousedown);
    64. }
    65. if (this.scrollContainer) {
    66. this.scrollContainer.addEventListener("scroll", this.scroll);
    67. }
    68. },
    69. removeEvents(d) {
    70. if (this.dragContainer) {
    71. this.dragContainer.removeAttribute("sgDragMoveTile_grab");
    72. this.dragContainer.removeEventListener("mousedown", this.mousedown);
    73. }
    74. if (this.scrollContainer) {
    75. this.scrollContainer.removeEventListener("scroll", this.scroll);
    76. }
    77. removeEventListener("mouseup", this.mouseup);
    78. },
    79. scroll(e) {
    80. this.$emit(`scroll`, e);
    81. },
    82. mousedown(e) {
    83. this.$emit(`dragStart`, e);
    84. if (!this.isNotAllowedDrag()) return;
    85. this.dragContainer.setAttribute("sgDragMoveTile_grab", "down");
    86. let scrollContainer = this.scrollContainer;
    87. let dragContainer = this.dragContainer;
    88. //鼠标按下那一刻,滚动条的位置
    89. let mouseDownScrollPosition = {
    90. scrollLeft: scrollContainer.scrollLeft,
    91. scrollTop: scrollContainer.scrollTop,
    92. };
    93. //鼠标按下的位置坐标
    94. let mouseDownPoint = {
    95. x: e.clientX,
    96. y: e.clientY,
    97. };
    98. dragContainer.onmousemove = (e) => {
    99. //鼠标滑动的实时距离
    100. let dragMoveDiff = {
    101. x: mouseDownPoint.x - e.clientX,
    102. y: mouseDownPoint.y - e.clientY,
    103. };
    104. scrollContainer.scrollLeft = mouseDownScrollPosition.scrollLeft + dragMoveDiff.x;
    105. scrollContainer.scrollTop = mouseDownScrollPosition.scrollTop + dragMoveDiff.y;
    106. this.$emit(`dragMove`, e, {
    107. scrollLeft: scrollContainer.scrollLeft,
    108. scrollTop: scrollContainer.scrollTop,
    109. });
    110. };
    111. addEventListener("mouseup", this.mouseup);
    112. },
    113. mouseup(e) {
    114. this.dragContainer.onmousemove = null;
    115. removeEventListener("mouseup", this.mouseup);
    116. this.isNotAllowedDrag();
    117. this.$emit(`dragEnd`, e);
    118. },
    119. isNotAllowedDrag(d) {
    120. let scrollContainer = this.scrollContainer,
    121. rect_scrollContainer = scrollContainer.getBoundingClientRect();
    122. let dragContainer = this.dragContainer,
    123. rect_dragContainer = dragContainer.getBoundingClientRect();
    124. // 滚动区域不小于拖拽区域
    125. if (
    126. rect_scrollContainer.width >= rect_dragContainer.width &&
    127. rect_scrollContainer.height >= rect_dragContainer.height
    128. ) {
    129. this.dragContainer.setAttribute("sgDragMoveTile_grab", "not-allowed");
    130. return false;
    131. } else {
    132. this.dragContainer.setAttribute("sgDragMoveTile_grab", "ready");
    133. return true;
    134. }
    135. },
    136. },
    137. destroyed() {
    138. this.removeEvents();
    139. },
    140. };
    141. script>
    142. <style lang="scss">
    143. [sgDragMoveTile_grab="ready"] {
    144. /*禁止选中文本*/
    145. user-select: none;
    146. cursor: var(--sgDragMoveTile-grab); //css获取js传递的参数
    147. * {
    148. cursor: var(--sgDragMoveTile-grab); //css获取js传递的参数
    149. }
    150. }
    151. [sgDragMoveTile_grab="down"] {
    152. /*禁止选中文本*/
    153. user-select: none;
    154. cursor: var(--sgDragMoveTile-grabbing); //css获取js传递的参数
    155. * {
    156. cursor: var(--sgDragMoveTile-grabbing); //css获取js传递的参数
    157. }
    158. }
    159. [sgDragMoveTile_grab="not-allowed"] {
    160. /*禁止选中文本*/
    161. user-select: none;
    162. cursor: not-allowed;
    163. * {
    164. cursor: not-allowed;
    165. }
    166. }
    167. style>

    用例

    1. <template>
    2. <div :class="$options.name">
    3. <div class="sg-ctrl">
    4. <label>缩放百分比label>
    5. <el-input-number style="width: 150px;" v-model.trim="scaleValue" :precision="0" :step="10" :min="10" :max="100"
    6. :controls-position="`left`" />
    7. div>
    8. <div class="sg-tile-img" ref="scrollContainer">
    9. <div ref="dragContainer" :style="{ width: `${tileSize * colCount}px` }">
    10. <img v-for="(a, i) in tiles" :key="i" :loading="a.loading" :width="tileSize" :height="tileSize">
    11. div>
    12. div>
    13. <sgDragMoveTile :data="dragMoveTileData" />
    14. div>
    15. template>
    16. <script>
    17. import sgDragMoveTile from "@/vue/components/admin/sgDragMoveTile";
    18. export default {
    19. name: 'sgTileImage',
    20. components: {
    21. sgDragMoveTile
    22. },
    23. data() {
    24. return {
    25. dragMoveTileData: {},
    26. scaleValue: 100,
    27. orginTileSize: 0,
    28. tileSize: 0,
    29. colCount: 0,
    30. rowCount: 0,
    31. tiles: [],//瓦片图数组
    32. }
    33. },
    34. watch: {
    35. data: {
    36. handler(newValue, oldValue) {
    37. let len = 144;//瓦片图数量
    38. this.tiles = [...Array(len)].map(v => ({
    39. loading: false,
    40. }));
    41. this.orginTileSize = 500
    42. this.colCount = Math.sqrt(len)
    43. this.rowCount = Math.sqrt(len)
    44. console.log(this.tiles)
    45. },
    46. deep: true,//深度监听
    47. immediate: true,//立即执行
    48. },
    49. scaleValue: {
    50. handler(newValue, oldValue) {
    51. this.tileSize = this.orginTileSize * newValue / 100;
    52. },
    53. deep: true,//深度监听
    54. immediate: true,//立即执行
    55. },
    56. },
    57. mounted() {
    58. this.dragMoveTileData = {
    59. scrollContainer: this.$refs.scrollContainer,
    60. dragContainer: this.$refs.dragContainer,
    61. }
    62. },
    63. };
    64. script>
    65. <style lang="scss" scoped>
    66. .sgTileImage {
    67. .sg-ctrl {
    68. position: absolute;
    69. right: 0;
    70. top: 0;
    71. z-index: 1;
    72. box-sizing: border-box;
    73. padding: 10px 20px;
    74. background-color: white;
    75. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    76. border-radius: 4px;
    77. display: flex;
    78. align-items: center;
    79. justify-content: flex-end;
    80. label {
    81. margin-right: 10px;
    82. }
    83. }
    84. .sg-tile-img {
    85. position: absolute;
    86. left: 0;
    87. top: 0;
    88. overflow: auto;
    89. width: 100%;
    90. height: 100%;
    91. div {
    92. display: flex;
    93. flex-wrap: wrap;
    94. img {
    95. border: none;
    96. }
    97. }
    98. }
    99. }
    100. style>

    关联文章【经典】原生JS实现“用鼠标拖拽(drag)内容DIV”,滚动条对应同步滚动_js拖拽时索引条跟着拖动_你挚爱的强哥的博客-CSDN博客【代码】【经典】原生JS实现“用鼠标拖拽(drag)内容DIV”,滚动条对应同步滚动。_js拖拽时索引条跟着拖动https://blog.csdn.net/qq_37860634/article/details/127253779

  • 相关阅读:
    【云开发】小程序端中使用云函数的介绍
    ubuntu18.04安装并运行ORB-SLAM2
    IP风险画像 金融行业的安全盾牌
    运用精益管理思想提升MES管理系统建设水平
    【利用冒泡排序的思想模拟实现qsort函数】
    excel如何调整日期格式的方法
    python根据一个文件中的key和另外一个文件key对比,同时提取value
    SSM学习——apipost测试几种常用的请求与响应(11)
    AI四维彩超预测宝宝长相图片生成流量主小程序开发
    Java学习笔记------内部类
  • 原文地址:https://blog.csdn.net/qq_37860634/article/details/133292981