【leader-line-vue移动svg(指示线元素)到另外一个容器中(定位基准)】

1 篇文章 0 订阅
1 篇文章 0 订阅

leader-line-vue移动svg(指示线元素)到另外一个容器中(定位基准)

leader-line 绘制的svg指示线是利用相对于 body 的 absolute 定位。而在移动端给body的布局高度为 height:100%,页面是在body局部滚动的,所以指示线的位置相对body始终是固定的,在屏幕上看起来也就是固定不变的。leader-line 绘制的svg指示线是利用相对于 body 的 absolute 定位。而在移动端给body的布局高度为 height:100%,页面是在body局部滚动的,所以指示线的位置相对body始终是固定的,在屏幕上看起来也就是固定不变的。

查看代码

<template>
  <div class="HelloWorld">
    <div id="frame">
      <div id="container">
        <div id="terminal-1" class="terminal"></div>
        <div id="terminal-2" class="terminal"></div>
        <div id="terminal-3" class="terminal"></div>
      </div>
    </div>

    <svg version="1.1" id="svg-clip">
      <defs>
        <rect id="clip-rect" />
        <clipPath id="clip-1">
          <use xlink:href="#clip-rect" />
        </clipPath>
        <clipPath id="clip-2">
          <use xlink:href="#clip-rect" />
        </clipPath>
      </defs>
    </svg>
  </div>
</template>
<script>
import LeaderLine from "leader-line-vue";
import AnimEvent from "anim-event";
export default {
  name: "HelloWorld",
  data() {
    return {};
  },
  mounted() {
    this.$nextTick(() => {
      this.InitFun();
    });
  },
  beforeDestroy() {
    /**
     * 离开页面时销毁所有line
     */
    // this.ClearAllLine();
  },
  methods: {
    InitFun() {
      var elmFrame = document.getElementById("frame"),
        rectFrame = elmFrame.getBoundingClientRect(),
        elmClipRect = document.getElementById("clip-rect"),
        line1 = LeaderLine.setLine(
          document.getElementById("terminal-1"),
          document.getElementById("terminal-2")
        ),
        elmLine1 = document.querySelector(".leader-line:last-of-type"),
        elmRefClipRect1 = document.querySelector("#clip-1>use"),
        line2 = LeaderLine.setLine(
          document.getElementById("terminal-3"),
          line1.end
        ),
        elmLine2 = document.querySelector(".leader-line:last-of-type"),
        elmRefClipRect2 = document.querySelector("#clip-2>use");

      function update() {
        line1.position();
        line2.position();
        // Adjust clip position
        var rectLine = elmLine1.getBoundingClientRect();
        elmRefClipRect1.x.baseVal.value = rectFrame.left - rectLine.left;
        elmRefClipRect1.y.baseVal.value = rectFrame.top - rectLine.top;
        rectLine = elmLine2.getBoundingClientRect();
        elmRefClipRect2.x.baseVal.value = rectFrame.left - rectLine.left;
        elmRefClipRect2.y.baseVal.value = rectFrame.top - rectLine.top;
      }

      // Init clip size
      elmClipRect.width.baseVal.value = elmFrame.clientWidth;
      elmClipRect.height.baseVal.value = elmFrame.clientHeight;
      elmLine1.style.clipPath = "url(#clip-1)";
      elmLine2.style.clipPath = "url(#clip-2)";
      elmFrame.addEventListener("scroll", AnimEvent.add(update), false);
      update();
    },
    /**
     * 监听滚动条变化各部分连线跟随变化
     */
    AddEventListenerSrollFun() {
      window.addEventListener(
        "scroll",
        AnimEvent.add(() => {
          d3.selectAll(".leader-line").remove();
          this.lines1 = [];
          this.lines2 = [];
          this.lines3 = [];
          this.DrawLeaderLine1();
          this.DrawLeaderLine2();
          this.DrawLeaderLine3();
        }),
        false
      );
      let scrollableBox1 = document.getElementsByClassName("FirstContent")[0];
      scrollableBox1.addEventListener(
        "scroll",
        AnimEvent.add(() => {
          d3.selectAll(".leader-line").remove();
          this.lines1 = [];
          this.lines2 = [];
          this.lines3 = [];
          this.DrawLeaderLine1();
          this.DrawLeaderLine2();
          this.DrawLeaderLine3();
        }),
        false
      );
      let scrollableBox2 = document.getElementsByClassName("SecondContent")[0];
      scrollableBox2.addEventListener(
        "scroll",
        AnimEvent.add(() => {
          d3.selectAll(".leader-line").remove();
          this.lines1 = [];
          this.lines2 = [];
          this.lines3 = [];
          this.DrawLeaderLine1();
          this.DrawLeaderLine2();
          this.DrawLeaderLine3();
        }),
        false
      );
      let scrollableBox3 = document.getElementsByClassName("ThirdContent")[0];
      scrollableBox3.addEventListener(
        "scroll",
        AnimEvent.add(() => {
          d3.selectAll(".leader-line").remove();
          this.lines1 = [];
          this.lines2 = [];
          this.lines3 = [];
          this.DrawLeaderLine1();
          this.DrawLeaderLine2();
          this.DrawLeaderLine3();
        }),
        false
      );
      let scrollableBox4 = document.getElementsByClassName("FourContent")[0];
      scrollableBox4.addEventListener(
        "scroll",
        AnimEvent.add(() => {
          d3.selectAll(".leader-line").remove();
          this.lines1 = [];
          this.lines2 = [];
          this.lines3 = [];
          this.DrawLeaderLine1();
          this.DrawLeaderLine2();
          this.DrawLeaderLine3();
        }),
        false
      );
    },

    ClearAllLine() {
      if (this.lines1 && this.lines1.length) {
        this.lines1.forEach((line) => {
          line.remove();
        });
      }
      if (this.lines2 && this.lines2.length) {
        this.lines2.forEach((line) => {
          line.remove();
        });
      }
      if (this.lines3 && this.lines3.length) {
        this.lines3.forEach((line) => {
          line.remove();
        });
      }
    },
  },
};
</script>
<style lang="scss" scoped>
.HelloWorld {
  display: flex;
  flex-flow: row nowrap;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  background: #1f4760;
}
#frame {
  margin: 64px;
  width: 540px;
  height: 540px;
  overflow: scroll;
}

#container {
  width: 880px;
  height: 880px;
  position: relative;
  background-color: beige;
}

.terminal {
  width: 32px;
  height: 32px;
  position: absolute;
  background-color: blue;
}

#terminal-1 {
  left: 32px;
  top: 32px;
}

#terminal-2 {
  left: 416px;
  top: 320px;
}

#terminal-3 {
  left: 64px;
  top: 180px;
}

#svg-clip {
  width: 1px; /* for Gecko bug */
  height: 1px; /* for Gecko bug */
}
</style>

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
vue-drag-resize 是一个用于实现拖拽和缩放功能的 Vue 组件库,如果您想要让拖拽和缩放的元素容器间,可以通过一些 CSS 样式来实现。 假设您的容器一个固定宽高的 div,您可以将该 div 设置为相对定位(position: relative),并将拖拽和缩放的元素设置为绝对定位(position: absolute)。然后,通过计算元素的宽高以及容器的宽高,可以将元素定位容器间。 具体的实现方法如下: ```html <template> <div class="container"> <vue-drag-resize :w="width" :h="height" :x="x" :y="y" @dragging="onDragging" @resizing="onResizing"> <!-- 元素内容 --> </vue-drag-resize> </div> </template> <script> export default { data() { return { width: 100, height: 100, x: 0, y: 0 } }, methods: { onDragging(event) { // 拖拽事件处理 }, onResizing(event) { // 缩放事件处理 } } } </script> <style> .container { position: relative; width: 500px; height: 500px; } .vue-drag-resize { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); } </style> ``` 在上面的示例,将容器设置为相对定位,并将拖拽和缩放的元素设置为绝对定位。通过将元素的 left 和 top 设置为 50%,再通过 transform 属性将元素向左和向上移动宽度和高度的一半,就可以将元素容器了。 需要注意的是,这种方法仅适用于容器元素的宽高已知并且固定的情况。如果容器元素的宽高不固定,或者容器的宽高是相对于父元素的百分比,那么需要通过 JavaScript 计算来实现居效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

volodyan

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

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

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

打赏作者

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

抵扣说明:

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

余额充值