HTML&CSS:3D旋转动画机器人摄像头

效果演示

创建了一个3D机器人摄像头效果。

HTML

html 复制代码
<div class="modelViewPort">
    <div class="eva">
        <div class="head">
            <div class="eyeChamber">
                <div class="eye"></div>
                <div class="eye"></div>
            </div>
        </div>
        <div class="body">
            <div class="hand"></div>
            <div class="hand"></div>
            <div class="scannerThing"></div>
            <div class="scannerOrigin"></div>
        </div>
    </div>
</div>
  • modelViewPort类包含.eva类的div元素,它代表模型本身。
  • .eva类又包含了.head和.body两个部分,分别代表模型的头部和身体。
  • 头部包含两个.eye元素,代表眼睛。
  • 身体包含两个.hand元素代表手,一个.scannerThing代表扫描器的光束,以及一个.scannerOrigin代表扫描器的起点。

CSS

css 复制代码
.modelViewPort {
    perspective: 1000px;
    width: 20rem;
    aspect-ratio: 1;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    background: #000;
    overflow: hidden;
}

.eva {
    --EVA-ROTATION-DURATION: 4s;
    transform-style: preserve-3d;
    animation: rotateRight var(--EVA-ROTATION-DURATION) linear infinite alternate;
}

.head {
    position: relative;
    width: 6rem;
    height: 4rem;
    border-radius: 48% 53% 45% 55% / 79% 79% 20% 22%;
    background: linear-gradient(to right, white 45%, gray);
}

.eyeChamber {
    width: 4.5rem;
    height: 2.75rem;
    position: relative;
    left: 50%;
    top: 55%;
    border-radius: 45% 53% 45% 48% / 62% 59% 35% 34%;
    background-color: #0c203c;
    box-shadow: 0px 0px 2px 2px white, inset 0px 0px 0px 2px black;
    transform: translate(-50%, -50%);
    animation: moveRight var(--EVA-ROTATION-DURATION) linear infinite alternate;
}

.eye {
    width: 1.2rem;
    height: 1.5rem;
    position: absolute;
    border-radius: 50%;
}

.eye:first-child {
    left: 12px;
    top: 50%;
    background: repeating-linear-gradient(65deg,
            #9bdaeb 0px,
            #9bdaeb 1px,
            white 2px);
    box-shadow: inset 0px 0px 5px #04b8d5, 0px 0px 15px 1px #0bdaeb;
    transform: translate(0, -50%) rotate(-65deg);
}

.eye:nth-child(2) {
    right: 12px;
    top: 50%;
    background: repeating-linear-gradient(-65deg,
            #9bdaeb 0px,
            #9bdaeb 1px,
            white 2px);
    box-shadow: inset 0px 0px 5px #04b8d5, 0px 0px 15px 1px #0bdaeb;
    transform: translate(0, -50%) rotate(65deg);
}

.body {
    width: 6rem;
    height: 8rem;
    position: relative;
    margin-block-start: 0.25rem;
    border-radius: 47% 53% 45% 55% / 12% 9% 90% 88%;
    background: linear-gradient(to right, white 35%, gray);
}

.hand {
    position: absolute;
    left: -1.5rem;
    top: 0.75rem;
    width: 2rem;
    height: 5.5rem;
    border-radius: 40%;
    background: linear-gradient(to left, white 15%, gray);
    box-shadow: 5px 0px 5px rgba(0, 0, 0, 0.25);
    transform: rotateY(55deg) rotateZ(10deg);
}

.hand:first-child {
    animation: compensateRotation var(--EVA-ROTATION-DURATION) linear infinite alternate;
}

.hand:nth-child(2) {
    left: 92%;
    background: linear-gradient(to right, white 15%, gray);
    transform: rotateY(55deg) rotateZ(-10deg);
    animation: compensateRotationRight var(--EVA-ROTATION-DURATION) linear infinite alternate;
}

.scannerThing {
    width: 0;
    height: 0;
    position: absolute;
    left: 60%;
    top: 10%;
    border-top: 180px solid #9bdaeb;
    border-left: 250px solid transparent;
    border-right: 250px solid transparent;
    transform-origin: top left;
    mask: linear-gradient(to right, white, transparent 35%);
    animation: glow 2s cubic-bezier(0.86, 0, 0.07, 1) infinite;
}

.scannerOrigin {
    position: absolute;
    width: 8px;
    aspect-ratio: 1;
    border-radius: 50%;
    left: 60%;
    top: 10%;
    background: #9bdaeb;
    box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.5);
    animation: moveRight var(--EVA-ROTATION-DURATION) linear infinite;
}

@keyframes rotateRight {
    from {
        transform: rotateY(0deg);
    }

    to {
        transform: rotateY(25deg);
    }
}

@keyframes moveRight {
    from {
        transform: translate(-50%, -50%);
    }

    to {
        transform: translate(-40%, -50%);
    }
}

@keyframes compensateRotation {
    from {
        transform: rotateY(55deg) rotateZ(10deg);
    }

    to {
        transform: rotatey(30deg) rotateZ(10deg);
    }
}

@keyframes compensateRotationRight {
    from {
        transform: rotateY(55deg) rotateZ(-10deg);
    }

    to {
        transform: rotateY(70deg) rotateZ(-10deg);
    }
}

@keyframes glow {
    from {
        opacity: 0;
    }

    20% {
        opacity: 1;
    }

    45% {
        transform: rotate(-25deg);
    }

    75% {
        transform: rotate(5deg);
    }

    100% {
        opacity: 0;
    }
}
  • modelViewPort类为模型提供了一个视口,设置了透视效果、尺寸、宽高比、边框半径、显示方式、背景颜色和溢出隐藏。
  • .eva类定义了模型的3D变换样式,包括一个自定义属性--EVA-ROTATION-DURATION用于定义动画持续时间,以及一个无限循环的rotateRight动画。
  • .head类定义了头部的位置、尺寸和背景渐变。
  • .eyeChamber类定义了眼睛腔室的位置、尺寸、背景颜色和阴影,以及一个moveRight动画。
  • .eye类定义了眼睛的基本样式。
  • .body类定义了身体的位置、尺寸和背景渐变。
  • .hand类定义了手的位置、尺寸和背景渐变,以及两个手的不同动画。
  • .scannerThing和.scannerOrigin类定义了扫描器的样式和动画。
  • @keyframes定义了所有的动画效果,包括rotateRight、moveRight、compensateRotation、compensateRotationRight和glow。
相关推荐
Avan_菜菜11 小时前
AI 能写代码了,为什么我反而开始要求它先写文档?
前端·github·ai编程
爱勇宝15 小时前
鸿蒙生态的下半场:开发者不只要能开发,还要能赚钱
android·前端·程序员
IT_陈寒19 小时前
SpringBoot这个自动配置坑我跳了三次
前端·人工智能·后端
kyriewen19 小时前
我用 AI 一周写完了整个项目,上线第一天就崩了——这是我踩过最贵的 5 个坑
前端·javascript·ai编程
牧艺19 小时前
从零到协同:构建类飞书在线文档系统的五个技术重难点
前端·人工智能
红尘散仙20 小时前
想写一个像样的终端 App?试试把 React 的开发体验搬进 Rust TUI
前端·rust
袋鼠云数栈UED团队21 小时前
一套 Spec-First 的 AI 编程工作流
前端·人工智能
袋鼠云数栈前端21 小时前
一套 Spec-First 的 AI 编程工作流
前端·ai+
angerdream21 小时前
Android手把手编写儿童手机远程监控App之vue3 路由守卫
前端
不服老的小黑哥21 小时前
AI规范驱动编程-harness工程项目实战
前端