16-3d和盒阴影和遮罩

3d动画

3d立体空间 css3的属性,让我们非常简单的开发3d的应用

反观我们的2dtransform只是在平面上进行操作.

电脑上游览器绘制的不是真正的3d,而是游览器模拟出来的3d,是3d空间在屏幕当中的投影


我们的双眼是怎么看见立体空间的?

1.双眼,物体呈现的画面左右不同

2.大脑:近大远小(景深),绘画领域:透视法则

如果我们能够模拟这样的效果,我们就可以欺骗我们的大脑,让大脑以为这是一个真实的3D空间,最终我们可以实现3D效果

如何出现3d的盒子,

  • 一个普通的盒子旋转(rotate),绕着我们的X轴或Y轴进行旋转.上面我们旋转默认是绕着Z轴旋转

规定:立体空间坐标系

提到立体空间坐标系,就是我们的三维空间,

X轴和Y轴和以前一样

但是多出来一条Z轴.

**Z轴是什么(**画个图)

由屏幕到用户眼睛的轴为Z轴

这意味在离用户远的位置(Z轴负方向)上的元素,在屏幕上看起来应该小一些.

离用户近的位置则应该大一些.

而绕着X或Y轴旋转,也会导致元素某一部分变大,其余部分变小.

	.box{
		width: 300px;
		height: 300px;
		margin: 200px auto;
		background-color:skyblue;
		transform:rotate(45deg);
}
    	/*rota默认是绕着rotateZ轴旋转的,那我们想让看到立体效果是不是得换个轴.
    	我们也可以让盒子绕着X轴和Y轴进行旋转,
    	Y轴旋转是不是有点像是我们去翻书,然后把这本书翻开,是不是绕着我们Y轴进行旋转?*/

我们将rotateZ改成rotateY

.box{transform:rotateY(45deg)}
/*这个盒子变窄变瘦了,没有一个立体效果?为什么呢?
这是因为我们虽然写了rotateY,它确实绕着Y轴去旋转,
你可以想象一下我们竖直站在书的上面的去看这本书,绕着中心轴去翻,宽度会变窄.
所以单纯一个周的变换只会导致元素变窄,体现不会任何三维旋转*/
  • 所以让盒子绕着Y轴旋转,一般是看不到立体效果的,要像看到立体效果,必须要有景深(近大远小)的概念.

perspective:npx;距离盒子远处去进行观察,定义透视

恰当的距离一般是600px-1000px,1000px大概20厘米的距离就差不多.

这样的话确定用户距离这个元素有多远.

离得越近,变化越大.离得越远,变化越小.

默认是无穷远,所以不会发生明显的变化.

.box{
  transform:rotateY(45deg)
		perspective: 1000px;
	}
    /*还是看不到我们的3d效果,这是为什么?
     这是因为我们现在所去观察这个盒子,你不要直勾勾去看这个盒子.
     这里我们去看这个盒子的时候,游览器做了一个规定,默认情况下我们是眼睛贴着盒子去看.
     所以你看盒子每一处都是一样大的,所以它不具备这样的一个立体空间的效果.
     所以有句话叫做不识庐山真面目,只缘身在此山中.
     当你脱离了这个平面站在一定距离就能去观察到它的全貌.
     我们就需要有一个观察的位置和视角,距离盒子这个平面空间Z轴远处去观察,才能去看到立体效果*/

perspective:npx;距离盒子远处去进行观察,一般加到父级盒子上,在父级盒子中观察子盒子的立体效果

body{
		perspective: 1000px;
    /*此时打开开发者继续旋转,这有没有一种感觉,它好像变形了.
    这里好像是我们在看立体盒子的某一个侧面,这就是我们立体盒子绕着Y轴去进行旋转,
    现在中心点到一条边上是不是父级宽度的一半150px. */
	}

我们要去聊一下中心点在中间,

中心点到前面一条边的距离是不是150px,假如我站在300ox的距离去观察,这样效果是不是更明显了,

这是游览器通过一些计算让我们看上去有立体的效果,我们去写200px它就离我们越来越近了,

假如我们去写150px,这张纸绕转90deg了之后像不像刚好从我们的眼前划了过去.

我们还可以写transform:rotateX

.box{transform:rotateX(45deg)}/*绕着X轴的中心点去进行旋转*/

透视原点

默认情况下,假定观察者的视线与应用透视元素相交于元素的中心.

用术语来说,这意味着"消失点"在元素的中心.

可以通过perspective-origin来修改消失点的位置.

该属性与transform-origin类似,可以接受x/y坐标值(带关键字top,left.right.bottom),百分比或者长度值.

当为元素定义 perspective-origin 属性时,其子元素会获得透视效果,而不是元素本身,它是和perspective属性一起使用的,而且只影响 3D 转换元素

<div class="wrap">
		<div class="son1"></div>
		<div class="son2"></div>
	</div>

.wrap{
			perspective:1000px ;
			perspective-origin: 0 0;
			width: 600px;
			height: 600px;
			background-color: tomato;
			margin: 100px auto;
		}
		.son1{
			width: 200px;
			height: 200px;
			background-color: turquoise;
			transform: rotateX(40deg);
		}
		.son2{
			width: 200px;
			height: 200px;
			background-color: green;
		}

3d物体的制作方式

  1. 旋转物体 绕着X/Y轴进行旋转.
  2. 站在父级的空间去进行观测,并且有一定的视距perspective.

做一个立方体这么搞

一个立体体有几个面,6个面(上下左右前后)

我这六个面本质是不是都是六个正方形?

上下左右前后都是一个绝对的正方形.所以我们就用六个正方形去制作.

<div class="cube">
		<div class="small">上</div>
		<div class="small">下</div>
		<div class="small">左</div>
		<div class="small">右</div>
		<div class="small">前</div>
		<div class="small">后</div>
</div>
/*一个大盒子里面有六个小盒子分别代表正方体的六个面*/

接着我们来写CSS样式

首先设置最外层大盒子的样式.

	.cube {
			position: relative;
			width: 300px;
			height: 300px;
			margin: 180px auto 0;
			perspective: 1000px;
			/*视距:设置的就是观察点(类似于眼睛)距离我们的3D元素的距离。
			  一般设置1000px大概就是我们眼睛到屏幕的距离*/
		}

接着设置子元素的样式.

.cube .small {
			position: absolute;
			/*把六个相同的盒子叠在一起*/
			width: 300px;
			height: 300px;
			/*设置六个盒子的宽高*/
			box-shadow: 0 0 10px #ccc;
			/*盒子模糊半径10px,颜色#ccc;*/
			font-size: 50px;
			text-align: center;
			line-height: 300px;
			/*设置文字样式更有利于观察*/
			perspective: 1000px;
			/*给子元素添加视距*/
		}

这时候分别移动六个面的Z轴形成正方体

.cube .small:nth-child(1) {
	transform: rotateX(90deg) translateZ(150px);
	}
	/*上面:X轴旋转90deg,此时Z轴朝上,Z轴再平移150px即可*/
.cube .small:nth-child(2) {
	transform: rotateX(-90deg) translateZ(150px);
	}
	/*下面:X轴旋转-90deg,此时Z轴朝下,Z轴再平移150px即可*/
.cube .small:nth-child(3) {
	transform: rotateY(-90deg) translateZ(150px);
	}
	/*左面:Y轴旋转-90deg,此时Z轴朝左,Z轴再平移150px即可*/
.cube .small:nth-child(4) {
	transform: rotateY(90deg) translateZ(150px);
	}
	/*右面:Y轴旋转90deg,此时Z轴朝右,Z轴再平移150px即可*/
.cube .small:nth-child(5) {
	transform: translateZ(150px);
	}
	/*前面:直接朝着Z轴我们眼睛这条轴向前平移150px即可*/	
.cube .small:nth-child(6) {
	transform:rotateY(180deg) translateZ(150px);
	}
	/*后面:Y轴旋转180deg,此时Z轴朝后,Z轴再平移150px即可*/		

此时3D盒子就已经出来了我们去让它旋转吧.

.cube {animation: roll 4s linear infinite;}
/*定义了一个roll的动画,时间4s匀速无限循环*/

我们去设置动画的具体效果吧.

@keyframes roll {
			0% {
				transform: rotateX(0deg) rotateY(0deg);
			}
			100% {
				transform: rotateX(360deg) rotateY(360deg);
			}
		}
/*定义了roll动画的关键帧*/

这时候你会发现是一个扁的平面在旋转,不是我们正方体旋转,这是因为我们没有开启大盒子的3D空间

.cube {transform-style: preserve-3d;}
	/*开启父级盒子的3d属性,能容纳子盒子*/

可是这时候又发现了为什么每个面都不一样大?因为这时候我们的视距还是在大盒子之上,相当于我们站在大盒子去看,这是我们就想单独站在每个小盒子上去看.

.cube .small { perspective: 1000px; }

这时候我们一个简单旋转的3D盒子就制作完成了

/*每个步骤的分解*/
@keyframes roll{
			0%{
				transform: rotateX(0deg) translateZ(0px)
			}
			50%{
				transform: rotateX(90deg) translateZ(0px)
			}
			100%{
				transform: rotateX(90deg) translateZ(150px)
			}
		}
		@keyframes roll2{
			0%{
				transform: rotateY(0deg) translateZ(0px)
			}
			50%{
				transform: rotateY(-90deg) translateZ(0px)
			}
			100%{
				transform: rotateY(-90deg) translateZ(150px)
			}
		}
@keyframes roll3{
				0%{
					transform:rotateY(0deg) translateZ(0px);
				}
				50%{
					transform:rotateY(-90deg) translateZ(0px);
				}
				100%{
					transform:rotateY(-90deg) translateZ(250px);
				}
			}

			@keyframes roll4{
				0%{
					transform:rotateY(0deg) translateZ(0px);
				}
				50%{
					transform:rotateY(90deg) translateZ(0px);
				}
				100%{
					transform:rotateY(90deg) translateZ(250px);
				}
			}

			@keyframes roll5{
				0%{
					transform:rotateY(0deg) translateZ(0px);
				}
				100%{
					transform:rotateY(0deg) translateZ(250px);
				}
			}

			@keyframes roll6{
				0%{
					transform:rotateY(0deg) translateZ(0px);
				}
				100%{
					transform:rotateY(0deg) translateZ(-250px);
				}
			}

perspective视角的位置问题

<ul>
	<li>
		<div></div>
	</li>
	<li>
		<div></div>
	</li>
	<li>
		<div></div>
	</li>
	<li>
		<div></div>
	</li>
</ul>	
   ul{
			list-style: none;
		}
		ul{
			width: 800px;
			height: 100px;
			margin: 200px auto;
    	/*perspective: 500px 父级盒子添加视距,我们只是站在父级盒子一个点上去观察盒子.
		  大剧院,百叶窗*/
		}
	ul li{
			float: left;
    	width: 100px;
			height: 100px;
			perspective: 500px;
     /*对每个观测物体都添加特定的视角,从而解决单视角的问题 多个机位*/
		}
		ul li div{
			width: 100px;
			height: 100px;
			margin-right: 10px;
			border: 3px solid skyblue;
			transform: rotateY(60deg);
		}
		

盒子阴影

盒阴影属性介绍

盒阴影是CSS3中专门用来修饰元素边缘的,较之CSS2.1及之前的border,outline等属性,盒阴影既不会影响网页的整体布局,也能有更多的表现形式

我们可以简单的整个网页内容进行一个分析,网页的布局就如同是把一个个的瓷砖贴在地板上,用户则是永远趴在天花板上看下面的瓷砖

盒阴影属性详解

box-shadow:xOffset水平方向偏移 yOffset垂直方向偏移 burlLehgth阴影模糊距离 spread阴影缩放 color阴影颜色 outset 阴影显示方式;

  • box-shadow 属性用于向盒子添加一个或多个阴影效果。
	.wrap{
			width: 200px;
			height: 200px;
			background-color: pink;
			box-shadow:0px 0px 0 0 blue;
/*盒阴影:水平方向不偏移  垂直方向不偏移 阴影模糊程度为0 阴影缩放为0 阴影颜色为蓝色 外部显示阴影*/
    
    /*看似没有任何效果,原因其实很简单,因为此时影子的大小与元素一致,而且没有给影子设置偏移,那么以用户的从上往下看的视角来看,元素的影子全部都被元素本身给遮挡住了
而元素的xOffset属性值的作用就是把这个影子在原来的位置上设置一个偏移,当Xoffset的值为正值时,影子向右偏移,xOffset为负值时,影子向左偏移*/
		}
	<div class="wrap"></div>

offset-x:阴影的水平偏移量。正数向右偏移,负数向左偏移。

offset-y:阴影的垂直偏移量。正数向下偏移,负数向上偏移。

blur:阴影模糊度,指的是完全颜色到消失颜色的一个长度.不能取负数。此值的显示效果就好像是在原来的影子周围加上了一条有模糊渐变效果的边框,它能使影子看上去更大并且具有朦胧的效果,即便在元素没有偏移的时候,因为影子本身更大了,所以也能在元素的周围看到一层朦胧的蓝色光圈

spread:阴影大小。正数阴影扩大(阴影大小大于盒子大小),负数阴影缩小(阴影大小小于盒子大小),0阴影与盒子同等大小。

color:影子的颜色,此处颜色可设置渐变色、英语单词、rgb、rgba、十六进制等,作用就是改变影子的颜色;默认黑色

inset表示添加内阴影,默认为外阴影outset。但是如果给盒阴影加上inset,则影子的显示就如同在元素的边缘向内部蔓延一般,此时影子的大小会遮盖部分元素的内容

多个阴影的写法

逗号隔开

box-shadow:10px 10px 10px 10px #ffcc33,-10px -10px 10px 10px #9933ff;

	/*阴影的实例*/
<div class="wrap">
		<div class="gradient"></div>
	</div>
.wrap {
			overflow: hidden;
			position: relative;
			width: 300px;
			height: 300px;
			margin: 100px auto 0;
			background-color: skyblue;
			border-radius: 10px;
			transition: all .6s ease;
		}

		.gradient {
			position: absolute;
			top: 0;
			left: -100%;
			width: 100%;
			height: 100%;
			transform: skew(-25deg);
			background-image: linear-gradient(0deg, hsla(0, 0%, 100%, 0), hsla(0, 0%, 100%, 0.5), hsla(0, 0%, 100%, 0));
			transition: all .6s ease;
			opacity: 0;
		}

		.wrap:hover {
			transform: translateY(-6px);
			box-shadow: 0 0 20px 0 lightgreen;
		}
		.wrap:hover .gradient {
			opacity: 1;
			left: 120%;
		}

滤镜

	.wrap{
		width: 400px;
		height: 400px;
		background: url(1.jpg) no-repeat center/cover;
		margin: 30px auto;
		transition: 0.5s
		}
	wrap:hover{
       filter:brightness(1.5);/*亮度
    当倍数值大于1的时候元素会变亮,小于1的时候元素会变暗
该属性的作用为调整元素当前的亮度,一般来说可以适用于鼠标悬浮到某元素时的提醒作用*/
     }
	<div class="wrap"></div>
对比度 filter:contrast(百分比);默认是100%
所谓对比度,简单理解的话就是一个区域里面每个颜色都会变得格外显眼,黑的更黑,白的更白
模糊 filter:blur(模糊半径)像素
给图像设置高斯模糊。模糊半径的值设定高斯函数的标准差,或者是屏幕上以多少像素融在一起, 所以值越大越模糊;
灰色色阶 filter:grayscale(百分比)默认是0%
该属性的作用较为简单,就是将一个颜色复杂的区域改造成一个只有黑白二色的区域。圆括号里面的值定义转换的比例。值为100%则完全转为灰度图像,值为0%图像无变化。值在0%到100%之间,则是效果的线性乘子。若未设置,值默认是0;
褐色色阶 filter:sepia(百分比)默认是0%
该属性的作用同上,都是将某个区域的颜色进行简化,该属性会将一个颜色丰富的区域变成一种老黑白照片效果,让图片有一种轻微泛黄的样子
饱和度filter:saturate(%);转换图像饱和度。圆括号里面的值定义转换的比例。值为0%则是完全不饱和,值为100%则图像无变化。其他值,则是效果的线性乘子。超过100%的值是允许的,则有更高的饱和度。 若值未设置,值默认是1。随着饱和度的增加,颜色就会更“清楚”。饱和度越小,颜色就会越“淡”;
/*实例*/
<div class="wrap">
		<div class="son1"></div>
		<div class="son2"></div>
		<div class="son3"></div>
	</div>	
	body{
			margin: 0;
			background-color: black;
		}
		.wrap{
			position: relative;
			width: 600px;
			height: 600px;
			background-color:#000;
			margin: 20px auto;
			filter: blur(20px) contrast(30);
		}
		.wrap>div{
			position: absolute;
			top: 0;
			bottom: 0;
			left: 0;
			right: 0;
			margin: auto;
			width: 100px;
			height: 100px;
			background-color: #fff;
			border-radius: 50%;
		}
		.son2{
			transform: translate(-200px);
		}
		.son3{
			transform: translate(200px);
			box-shadow: 400px 0 0 #fff;
			animation: move 1s linear infinite alternate;
		}
		@keyframes move{
			from{
				box-shadow: 400px 0 0 #fff;
			}
			to{
				box-shadow: -800px 0 0 #fff;
			}
		}

遮罩

遮住一部分,只露出一部分表现效果

css3的属性,不重要,兼容性也不好,IE浏览器不支持,webkit内核的浏览器(包括chrome、safari、IOS、android)需要添加-webkit-前缀。要特别注意的是,firefox浏览器也支持webkit-mask属性

各种游览器对我们写出来的效果不一样.各种标准更新迭代也很快,对新标准的支持程度也不一.所以我你们要写出兼容性前缀要它更好的识别.

	.box{
			width: 300px;
			height: 300px;
			background:url("1.jpg") no-repeat center/cover;
			margin: 100px auto 0;
			-webkit-mask-image:linear-gradient(red,blue);
    	}
			/*此时没有任何效果,打开控制台可以看到我们代码运行已经成功了.
			  可是为什么没有效果呢?此时我们就要去讲,遮罩用什么遮的呢?
  			我们要用transparent透明去遮住图片.
         遮罩mask的功能就是使用透明的图片或渐变遮罩元素的背景*/

-webkit-mask-image:linear-gradient(red,transparent);
/*这就有点相当于我们滤镜了,我们去给背景添加一个颜色*/
body{ background-color: skyblue ;}
/*图片会穿过透明层,观察到后面的内容.
  我们还可以写径向渐变去实现遮罩.*/
-webkit-mask-image:radial-gradient(red,transparent)
/*我们还可以去写写百分比.*/
-webkit-mask-image:radial-gradient(red 50%,transparent 50%);
/*外围一圈就完全被遮住了.*/

**ps:**遮罩可以用透明png图片实现去遮罩

遮罩mask是一个复合属性,

mask-image,默认值为none,值为透明图片,或透明渐变

mask-repeat,默认值为repeat,可选值与background-repeat相同

mask-position.默认值为0 0,可选值与background-position相同

mask-clip,默认值为border-box,可选值与background-clip相同

mask-origin,默认值为border-box,可选值与background-origin相同

mask-size,默认值为auto,可选值与background-size相同

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值