Vue 前端根据坐标点按顺序生成连线

根据自定义的一些点, 按顺序连成一个闭环, 并赋予不同的class展示

HTML:

<div class="city">
  当前点亮城市:{{ cityList.find((v) => v.id === currentLightCityId).name }}
  <div v-html="lines"></div>
  <div :style="{
      position: 'absolute',
      top: item.top,
      right: item.right
    }"
    :class="[{
      'city-lighting': item.id === currentLightCityId }, {
      'city-lighted': item.id < currentLightCityId }, {
    }]"
    :ref="`city${item.id}`"
    v-for="(item, index) in cityList"
    :key="index">
      {{item.name}}
  </div>
</div>

JS: 

data() {
  return {
    cityList: [
      {
        id: 1,
        name: '星星城',
        top: '120px',
        right: '30px',
      },
      {
        id: 2,
        name: '月亮城',
        top: '70px',
        right: '170px',
      },
      {
        id: 3,
        name: '太阳城',
        top: '220px',
        right: '300px',
      },
      {
        id: 4,
        name: '柳城',
        top: '320px',
        right: '220px',
      },
    ],
    lines: '',
    currentLightCityId: 1,
  };
}
created() {
  this.$nextTick(() => {
    const lineArray = [];
    for (let i = 1; i <= this.cityList.length; i += 1) {
      let className = 'unlight';
      // 最新点亮的城市与上一个城市之间的连线
      if (this.currentLightCityId > 1 && i === this.currentLightCityId - 1) {
        className = 'lighting';
      } else if (this.currentLightCityId > i) {
        className = 'lighted';
      }
      if (i === this.cityList.length) {
        // 最后一个城市与第一个城市之间的连线
        lineArray.push(this.drawLine(this.$refs[`city${i}`][0], this.$refs.city1[0], className));
      } else {
        lineArray.push(this.drawLine(this.$refs[`city${i}`][0], this.$refs[`city${i + 1}`][0], className));
      }
    }
    this.lines = lineArray.join('');
    this.$forceUpdate();
  });
},
methods: {
  drawLine(startObj, endObj, className) {
    // 起点元素中心坐标
    // console.log(this.getOffset(startObj));
    const startObjOffset = this.getOffset(startObj);
    const endObjOffset = this.getOffset(endObj);
    const xStart = startObjOffset.height / 2 + startObjOffset.left;
    const yStart = startObjOffset.height / 2 + startObjOffset.top;
    // console.log(yStart);
    // console.log(xStart);
    // 终点元素中心坐标
    const xEnd = endObjOffset.height / 2 + endObjOffset.left;
    const yEnd = endObjOffset.height / 2 + endObjOffset.top;
    // console.log(yEnd);
    // console.log(xEnd);
    // 用勾股定律计算出斜边长度及其夹角(即连线的旋转角度)
    const lx = xEnd - xStart;
    const ly = yEnd - yStart;
    // 计算连线长度
    const length = Math.sqrt(lx * lx + ly * ly);
    // 弧度值转换为角度值
    const c = (360 * Math.atan2(ly, lx)) / (2 * Math.PI);

    // 连线中心坐标
    const midX = (xEnd + xStart) / 2;
    const midY = (yEnd + yStart) / 2;
    const deg = c <= -90 ? (360 + c) : c; // 负角转换为正角
    // console.log('length', length);
    // console.log('c', c);
    // console.log('midX', midX);
    // console.log('midY', midY);
    // console.log('deg', deg);
    // console.log(`<div class='line'
    //             style='top:${midY}px;left:${(midX - length / 2).toFixed(2)}px;width:${length.toFixed(2)}px;transform:rotate(${deg.toFixed(2)}deg);'>
    //         </div>`);
    return `<div class='line ${className}'
                style='top:${midY}px;left:${(midX - length / 2).toFixed(2)}px;width:${length.toFixed(2)}px;transform:rotate(${deg.toFixed(2)}deg);'>
            </div>`;
  },
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值