博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
手把手教你做一个CSS 3D云
阅读量:6142 次
发布时间:2019-06-21

本文共 7231 字,大约阅读时间需要 24 分钟。

  hot3.png

介绍:之前在runjs分享了个3d云,今天在这分享个制作过程。这是个简化版,为了减轻浏览器打开时的压力去掉了云流动效果和鼠标滚轴效果。

1.创建一个模型和相机

首先,定义两个div:viewport和world。其他剩余元素动态创建。viewport全屏铺开,用它作为相机的一个平面。这里的相机你可以认为是真实世界里一块薄玻璃。我们可以移动玻璃的位置,来使我们看到不同的视角。world元素用来放置我们的一些css 3d效果。代码如下:

接下来对css属性进行定义:

#viewport { -webkit-perspective: 400;  -moz-perspective: 400;  -o-perspective: 400;  position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; background-image: linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%); background-image: -o-linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%); background-image: -moz-linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%); background-image: -webkit-linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%); background-image: -ms-linear-gradient(bottom, rgb(69,132,180) 28%, rgb(31,71,120) 64%); background-image: -webkit-gradient( linear, left bottom, left top, color-stop(0.28, rgb(69,132,180)), color-stop(0.64, rgb(31,71,120)) ); } #world { position: absolute; left: 50%; top: 50%; margin-left: -256px; margin-top: -256px; height: 512px; width: 512px; background-color: rgba( 255, 0, 0, .2 ); -webkit-transform-style: preserve-3d; -moz-transform-style: preserve-3d; -o-transform-style: preserve-3d; }

viewport的属性定义主要是模仿天空的效果,world模仿一个块状元素

添加鼠标移动效果:

 /* 	定义变量 worldXAngle,worldYAngle表示world的x轴,y轴旋转偏移 d代表着景深*/var world = document.getElementById( 'world' ),    viewport = document.getElementById( 'viewport' ),    worldXAngle = 0,    worldYAngle = 0,    d = 0; /*    鼠标移动位置的事件监听器    从-180到180,包括垂直和水平*/window.addEventListener( 'mousemove', function( e ) {    worldYAngle = -( .5 - ( e.clientX / window.innerWidth ) ) * 180;    worldXAngle = ( .5 - ( e.clientY / window.innerHeight ) ) * 180;    updateView();} ); /* 修改world的变换属性 通过d像素改变world x,y,z轴各个属性值*/function updateView() { var t = 'translateZ( ' + d + 'px ) rotateX( ' + worldXAngle + 'deg) rotateY( ' + worldYAngle + 'deg)'; world.style.webkitTransform = t; world.style.MozTransform = t; world.style.oTransform = t;}

2.向模型中添加对象

现在开始向world模型中添加真正的3D内容了,在world的相对空间内添加一些细碎的div。div的属性如下:

.cloudBase {		background-color: rgba( 255, 0, 255, .5 );		position: absolute;		left: 256px;		top: 256px;		width: 20px;		height: 20px;		margin-left: -10px;		margin-top: -10px;	}
接下来我们使用generate()和
createCloud()来填充world元素,如下在js中添加下面两个方法:

/*	清理前一次渲染的div并且生成新的div*/function generate() {		objects = [];		if ( world.hasChildNodes() ) {			while ( world.childNodes.length >= 1 ) {				world.removeChild( world.firstChild );       			} 		}		for( var j = 0; j < 5; j++ ) {			objects.push( createCloud() );		}	}/*	生成“云朵”div,随机分布,区间在-256到256之间*/function createCloud() {			var div = document.createElement( 'div'  );		div.className = 'cloudBase';		var x = 256 - ( Math.random() * 512 );		var y = 256 - ( Math.random() * 512 );		var z = 256 - ( Math.random() * 512 );		var t = 'translateX( ' + x + 'px ) translateY( ' + y + 'px ) translateZ( ' + z + 'px )';		div.style.webkitTransform = t;		div.style.MozTransform = t;		div.style.oTransform = t;		world.appendChild( div );				return div;	}
3.为对象创建层

接下来我们为每一个cloudBase div添加一个绝对定位的.cloudLayer层div。.cloudLayer属性如下:

.cloudLayer {		position: absolute;		left: 50%;		top: 50%;		width: 256px;		height: 256px;		margin-left: -128px;		margin-top: -128px;		background-color: rgba( 0, 255, 255, .1 );		-webkit-transition: opacity .5s ease-out;		-moz-transition: opacity .5s ease-out;		-o-transition: opacity .5s ease-out;	}
oh,这个地方还要重新改一下createCloud()方法,让他也能随机生成几个“云层”。

/*	生成“云朵”div,随机分布,区间在-256到256之间*/function createCloud() {			var div = document.createElement( 'div'  );		div.className = 'cloudBase';		var x = 256 - ( Math.random() * 512 );		var y = 256 - ( Math.random() * 512 );		var z = 256 - ( Math.random() * 512 );		var t = 'translateX( ' + x + 'px ) translateY( ' + y + 'px ) translateZ( ' + z + 'px )';		div.style.webkitTransform = t;		div.style.MozTransform = t;		div.style.oTransform = t;		world.appendChild( div );				for( var j = 0; j < 5 + Math.round( Math.random() * 10 ); j++ ) {			var cloud = document.createElement( 'div' );			cloud.className = 'cloudLayer';						var x = 256 - ( Math.random() * 512 );			var y = 256 - ( Math.random() * 512 );			var z = 100 - ( Math.random() * 200 );			var a = Math.random() * 360;			var s = .25 + Math.random();			x *= .2; y *= .2;			cloud.data = { 				x: x,				y: y,				z: z,				a: a,				s: s			};			var t = 'translateX( ' + x + 'px ) translateY( ' + y + 'px ) translateZ( ' + z + 'px ) rotateZ( ' + a + 'deg ) scale( ' + s + ' )';			cloud.style.webkitTransform = t;			cloud.style.MozTransform = t;			cloud.style.oTransform = t;					div.appendChild( cloud );			layers.push( cloud );		}				return div;	}
现在你应该能看到成片的“云朵”了,虽然他们还是规则的几何形状,no hashion!不要急,接下来我们给他们点立体效果看看。

4.制作3D效果

魔术即将上演,定义个layer[]数据把所有world中的layer放到这个数组中,然后在新添加在update方法中遍历数组,动态的给world中元素的位置赋值。update()方法如下:

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.webkitTransform = t;			layer.style.MozTransform = t;			layer.style.oTransform = t;		}				requestAnimationFrame( update );			}
现在看起来有了3D效果,但是还是一堆图形,no hashion!丑小鸭如何变白天鹅呢?

5.终结者

最后一步很简单啦,把layer中的backgroud-image替换成一张云的图片就行啦(当然你也可以换成其他图片,比如暴风,血浆,甚至狗屎),最好是png透明格式的。只需改下createCloud。

/*	生成“云朵”div,随机分布,区间在-256到256之间*/	function createCloud() {			var div = document.createElement( 'div'  );		div.className = 'cloudBase';		var x = 256 - ( Math.random() * 512 );		var y = 256 - ( Math.random() * 512 );		var z = 256 - ( Math.random() * 512 );		var t = 'translateX( ' + x + 'px ) translateY( ' + y + 'px ) translateZ( ' + z + 'px )';		div.style.webkitTransform = t;		div.style.MozTransform = t;		div.style.oTransform = t;		world.appendChild( div );				for( var j = 0; j < 5 + Math.round( Math.random() * 10 ); j++ ) {			var cloud = document.createElement( 'img' );			cloud.style.opacity = 0;			var r = Math.random();			var src = 'cloud.png';			( function( img ) { img.addEventListener( 'load', function() {				img.style.opacity = .8;			} ) } )( cloud );			cloud.setAttribute( 'src', src );			cloud.className = 'cloudLayer';						var x = 256 - ( Math.random() * 512 );			var y = 256 - ( Math.random() * 512 );			var z = 100 - ( Math.random() * 200 );			var a = Math.random() * 360;			var s = .25 + Math.random();			x *= .2; y *= .2;			cloud.data = { 				x: x,				y: y,				z: z,				a: a,				s: s,				speed: .1 * Math.random()			};			var t = 'translateX( ' + x + 'px ) translateY( ' + y + 'px ) translateZ( ' + z + 'px ) rotateZ( ' + a + 'deg ) scale( ' + s + ' )';			cloud.style.webkitTransform = t;			cloud.style.MozTransform = t;			cloud.style.oTransform = t;					div.appendChild( cloud );			layers.push( cloud );		}				return div;	}
c哈看下效果,一朵朵云像棉花糖一样盛开了!

不够完美,还带有边框,没关系接下来我们把这些边框去掉。

.cloudLayer {background-color: rgba( 0, 255, 255, .1 );}#world {background-color: rgba( 255, 0, 0, .2 );}.cloudBase { background-color: rgba( 255, 0, 255, .5 );}
把这三个背景去掉,ok啦!

效果演示地址:    

 爆炸效果

转载于:https://my.oschina.net/mousai/blog/131796

你可能感兴趣的文章
面试总结
查看>>
Chrome浏览器播放HTML5音频没声音的解决方案
查看>>
easyui datagrid 行编辑功能
查看>>
HDU 2818 (矢量并查集)
查看>>
实验二 Java面向对象程序设计
查看>>
------__________________________9余数定理-__________ 1163______________
查看>>
webapp返回上一页 处理
查看>>
新安装的WAMP中phpmyadmin的密码问题
查看>>
20172303 2017-2018-2 《程序设计与数据结构》第5周学习总结
查看>>
eclipse中将一个项目作为library导入另一个项目中
查看>>
Go语言学习(五)----- 数组
查看>>
Android源码学习之观察者模式应用
查看>>
416. Partition Equal Subset Sum
查看>>
Django之FBV与CBV
查看>>
Vue之项目搭建
查看>>
app内部H5测试点总结
查看>>
[TC13761]Mutalisk
查看>>
Data Wrangling文摘:Non-tidy-data
查看>>
while()
查看>>
常用限制input的方法
查看>>