목차
介绍
1.新建一个世界和视角
2.向我们创建的世界里添加对象
3.往我们的对象上添加层
4.让3D效果运行起来
最后总结
웹 프론트엔드 HTML 튜토리얼 怎样用CSS做出3D效果的云_html/css_WEB-ITnose

怎样用CSS做出3D效果的云_html/css_WEB-ITnose

Jun 24, 2016 am 11:23 AM

介绍

本文将介绍如何一步一步制作出一些3D效果的云彩,会用到一些高级的属性,主要是如何通过CSS的3D变换效果来实现,如果你想了解更多,这地方是个不错的开始。

静态效果图

本教程将会分成几个部分,每一部分都会有详细的步骤让你理解HTML,CSS和Javascript都是如何工作的,每一步都有衔接,以及一个链接来测试单个部分的代码效果。教程里的代码是最终demo的简化版,但是主要区别在每一部分都有说明

  • 1.新建一个世界和视角
  • 2.向我们创建的世界里添加对象
  • 3.往我们的对象上添加层
  • 4.让3D效果运行起来
  • 5.最后总结

1.新建一个世界和视角

首先,我们需要两个div元素: viewport 和 world。剩下的部分将会在后面动态的加入。

viewport 包含了整一个屏幕和一个摄影机。由于在CSS 3D变换中没有摄影机本身,就假想你在通过一个透明的玻璃屏幕来看屏幕里的视野,你也可以改变看视野的方向。我们将会把所有对象都放在里面,然后对他们进行变换。

world 是一个用来固定所有对象的 div 盒子。 旋转,转化或者放大都变换都会改变我们的元素。为简单起见,我将不使用CSS属性前缀,而是使用浏览器前缀(-webkit,-moz,-0,-ms等等)

这就是我们需要的所有盒子模型:

<div id="viewport">    <div id = "world" ></div></div>
로그인 후 복사

下面是我们定义的两个CSS样式,这里非常重要的是要将 world div 放在 viewport div里面,否则将无法渲染场景。要记住你将旋转一个放置在文档里的元素,像其他2D元素那样。

#viewport{    bottom:0;    left:0;    overflow:hidden;    perspective:400;    position:absolute;    right:0;    top:0;}#world{    height: 512px;    left: 50%;    margin-left: -256px;    margin-top: -256px;    position: absolute;    top: 50%;    transform-style: preserve-3d;    width: 512px;}
로그인 후 복사

现在写一些代码来初始化我们的对象,绑定 mousemove 事件以及定义 updateView() 函数。

/*    Defining our variables    world and viewport are DOM elements,    worldXAngle and worldYAngle are floats that hold the world rotations,    d is an int that defines the distance of the world from the camera */var world = document.getElementById( 'world' ),    viewport = document.getElementById( 'viewport' ),    worldXAngle = 0,    worldYAngle = 0,    d = 0;/*    Event listener to transform mouse position into angles     from -180 to 180 degress, both vertically and horizontally*/window.addEventListener( 'mousemove', function( e ) {    worldYAngle = -( .5 - ( e.clientX / window.innerWidth ) ) * 180;    worldXAngle = ( .5 - ( e.clientY / window.innerHeight ) ) * 180;    updateView();} );/*    Changes the transform property of world to be    translated in the Z axis by d pixels,    rotated in the X axis by worldXAngle degrees and    rotated in the Y axis by worldYAngle degrees.*/function updateView() {    world.style.transform = 'translateZ( ' + d + 'px ) \    rotateX( ' + worldXAngle + 'deg) \    rotateY( ' + worldYAngle + 'deg)';}
로그인 후 복사

world 是红色的,viewport 有背景色来模拟天空,mousewheel滚轮事件来监听摄影机的远近距离。移动鼠标来观察红色的 div 是如何改变方向的。

这是这一部分的演示链接

2.向我们创建的世界里添加对象

现在我们开始添加真正的3D内容。我们加入一些新的 div 放置在 world 空间里。有必要添加几个绝对位置的 div 作为 world 的子节点,但是用3D变换来替代 left 和 top, 他们默认会出现在 world 的中央位置。width 和 height属性无关紧要,因为这些新的容器是放置那些真实云的层。如果正式应用里最好将他们居中(通过设置 margin-left 和 margin-top 属性 来设置 width 和 height 一半的负数值)。

.cloudBase {    height: 20px;    left: 256px;    margin-left: -10px;    margin-top: -10px;    position: absolute;    top: 256px;    width: 20px;}
로그인 후 복사

我们添加 generate() 和 createCloud() 方法来充实 world。注意 random_{var} 不是真实的变量值,而是一个代码占位符,应该返回一个给定范围内的随机数

/*    objects is an array of cloud bases    layers is an array of cloud layers*/    var objects = [],    layers = [];/*    Clears the DOM of previous clouds bases     and generates a new set of cloud bases*/    function generate() {        objects = [];        layers = [];        if ( world.hasChildNodes() ) {            while ( world.childNodes.length >= 1 ) {                world.removeChild( world.firstChild );               }         }        for( var j = 0; j <; 5; j++ ) {            objects.push( createCloud() );        }    }/*    Creates a single cloud base: a div in world    that is translated randomly into world space.    Each axis goes from -256 to 256 pixels.*/    function createCloud() {        var div = document.createElement( 'div'  );        div.className = 'cloudBase';        var t = 'translateX( ' + random_x + 'px ) \        translateY( ' + random_y + 'px ) \        translateZ( ' + random_z + 'px )';        div.style.transform = t;        world.appendChild( div );        return div;    }
로그인 후 복사

页面中那些粉红色方块的层就是云层模型了,这里有一个 p 变量来更简单的改变 viewport.style.perspective 的值。试着去改变这个变量来观察我们的摄影机是如何变化的。这个值越大,视角的垂直度就会越大。再次提醒,那个 randowm_{var} 并不是真正的变量。

点我来观察这部分的演示

3.往我们的对象上添加层

现在有趣的事情开始发生了,我们添加了几个绝对位置的“云层” div 盒子来表示云,这些盒子将会用来装载云的贴图。

.cloudLayer {    height: 256px;    left: 50%;    margin-left: -128px;    margin-top: -128px;    position: absolute;    top: 50%;    width: 256px;}
로그인 후 복사

旧的 createCloud() 函数做了一些改动,添加了云层的随机数。

/*    Creates a single cloud base and adds several cloud layers.    Each cloud layer has random position ( x, y, z ), rotation (a)    and rotation speed (s). layers[] keeps track of those divs.*/function createCloud() {    var div = document.createElement( 'div'  );    div.className = 'cloudBase';    var t = 'translateX( ' + random_x + 'px ) \        translateY( ' + random_y + 'px ) \        translateZ( ' + random_z + 'px )';    div.style.transform = t;    world.appendChild( div );    for( var j = 0; j < 5 + Math.round( Math.random() * 10 ); j++ ) {        var cloud = document.createElement( 'div' );        cloud.className = 'cloudLayer';        cloud.data = {             x: random_x,            y: random_y,            z: random_z,            a: random_a,            s: random_s        };        var t = 'translateX( ' + random_x + 'px ) \            translateY( ' + random_y + 'px ) \            translateZ( ' + random_z + 'px ) \            rotateZ( ' + random_a + 'deg ) \            scale( ' + random_s + ' )';        cloud.style.transform = t;        div.appendChild( cloud );        layers.push( cloud );    }    return div;}
로그인 후 복사

点我来观察第三部分的演示

云层就是那些蓝色带有一点白色边边的部分,看起来相当有层次感呐。移动鼠标来观察下每一层的位置是怎样的以及如何旋转的。

4.让3D效果运行起来

接下来就是见证奇迹的时刻!我们用 layers[] 来为世界里每一个单独的云层建立一个引用。我们用 worldXangle 和 worldYAngle 来表示整个空间的选择变换。

如果我们将每个层都设置成相反的旋转,这会在viewport里重新调整他们:我们就有一个布告板了。因为我们旋转world先是X方向然后是Y方向,我们需要反着顺序来旋转每一个层,首先是Y方向再是X方向,变换的顺序是非常重要的,如果你没有正确的设置顺序,元素的方向就都会不对了。

/*    Iterate layers[], update the rotation and apply the    inverse transformation currently applied to the world.    Notice the order in which rotations are applied.*/function update (){          for( var j = 0; j < layers.length; j++ ) {        var layer = layers[ j ];        layer.data.a += layer.data.speed;        var t = 'translateX( ' + layer.data.x + 'px ) \            translateY( ' + layer.data.y + 'px ) \            translateZ( ' + layer.data.z + 'px ) \            rotateY( ' + ( - worldYAngle ) + 'deg ) \            rotateX( ' + ( - worldXAngle ) + 'deg ) \            scale( ' + layer.data.s + ')';        layer.style.transform = t;    }    requestAnimationFrame( update );}
로그인 후 복사

来回的移动鼠标,你将会看到蓝色的云层现在已经变成垂直的了(他们总是面对这镜头),但是 world 和其他云基体还是三维空间里的对象。

点我来见证神奇的效果

最后总结

为了达到最后的效果,只需要将用来调试的那些颜色去掉,把云层 div 用一个 img 贴上云的图片。注意图片得是带有alpha通道的PNG格式,要不没效果。

点我看看最后的效果

点我看看最后版本

当然,你可以随意换其他你想要的图片:烟雾痕迹,等离子体云,绿叶,飞行的面包机等等。只要把 backgroud-image 更改下就好了。混合不同比例的纹理材质会有神奇的效果。

随机的添加元素是可以的,但是你也可以创建有序的结构,比如树,鸭子形状的云或者复杂的大爆炸等。可以尝试一些3D曲线,创建固定的云的运行轨迹,创造一个多人游戏来猜3D云的形状等等,充满着无限可能。

NOTE:文中的代码都是简化了的哦,如果想一步一步实际操作的话最好保存下示例效果的链接页面来查看源码。

本文译自 https://www.clicktorelease.com/blog/how-to-make-clouds-with-css-3d#涉及到一些3D透视等专业词汇翻译有误敬请见谅,欢迎指正。

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
2 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
2 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

& lt; datalist & gt의 목적은 무엇입니까? 요소? & lt; datalist & gt의 목적은 무엇입니까? 요소? Mar 21, 2025 pm 12:33 PM

이 기사는 HTML & LT; Datalist & GT에 대해 논의합니다. 자동 완성 제안을 제공하고, 사용자 경험을 향상시키고, 오류를 줄임으로써 양식을 향상시키는 요소. 문자 수 : 159

& lt; Progress & Gt의 목적은 무엇입니까? 요소? & lt; Progress & Gt의 목적은 무엇입니까? 요소? Mar 21, 2025 pm 12:34 PM

이 기사는 HTML & lt; Progress & Gt에 대해 설명합니다. 요소, 그 목적, 스타일 및 & lt; meter & gt의 차이; 요소. 주요 초점은 & lt; progress & gt; 작업 완료 및 & lt; meter & gt; Stati의 경우

& lt; meter & gt의 목적은 무엇입니까? 요소? & lt; meter & gt의 목적은 무엇입니까? 요소? Mar 21, 2025 pm 12:35 PM

이 기사는 HTML & lt; meter & gt에 대해 설명합니다. 범위 내에 스칼라 또는 분수 값을 표시하는 데 사용되는 요소 및 웹 개발의 일반적인 응용 프로그램. & lt; meter & gt; & lt; Progress & Gt; 그리고 Ex

& lt; iframe & gt; 꼬리표? 보안을 사용할 때 보안 고려 사항은 무엇입니까? & lt; iframe & gt; 꼬리표? 보안을 사용할 때 보안 고려 사항은 무엇입니까? Mar 20, 2025 pm 06:05 PM

이 기사는 & lt; iframe & gt; 외부 컨텐츠를 웹 페이지, 공통 용도, 보안 위험 및 객체 태그 및 API와 같은 대안을 포함시키는 태그의 목적.

뷰포트 메타 태그는 무엇입니까? 반응 형 디자인에 중요한 이유는 무엇입니까? 뷰포트 메타 태그는 무엇입니까? 반응 형 디자인에 중요한 이유는 무엇입니까? Mar 20, 2025 pm 05:56 PM

이 기사는 모바일 장치의 반응 형 웹 디자인에 필수적인 Viewport Meta Tag에 대해 설명합니다. 적절한 사용이 최적의 컨텐츠 스케일링 및 사용자 상호 작용을 보장하는 방법을 설명하는 반면, 오용은 설계 및 접근성 문제로 이어질 수 있습니다.

HTML5 양식 유효성 검사 속성을 사용하여 사용자 입력을 유효성있게하려면 어떻게합니까? HTML5 양식 유효성 검사 속성을 사용하여 사용자 입력을 유효성있게하려면 어떻게합니까? Mar 17, 2025 pm 12:27 PM

이 기사에서는 브라우저에서 직접 사용자 입력을 검증하기 위해 필요한, Pattern, Min, Max 및 Length 한계와 같은 HTML5 양식 검증 속성을 사용하는 것에 대해 설명합니다.

HTML5의 크로스 브라우저 호환성에 대한 모범 사례는 무엇입니까? HTML5의 크로스 브라우저 호환성에 대한 모범 사례는 무엇입니까? Mar 17, 2025 pm 12:20 PM

기사는 HTML5 크로스 브라우저 호환성을 보장하기위한 모범 사례에 대해 논의하고 기능 감지, 점진적 향상 및 테스트 방법에 중점을 둡니다.

html5 & lt; time & gt; 의미 적으로 날짜와 시간을 나타내는 요소? html5 & lt; time & gt; 의미 적으로 날짜와 시간을 나타내는 요소? Mar 12, 2025 pm 04:05 PM

이 기사는 html5 & lt; time & gt; 시맨틱 날짜/시간 표현 요소. 인간이 읽을 수있는 텍스트와 함께 기계 가독성 (ISO 8601 형식)에 대한 DateTime 속성의 중요성을 강조하여 Accessibilit를 향상시킵니다.

See all articles