弹窗动画特效

看下效果图
在这里插入图片描述
弹窗组件
优势:弹窗内容自定义 边框大小自定义
目录结构:
在这里插入图片描述

<!-- 弹窗组件 -->
<template>
  <div :class="modalActive">
    <div id="modal-container" :class="active">
      <div class="modal-background" @click="closeDialog">
      </div>
      <div class="modal" :style="contentStyle">
        <!-- 内容 -->
        <slot name="content"></slot>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: ['contentStyle'],
  data () {
    return {
      active: '',
      modalActive: ''
    }
  },
  methods: {
    // 关闭弹窗
    closeDialog () {
      this.active = 'out'
      this.modalActive = ''
    },
    // 打开弹窗
    openDialog () {
      this.active = 'one'
      this.modalActive = 'modal-active'
    }
  }
}
</script>

<style  scoped>
.modal-active {
  overflow: hidden;
}

#modal-container {
  position: fixed;
  display: table;
  height: 32.4rem;
  width: 100%;
  top: 0;
  left: 0;
  transform: scale(0);
  z-index: 99;
}
#modal-container.one {
  transform: scaleY(0.01) scaleX(0);
  animation: unfoldIn 1s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.one .modal {
  transform: scale(0);
  animation: zoomIn 0.5s 0.8s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.out {
  transform: scale(1);
  animation: unfoldOut 1s 0.3s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container.out .modal {
  animation: zoomOut 0.5s cubic-bezier(0.165, 0.84, 0.44, 1) forwards;
}
#modal-container .modal-background {
  background: rgba(0, 0, 0, 0.8);
  width: 100%;
  height: 32.4rem;
  position: absolute;
  z-index: 0;
  cursor: pointer;
}
#modal-container .modal {
  width: 80rem;
  height: 28rem;
  background: white;
  border-radius: 3px;
  font-weight: 300;
  position: relative;
  margin: 2rem auto;
}
.content {
  min-height: 92%;
  height: 92%;
  background: white;
  position: relative;
  z-index: 0;
}
.content h1 {
  padding: 75px 0 30px 0;
  text-align: center;
  font-size: 30px;
  line-height: 30px;
}
.content .buttons {
  max-width: 800px;
  margin: 0 auto;
  padding: 0;
  text-align: center;
}
.content .buttons .button {
  display: inline-block;
  text-align: center;
  padding: 10px 15px;
  margin: 10px;
  background: red;
  font-size: 18px;
  background-color: #efefef;
  border-radius: 3px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
  cursor: pointer;
}
.content .buttons .button:hover {
  color: white;
  background: #009bd5;
}

@keyframes unfoldIn {
  0% {
    transform: scaleY(0.005) scaleX(0);
  }
  50% {
    transform: scaleY(0.005) scaleX(1);
  }
  100% {
    transform: scaleY(1) scaleX(1);
  }
}
@keyframes unfoldOut {
  0% {
    transform: scaleY(1) scaleX(1);
  }
  50% {
    transform: scaleY(0.005) scaleX(1);
  }
  100% {
    transform: scaleY(0.005) scaleX(0);
  }
}
@keyframes zoomIn {
  0% {
    transform: scale(0);
  }
  100% {
    transform: scale(1);
  }
}
@keyframes zoomOut {
  0% {
    transform: scale(1);
  }
  100% {
    transform: scale(0);
  }
}
@keyframes fadeIn {
  0% {
    background: rgba(0, 0, 0, 0);
  }
  100% {
    background: rgba(0, 0, 0, 0.7);
  }
}
@keyframes fadeOut {
  0% {
    background: rgba(0, 0, 0, 0.7);
  }
  100% {
    background: rgba(0, 0, 0, 0);
  }
}
</style>

父组件:

<!--  -->
<template>
  <div>
    <dialogAlert ref="mychild" :contentStyle="dialogStyle">
      <!--弹窗内容 -->
      <div slot="content">
        <div id="container"></div>
      </div>
    </dialogAlert>
  </div>
</template>

<script>
import dialogAlert from './Dialogalert.vue'
export default {
  components: {
    dialogAlert
  },
  data () {
    return {
      dialogStyle: 'width:60rem'
    }
  },
  methods: {
    // 弹窗
    openDialog () {
      this.$refs.mychild.openDialog()
    }
  },
  mounted () {
    var map = new window.BMap.Map('container')
    var point = new window.BMap.Point(116.404, 39.915)
    map.centerAndZoom(point, 15)
    map.enableScrollWheelZoom() // 开启鼠标滚轮缩放
    map.addControl(new window.BMap.ScaleControl()) // 添加比例尺控件

    var pointStr = '104.038748,30.641821,104.047789,30.648128,104.063959,30.655336,104.067264,30.660307,104.067264,30.664438,104.064008,30.665316'.split(',')
    var pointArr = []

    for (var k = 0; k < pointStr.length; k += 2) {
      pointArr.push({
        lng: pointStr[k],
        lat: pointStr[k + 1]
      })
    }

    // 生成坐标点
    var trackPoint = []
    for (var i = 0, j = pointArr.length; i < j; i++) {
      trackPoint.push(new window.BMap.Point(pointArr[i].lng, pointArr[i].lat))
    }

    map.centerAndZoom(trackPoint[0], 15)

    // 画线
    var polyline = new window.BMap.Polyline(trackPoint, {
      strokeColor: '#1869AD',
      strokeWeight: 3,
      strokeOpacity: 1
    })
    map.addOverlay(polyline)
    // 画图标
    // for (var i = 0, j = trackPoint.length; i < j; i++) {
    //   var marker = new window.BMap.Marker(trackPoint[i], {
    //     icon: '',
    //     offset: ''
    //   }) // 创建标注
    //   map.addOverlay(marker)
    // }

    // 根据经纬极值计算绽放级别。
    function getZoom (maxLng, minLng, maxLat, minLat) {
      var zoom = ['50', '100', '200', '500', '1000', '2000', '5000', '10000', '20000', '25000', '50000', '100000', '200000', '500000', '1000000', '2000000'] // 级别18到3。
      var pointA = new window.BMap.Point(maxLng, maxLat) // 创建点坐标A
      var pointB = new window.BMap.Point(minLng, minLat) // 创建点坐标B
      var distance = map.getDistance(pointA, pointB).toFixed(1) // 获取两点距离,保留小数点后两位
      for (var i = 0, zoomLen = zoom.length; i < zoomLen; i++) {
        if (zoom[i] - distance > 0) {
          return 18 - i + 3 // 之所以会多3,是因为地图范围常常是比例尺距离的10倍以上。所以级别会增加3。
        }
      }
    }

    //  (从网上复制)
    function setZoom (points) {
      if (points.length > 0) {
        var maxLng = points[0].lng
        var minLng = points[0].lng
        var maxLat = points[0].lat
        var minLat = points[0].lat
        var res
        for (var i = points.length - 1; i >= 0; i--) {
          res = points[i]
          if (res.lng > maxLng) maxLng = res.lng
          if (res.lng < minLng) minLng = res.lng
          if (res.lat > maxLat) maxLat = res.lat
          if (res.lat < minLat) minLat = res.lat
        }
        var cenLng = (parseFloat(maxLng) + parseFloat(minLng)) / 2
        var cenLat = (parseFloat(maxLat) + parseFloat(minLat)) / 2
        var zoom = getZoom(maxLng, minLng, maxLat, minLat)
        map.centerAndZoom(new window.BMap.Point(cenLng, cenLat), zoom)
      } else {
        // 没有坐标,显示全中国
        map.centerAndZoom(new window.BMap.Point(103.388611, 35.563611), 5)
      }
    }

    setZoom(pointArr)
  }
}
</script>

<style  scoped>
#container {
  overflow: hidden;
  width: 100%;
  height: 28rem;
  margin: 0;
  font-family: "微软雅黑";
}
</style>

index.vue

<!--  -->
<template>
  <div>
    <div @click="detail">打开地图</div>
    <div @click="trail">打开轨迹地图</div>
    <!-- 地图弹窗 -->
    <dialogMap ref="mychild"></dialogMap>
    <dialogTrail ref="mychild1"></dialogTrail>
  </div>
</template>

<script>
import dialogMap from '../components/Dialogmap.vue'
import dialogTrail from '../components/Dialogtrail.vue'
export default {
  components: {
    dialogMap,
    dialogTrail
  },
  data () {
    return {
      dialogStyle: 'width:60rem'
    }
  },
  methods: {
    // 弹窗
    detail () {
      this.$refs.mychild.openDialog()
    },
    trail () {
      this.$refs.mychild1.openDialog()
    }
  },
  mounted () {

  }
}
</script>

<style  scoped>
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值