CSS3从头来过_3

过渡

transition:提供了一种在更改CSS属性时控制动画速度的方法,其可以让属性变化成为一个持续一段时间的过程,而不是立即生效的,它是一个简写属性

  1. API介绍
    transition-property 指定要产生过渡效果的属性,有些属性不能产生过渡效果,比如display
    transition-duration 指定过渡持续的时间,必须带单位
    transition-timing-function 指定过渡运动的形式
    transition-delay 指定过渡效果开始之前的延迟时间

  2. 注意点
    2.1 当属性值对应不一致的时候:
    transition-property: width height color;
    transition-duration: 1s 2s;
    transition-timing-function: ease linear;
    transition-delay: 1s 2s;
    时间列表会重复,并将多余的截去,而运动形式则采用默认值ease,(1s 2s)重复成(1s 2s 1s 2s)将1s给color,将多余的2s截去,color的运动形式直接采用默认值ease
    2.2 0也一定要带单位
    transition-duration: 0 和 transition-duration: 0s 区别很大

  3. 过渡事件
    当过渡效果完成时触发一个事件,在符合标准的浏览器下,这个事件是transitionend,在webkit内核下是webkitTransitionEnd
    每一个拥有过渡的属性在其完成过渡时都会触发一次transitionend事件
    在transitionend完成前设置display:none,事件不会触发

  4. 过渡的天坑

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			*{
				margin: 0;
				padding: 0;
			}
			html{
				height: 100%;
			}
			body{
				height: 60%;
				width: 60%;
				margin: 100px auto 0;
				border: 1px solid;
			}
			#test{
				width: 200px;
				height: 200px;
				border-radius: 50%;
				background: pink;
				text-align: center;
				font: 30px/200px "微软雅黑";
				position: absolute;
				top: 0;
				right: 0;
				bottom: 0;
				left: 0;
				margin: auto;
				transition-property: width;
				transition-duration: 2s;
				transition-timing-function: linear;
			}
			body:hover #test{
				transition-property: height;
				width: 100px;
				height: 100px;
			}
			/* 这样写鼠标悬浮是高度先变,鼠标移出宽度在变 */
			/* 要注意的是:此时,当鼠标移入框内时,变化的并不是width,而是height;
			当鼠标移出框内时,width进行变化。解释:这跟浏览器的渲染机制有关系,
			浏览器真正在页面上渲染动画过程中是需要去画布局的,
			这个过程比解析代码来得慢,导致有一个时间差。
			浏览器第一次解析时的确是移入框内width进行变化。
			但是,CSS代码解析的速度极快,当鼠标移入框内时,
			触发body:hover #test中的代码,发现有transition-property: height;
			因此就立即把内存中需要变化的width改为height;在这一过程中,
			浏览器根本来不及进行渲染工作,因此,当渲染发生时,
			浏览器去内存中寻找到底是哪个属性要进行过渡,此时,
			width已经被改为height,所以渲染的时候,就直接将更改后的height进行过渡。
			然后,当鼠标移出框外的一瞬间,浏览器发现有transition-property: width;
			然后就立即把height改为width,这段时间内浏览器仍然由于时间太短而无法进行渲染工作,
			因此移出时是width进行过渡
			*/
		</style>
	</head>
	<body>
		<div id="test">
			123
		</div>
	</body>
</html>

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
			}

			html {
				height: 100%;
			}

			body {
				width: 60%;
				height: 60%;
				border: 1px solid;
				margin: 100px auto 0;
			}

			#test {
				width: 100px;
				height: 100px;
				background: pink;
				text-align: center;
				position: absolute;
				left: 0;
				right: 0;
				bottom: 0;
				top: 0;
				margin: auto;
				/*------------以上代码用于居中、边框等--------------*/
				transition-property: width;
				transition-duration: 2s;
				transition-timing-function: linear;
			}
		</style>
	</head>
	<body>
		<div id="test">
		</div>
	</body>
	<script type="text/javascript">
		//transition在元素首次渲染还没有结束的情况下是不会触发的
		window.onload = function() {
			var test = document.querySelector("#test");
			// 这样也没有渲染效果,因为又变成了100px,100px到100px没有过渡效果
			test.style.width = "300px";
			test.style.width = "100px";
			//
			/*
			这样也属于首次渲染,不会触发过渡效果
			var test = document.createElement("div");
			test.id = "test";
			document.documentElement.appendChhild(test);
			//这里加个2s定时器就可以
			test.style.width = "300px"
			*/
		}
	</script>
</html>

  1. 过渡的简写属性
    CSS过渡由简写属性定义是最好的方式,可以避免属性值列表长度不一,节省调试时间,但要注意,在transition属性中,各个值的书写顺序是很重要的,第一个解析成时间赋给transition-duration,第二个解析成时间的值会赋值给transition-delay延迟

2D变换

transform属性允许你修改CSS视觉格式模型的坐标空间
transform属性,只对block级元素生效

  1. 旋转
    transform: rotate(角度)

  2. 平移
    transform: translate(x轴偏移,Y轴偏移) 一个参数时也是X轴偏移
    translateX(偏移量) translateY(偏移量)

  3. 倾斜
    skew(角度) 单值仅对X有效

  4. 缩放
    scale(数字) 大于1放大 小于1缩小 单值X,Y均有效

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
			}

			html {
				height: 100%;
				overflow: hidden;
			}

			body {
				height: 60%;
				width: 60%;
				margin: 100px auto 0;
				border: 1px solid;
				overflow: hidden;
			}
        
			#test {
				width: 200px;
				height: 200px;
				border-radius: 50%;
				background: pink;
				text-align: center;
				font: 30px/200px "微软雅黑";
				position: absolute;
				top: 0;
				right: 0;
				bottom: 0;
				left: 0;
				margin: auto;
				transition: transform 1s linear;
				/* 基点变换 基于左上角的位置变换 */
				/* 可以写像素,也可以写百分比 */
				/* 对平移不会造成影响 */
				/* transform-origin: left top; */
			}

			body:hover #test {
				transform: rotate(360deg);
				/* transform: translateX(100px); */
				/* transform: skew(45deg); */
				/* transform: scale(1.5); */
			}

		</style>
	</head>
	<body>
		<div id="test">
			123
		</div>
	</body>
</html>

  1. 基点的变换
    transform-origin: left top; //基于左上角进行变换
    10px 10px; //基于(10px 10px)的位置进行变换
    10% 10%; //基于自身(10% 10%)的位置进行变换

  2. 2D变换组合
    变换的本质是矩阵的计算,对应的变换就是乘以对应变换的矩阵
    transform: rotate(45deg) translateX(100px)
    transform: translateX(100px) rotate(45deg)
    变换组合的计算方式是从右往左进行计算,第一个是先乘以X轴平移的矩阵,再乘以旋转的矩阵,第二个是先乘以旋转的矩阵,再乘以X轴平移的矩阵
    二者的效果不同,因为矩阵乘法不满足交换律

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
			}

			html {
				height: 100%;
				overflow: hidden;
			}

			body {
				height: 60%;
				width: 60%;
				margin: 100px auto 0;
				border: 1px solid;
				overflow: hidden;
			}

			#test {
				width: 200px;
				height: 200px;
				border-radius: 50%;
				background: pink;
				text-align: center;
				font: 30px/200px "微软雅黑";
				position: absolute;
				top: 0;
				right: 0;
				bottom: 0;
				left: 0;
				margin: auto;
				transition: 1s;
			}

			body:hover #test {
				/* 变换组合都是从右往左进行计算的 */
				/* 变换的本质是矩阵的计算,对应的变换就是乘以对应变换矩阵 */
				transform: translateX(200px) rotate(360deg);
				/* 两者变换效果,大不同,因为矩阵乘法不满足交换律 */
				/* transform: rotate(360deg) translateX(200px); */
			}
		</style>
	</head>
	<body>
		<div id="test">
			123
		</div>
	</body>
</html>

综合应用
时钟

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
			}

			#wrap {
				/* 钟盘居中,没什么好说的 */
				position: absolute;
				left: 50%;
				top: 50%;
				margin-top: -100px;
				margin-left: -100px;
				width: 200px;
				height: 200px;
				border: 1px solid black;
				border-radius: 50%;
			}

			#wrap>ul {
				list-style: none;
			}

			#wrap>ul>li {
				/* 移动到12点的位置 */
				position: absolute;
				top: 0;
				left: 99px;
				width: 2px;
				height: 10px;
				background: #000000;
				/* 旋转的基点调整为钟盘的圆心 */
				transform-origin: center 100px;
			}

			#wrap>ul>li:nth-child(5n+1) {
				/* 长针怼出来 */
				height: 15px;
			}

			#wrap>.hour {
				/* left:100-width/2 */
				/* top:100-height */
				position: absolute;
				left: 97px;
				top: 70px;
				width: 6px;
				height: 30px;
				background: black;
				/* 基点为自己的`尾巴` */
				transform-origin: center bottom;
			}

			#wrap>.minute {
				position: absolute;
				left: 98px;
				top: 50px;
				width: 4px;
				height: 50px;
				background: gray;
				transform-origin: center bottom;
			}

			#wrap>.second {
				position: absolute;
				left: 99px;
				top: 30px;
				width: 2px;
				height: 70px;
				background: red;
				transform-origin: center bottom;
			}

			#wrap>.icon {
				/* left:100-width/2 */
				/* top:100-height/2 */
				position: absolute;
				left: 90px;
				top: 90px;
				width: 20px;
				height: 20px;
				background: pink;
				border-radius: 50%;
			}
		</style>
	</head>
	<body>
		<div id="wrap">
			<ul>
			</ul>
			<div class="hour">

			</div>
			<div class="minute">

			</div>
			<div class="second">

			</div>
			<div class="icon">

			</div>
		</div>
	</body>
	<script type="text/javascript">
		// 获取相关操作节点
		var hourNode = document.querySelector("#wrap>.hour");
		var minuteNode = document.querySelector("#wrap>.minute");
		var secondNode = document.querySelector("#wrap>.second");
		var ulNode = document.querySelector("#wrap>ul");
		//创建一个style节点
		var styleNode = document.createElement("style");
		var liHTML = "";
		var styleHTML = "";
		//往ul里面塞60个li,并添加旋转,每次增加旋转6度,转出一个表的刻度
		for (let i = 0; i < 60; i++) {
			liHTML += "<li></li>";
			styleHTML += `#wrap>ul>li:nth-child(${i+1}){transform: rotate(${6*i}deg)}`;
		}
		ulNode.innerHTML = liHTML;
		styleNode.innerHTML = styleHTML;
		document.head.appendChild(styleNode);
        
		move();
		//1s执行一次,模拟时钟一s走一下嘛
		setInterval(move, 1000);
        
		//走表函数
		function move() {
			//获取当前时间
			var date = new Date();
			var s = date.getSeconds();
			//加上秒数的尾巴,每次分数都不一样,模拟分针每次都走嘛
			var m = date.getMinutes() + s / 60;
			//类似
			var h = date.getHours() + m / 60;
            
			//时针一个小时走360/12=30°
			hourNode.style.transform = `rotate(${h*30}deg)`;
			//分针一分钟6°
			minuteNode.style.transform = `rotate(${m*6}deg)`;
			//秒针一秒6°
			secondNode.style.transform = `rotate(${s*6}deg)`;
		}
	</script>
</html>

扇形导航

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
			}

			#wrap {
				height: 50px;
				width: 50px;
				position: fixed;
				right: 0;
				bottom: 0;
				border-radius: 50%;
			}

			#wrap>.inner {
				height: 100%;
			}

			#wrap>.inner>img {
				position: absolute;
				left: 0;
				top: 0;
				margin: 4px;
				border-radius: 50%;
			}

			#wrap>#home {
				width: 100%;
				height: 100%;
				position: absolute;
				left: 0;
				top: 0;
				z-index: 1;
				transition: 1.5s;
			}

			#home>img {
				border-radius: 50%;
			}
		</style>
	</head>
	<body>
		<div id="wrap">
			<div class="inner">
				<img src="img/clos.png">
				<img src="img/full.png">
				<img src="img/open.png">
				<img src="img/prev.png">
				<img src="img/refresh.png">
			</div>
			<div id="home">
				<img src="img/home.png">
			</div>
		</div>
	</body>
	<script type="text/javascript">
		window.onload = function() {
			var homeElem = document.querySelector("#home");
			var imgs = document.querySelectorAll("#wrap>.inner>img");
			var c = 140;
			var flag = true;
			//第二部分(点击放大并缩回去)
			for (let i = 0; i < imgs.length; i++) {
				imgs[i].onclick = function() {
					//存在闭包,里面不要用i,用this
					//注意点1:记得重置一下,因为下面也操作了img,并增加了延迟
					//这里应该取消掉延迟
					this.style.transition = "0.5s";
					//为了防止样式切换时对应不一致,导致效果失效
					//transform覆盖的时候应该带上上次的状态
					//这是最笨的办法,我们可以自己封装一个函数处理,抱歉,我不会
					this.style.transform = "rotate(-720deg) scale(2)";
					this.style.opacity = 0.1;
					//过渡结束就会触发的事件,必须放在这个函数里面
					//不然外面的过渡效果结束,也会来触发这个事件
					this.addEventListener("transitionend", fn);
				}
			}

			function fn() {
				this.style.transition = "0.3s";
				this.style.transform = "rotate(-720deg) scale(1)";
				this.style.opacity = 1;
				//因为事件一旦绑定就不会消失,这样其他的过渡效果也会触发这个事件
				//所以应该解绑
				this.removeEventListener("transitionend", fn);
			}
			//第一部分(导航出现和消失)
			homeElem.onclick = function() {
				if (flag) {
					this.style.transform = "rotate(-720deg)";
					for (let i = 0; i < imgs.length; i++) {
						imgs[i].style.transition = `1s ${i*0.1}s`;
						imgs[i].style.transform = "rotate(-720deg) scale(1)";
						imgs[i].style.top = -getPosition(c, 90 * i / (imgs.length - 1)).top + "px";
						imgs[i].style.left = -getPosition(c, 90 * i / (imgs.length - 1)).left + "px";
					}
				} else {
					this.style.transform = "rotate(0deg) scale(1)";
					for (let i = 0; i < imgs.length; i++) {
						imgs[i].style.transition = `1s ${(imgs.length-1-i)*0.1}s`;
						imgs[i].style.transform = "rotate(0deg)";
						imgs[i].style.top = 0;
						imgs[i].style.left = 0;
					}
				}
				flag = !flag;
			}

			function getPosition(c, deg) {
				var x = Math.round(c * Math.sin(deg * Math.PI / 180));
				var y = Math.round(c * Math.cos(deg * Math.PI / 180));
				return {
					left: x,
					top: y
				};
			}
		}
	</script>
</html>

好了,我的分享就到这里了,谢谢大家

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值