`CSS`----图标`3D`环绕旋转,近大远小效果

CSS----图标3D环绕旋转,近大远小效果

1、先设置图标底部圆环,图片为一张正圆图,给图片外层盒子设置 transform: scaleY(0.25);,将图片效果转为椭圆
代码如下:
  <div class="entry-box">
      <div class="entry-box-content">
        <div class="content-circle">
          <div
            class="circle"
          ></div>
        </div>
      </div>
    </div>
  .entry-box {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    &-content {
      width: 50vw;
      height: 50vw;
      position: absolute;
      top: calc(50% - 25vw);
      left: 25vw;
      z-index: 1;
         .content-circle {
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        transform: scaleY(0.25);//将背景圆设置为3D效果

        .circle {
          width: 100%;
          height: 100%;
          border-radius: 50%;
          background: url("../../assets/bgImg/circular5.png") no-repeat center center;
          background-size: 100% 100%;
        }
      }
      }
}
效果图

在这里插入图片描述

2、给底部圆环添加动画
  .circle {
          width: 100%;
          height: 100%;
          border-radius: 50%;
          background: url("../../assets/bgImg/circular5.png") no-repeat center center;
          background-size: 100% 100%;
          animation: centerRotate 15s linear infinite;
        }

@keyframes centerRotate {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

3、引入图标,并渲染到页面
import icon1 from "@/assets/iconImg/GEO终端.png";
import icon2 from "@/assets/iconImg/MF终端.png";
import icon3 from "@/assets/iconImg/pad.png";
import icon4 from "@/assets/iconImg/手机.png";
import icon5 from "@/assets/iconImg/显示器.png";
import icon6 from "@/assets/iconImg/服务器.png";
import icon7 from "@/assets/iconImg/笔记本.png";
import icon8 from "@/assets/iconImg/视频终端.png";

const IconList = [
  { id: 1, iconImg: icon1 },
  { id: 2, iconImg: icon2 },
  { id: 3, iconImg: icon3 },
  { id: 4, iconImg: icon4 },
  { id: 5, iconImg: icon5 },
  { id: 6, iconImg: icon6 },
  { id: 7, iconImg: icon7 },
  { id: 8, iconImg: icon8 },
];

 <div
          :class="['icon', 'icon' + item.id]"
          v-for="item in IconList"
          :key="item.id"
         
        >
          <img :src="item.iconImg" alt="" />
        </div>
4、设置每个图标的位置,并给每个图标添加动画
 <div
          :class="['icon', 'icon' + item.id]"
          v-for="item in IconList"
          :key="item.id"
         
        >
          <img :src="item.iconImg" alt="" />
        </div>
   .icon {
        width: 6vw;
        height: 6vw;
        position: absolute;
        display: flex;
        justify-content: center;
        align-items: center;

        img {
          width: 120%;
        }

        img:hover {
          width: 140%;
        }
      }     
      .icon1 {
        top: 24vw;
        left: 22vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -4s infinite alternate,
                   turnY 8s cubic-bezier(0.36, 0, 0.64, 1) 0s infinite alternate,
                   turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) 0s infinite alternate;
      }
      .icon2 {
        top: 22.25vw;
        left: 11.25vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -6s infinite alternate,
          turnY 8s cubic-bezier(0.36, 0, 0.64, 1) -2s infinite alternate,
          turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) -2s infinite alternate;
      }
      .icon3 {
        top: 19vw;
        left: 3vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -8s infinite alternate,
          turnY 8s cubic-bezier(0.36, 0, 0.64, 1) -4s infinite alternate,
          turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) -4s infinite alternate;
      }
      .icon4 {
        top: 15.25vw;
        left: 11.25vw;
        animation: turnX  8s cubic-bezier(0.36, 0, 0.64, 1) -10s infinite alternate,
                   turnY  8s cubic-bezier(0.36, 0, 0.64, 1) -6s infinite alternate,
                   turn-self 16s cubic-bezier(0.36, 0, 0.64, 1)-6s infinite alternate;
      }
      .icon5 {
        top: 14.5vw;
        left: 22vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -12s infinite alternate,
          turnY 8s cubic-bezier(0.36, 0, 0.64, 1) -8s infinite alternate,
          turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) -8s infinite alternate;
      }
      .icon6 {
        top: 15.25vw;
        right: 11.25vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -14s infinite alternate,
          turnY 8s cubic-bezier(0.36, 0, 0.64, 1) -10s infinite alternate,
          turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) -10s infinite alternate;
      }
      .icon7 {
        top: 19vw;
        left: 41vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -16s infinite alternate,
          turnY 8s cubic-bezier(0.36, 0, 0.64, 1) -12s infinite alternate,
          turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) -12s infinite alternate;
      }

      .icon8 {
        top: 22.25vw;
        right: 11.25vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -18s infinite alternate,
          turnY 8s cubic-bezier(0.36, 0, 0.64, 1) -14s infinite alternate,
          turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) -14s infinite alternate;
      }

1、第一个icon初始值:

turn-self :duration为 turnX和turnY之和

turnX:delay 为turn-self duration一半

turnY,turn-self :delay 为 0

2、每个delay 每次递减的值为 turn-self的duration/icon的数量 例子:16/8 = 2,每次递减2;

3、cubic-bezier,css3贝塞尔曲线 一条表示进度变化快慢的速度曲线

/* icon自身的大小缩放 */
@keyframes turn-self {
  0% {
    transform: scale(0.7);
  }

  50% {
    transform: scale(1);
  }

  100% {
    transform: scale(0.7);
  }
}

/* icon横向运动变化,x轴的范围 */
@keyframes turnX {
  0% {
    left: 3vw;
  }

  100% {
    left: 41vw;
  }
}

/*icon纵向运动变化,Y轴的范围 */
@keyframes turnY {
  0% {
    top: 14.5vw;
  }

  100% {
    top: 24vw;
  }
}

效果图:

在这里插入图片描述

5、设置鼠标移入移出效果
 <div
          :class="['icon', 'icon' + item.id]"
          v-for="item in IconList"
          :key="item.id"
          :style="`animation-play-state: ${animationPlayState};`"
          @mouseover="mouseOver"
          @mouseleave="mouseleave"
        >
let animationPlayState = ref<string>("");

function mouseOver() {
  animationPlayState.value = "paused";
}
function mouseleave() {
  animationPlayState.value = "running";
}
6、完整代码
<template>
  <div class="entry">
    <div class="entry-box">
      <div class="entry-box-content">
        <div class="content-circle">
          <div
            class="circle"
            :style="`animation-play-state: ${animationPlayState};`"
          ></div>
        </div>
        <div
          :class="['icon', 'icon' + item.id]"
          v-for="item in IconList"
          :key="item.id"
          :style="`animation-play-state: ${animationPlayState}; --item:${-(
            item.id + 1
          )}; --icon:${-(item.id - 1)}`"
          @mouseover="mouseOver"
          @mouseleave="mouseleave"
        >
          <img :src="item.iconImg" alt="" />
        </div>
      </div>
    </div>
  </div>
</template>



<script lang="ts" setup>
import icon1 from "@/assets/iconImg/GEO终端.png";
import icon2 from "@/assets/iconImg/MF终端.png";
import icon3 from "@/assets/iconImg/pad.png";
import icon4 from "@/assets/iconImg/手机.png";
import icon5 from "@/assets/iconImg/显示器.png";
import icon6 from "@/assets/iconImg/服务器.png";
import icon7 from "@/assets/iconImg/笔记本.png";
import icon8 from "@/assets/iconImg/视频终端.png";

const IconList = [
  { id: 1, iconImg: icon1 },
  { id: 2, iconImg: icon2 },
  { id: 3, iconImg: icon3 },
  { id: 4, iconImg: icon4 },
  { id: 5, iconImg: icon5 },
  { id: 6, iconImg: icon6 },
  { id: 7, iconImg: icon7 },
  { id: 8, iconImg: icon8 },
];

let animationPlayState = ref<string>("");

function mouseOver() {
  animationPlayState.value = "paused";
}
function mouseleave() {
  animationPlayState.value = "running";
}
</script>
<style lang="scss" scoped>
.entry {
  width: 100%;
  height: 100%;
  display: flex;
  position: relative;

  .entry-box {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    &-content {
      width: 50vw;
      height: 50vw;
      position: absolute;
      top: calc(50% - 25vw);
      left:25vw;
      z-index: 1;
      .content-circle {
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        transform: scaleY(0.25);

        .circle {
          width: 100%;
          height: 100%;
          border-radius: 50%;
          background: url("../../assets/bgImg/circular5.png") no-repeat center center;
          background-size: 100% 100%;
          animation: centerRotate 15s linear infinite;
        }
      }
      .icon {
        width: 6vw;
        height: 6vw;
        position: absolute;
        display: flex;
        justify-content: center;
        align-items: center;

        img {
          width: 120%;
        }

        img:hover {
          width: 140%;
        }
      }
      .icon1 {
        top: 24vw;
        left: 22vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -4s infinite alternate,
                   turnY 8s cubic-bezier(0.36, 0, 0.64, 1) 0s infinite alternate,
                   turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) 0s infinite alternate;
      }
      .icon2 {
        top: 22.25vw;
        left: 11.25vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -6s infinite alternate,
          turnY 8s cubic-bezier(0.36, 0, 0.64, 1) -2s infinite alternate,
          turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) -2s infinite alternate;
      }
      .icon3 {
        top: 19vw;
        left: 3vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -8s infinite alternate,
          turnY 8s cubic-bezier(0.36, 0, 0.64, 1) -4s infinite alternate,
          turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) -4s infinite alternate;
      }
      .icon4 {
        top: 15.25vw;
        left: 11.25vw;
        animation: turnX  8s cubic-bezier(0.36, 0, 0.64, 1) -10s infinite alternate,
                   turnY  8s cubic-bezier(0.36, 0, 0.64, 1) -6s infinite alternate,
                   turn-self 16s cubic-bezier(0.36, 0, 0.64, 1)-6s infinite alternate;
      }
      .icon5 {
        top: 14.5vw;
        left: 22vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -12s infinite alternate,
          turnY 8s cubic-bezier(0.36, 0, 0.64, 1) -8s infinite alternate,
          turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) -8s infinite alternate;
      }
      .icon6 {
        top: 15.25vw;
        right: 11.25vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -14s infinite alternate,
          turnY 8s cubic-bezier(0.36, 0, 0.64, 1) -10s infinite alternate,
          turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) -10s infinite alternate;
      }
      .icon7 {
        top: 19vw;
        left: 41vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -16s infinite alternate,
          turnY 8s cubic-bezier(0.36, 0, 0.64, 1) -12s infinite alternate,
          turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) -12s infinite alternate;
      }

      .icon8 {
        top: 22.25vw;
        right: 11.25vw;
        animation: turnX 8s cubic-bezier(0.36, 0, 0.64, 1) -18s infinite alternate,
          turnY 8s cubic-bezier(0.36, 0, 0.64, 1) -14s infinite alternate,
          turn-self 16s cubic-bezier(0.36, 0, 0.64, 1) -14s infinite alternate;
      }
    }
  }
}

@keyframes centerRotate {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

/* icon自身的大小缩放 */
@keyframes turn-self {
  0% {
    transform: scale(0.7);
  }

  50% {
    transform: scale(1);
  }

  100% {
    transform: scale(0.7);
  }
}

/* icon横向运动变化,x轴的范围 */
@keyframes turnX {
  0% {
    left: 3vw;
  }

  100% {
    left: 41vw;
  }
}

/*icon纵向运动变化,Y轴的范围 */
@keyframes turnY {
  0% {
    top: 14.5vw;
  }

  100% {
    top: 24vw;
  }
}
</style>
  • 28
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要在Cesium中实现HTML结构近大远小的效果,可以使用Cesium的3D Tiles功能。3D Tiles是一种用于将大量3D数据分层的格式,可以用来管理和渲染具有不同分辨率的3D模型。通过使用3D Tiles,可以在不牺牲质量的情况下,根据距离动态加载和卸载3D模型。 在使用3D Tiles时,可以设置不同层级的3D模型的显示距离和细节级别。这些设置可以控制3D模型随着距离的增加而变得更加简单,从而实现HTML结构近大远小的效果。 例如,可以将较远的3D模型设置为低细节级别,使其在远处显示为简单的形状。而在靠近时,可以将细节级别提高,使其显示更多的细节和结构。 下面是一个使用3D Tiles实现HTML结构近大远效果的示例代码: ```javascript var viewer = new Cesium.Viewer('cesiumContainer'); var tileset = new Cesium.Cesium3DTileset({ url : 'path/to/3d/tiles' }); // 设置3D Tiles的细节级别和显示距离 tileset.maximumScreenSpaceError = 16; tileset.maximumLevel = 5; tileset.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(0.0, 5000.0); viewer.scene.primitives.add(tileset); ``` 在这个示例中,`maximumScreenSpaceError`和`maximumLevel`属性控制了3D模型的细节级别,`distanceDisplayCondition`属性控制了3D模型的显示距离。通过调整这些属性的值,可以实现不同程度的HTML结构近大远效果。 ### 回答2: 在Cesium项目中实现HTML结构近大远小的效果,可以通过以下几个步骤实现: 1. 创建HTML结构:首先,你需要在Cesium场景中添加一个HTML元素用来承载你想要展示的内容。你可以使用Cesium的Entity API创建一个自定义的HTML元素,并通过设置其position属性来指定其在场景中的位置。 2. 调整HTML元素的样式:通过CSS样式来控制HTML元素的外观,例如大小、颜色和字体等。你可以在HTML元素上添加class或id,然后在CSS文件中定义这些样式,从而实现HTML元素的近大远效果。 3. 按照视角调整HTML元素的大小:Cesium提供了视角变化的事件,可以根据用户的视角变化来调整HTML元素的大小。通过监听场景的"camera.moveEnd"事件,可以获取到相机的位置和朝向,并根据这些信息来计算HTML元素应该显示的大小。 4. 实时更新HTML元素的位置和大小:在Cesium中,可以使用Viewer的renderEvent事件来实现每一帧渲染之前调用的函数。在这个函数中,你可以更新HTML元素的位置和大小,从而实现实时的近大远效果。 5. 优化性能:为了避免频繁更新HTML元素的位置和大小,可以设置一个阈值,当相机的距离超过这个阈值时才进行更新。可以调整这个阈值来平衡性能和效果的表现。 综上所述,通过创建HTML结构并调整其样式,根据视角变化实时更新其位置和大小,就可以在Cesium项目中实现近大远小的效果。 ### 回答3: 在Cesium项目中实现HTML结构近大远小的效果可以通过以下步骤实现: 1. 创建HTML标记:首先,你需要创建一个HTML标记,它将被用作你想要实现效果的模板。可以使用div、span或其他HTML元素来创建结构。 2. 将HTML标记添加到Cesium实体:将HTML标记添加到Cesium实体中,可以使用Cesium实体上的属性,如属性和属性表达式。例如,你可以使用Entity的description属性来添加HTML标记。 3. 定义HTML标记的样式:通过CSS样式表或内联样式,定义HTML标记的样式。你可以使用CSS属性如大小(width、height)、位置(position)、文本对齐(text-align)等属性来控制HTML标记的样式。 4. 进行相机远近的计算:通过Cesium的相机属性,如相机位置(camera.position)和相机距离(camera.distance)来进行相机的远近计算。根据相机距离的变化,可以动态改变HTML标记的大小。 5. 实现HTML标记的近大远效果:根据相机距离的变化,使用JavaScript或其他编程语言,在合适的时机修改HTML标记的样式或属性,从而使其近大远小。 6. 监听相机事件:通过监听相机的事件,如相机移动事件(camera.moveEnd)或场景更新事件(scene.postRender),可以在适当的时候更新HTML标记的样式或位置。 通过以上步骤,你可以在Cesium项目中实现HTML结构近大远小的效果。这样,当用户在场景中移动相机时,HTML标记将根据相机的距离动态调整大小,达到近大远小的效果

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值