怎样用CSS做出3D效果的云_html/css_WEB-ITnose
介绍
本文将介绍如何一步一步制作出一些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透视等专业词汇翻译有误敬请见谅,欢迎指正。

핫 AI 도구

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

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

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

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

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

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

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

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

뜨거운 주제









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

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

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

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

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

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

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

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