用css3和canvas实现的蜂窝动画效果

近期工作时研究了一下css3动画和js动画。主要是工作中为了增强页面的趣味性,大家都有意无意的加入了非常多动画效果。当然大部分都是css3动画效果。能够gpu加速,这会降低移动端的性能需求。

今天主要说的是蜂窝效果。详细效果大家等下能够执行源代码。这里就不放gif图了。

css3的原理非常easy,就是通过更改background-size,因为css3中的background中能够设置repeat属性,来使背景图片在x,y方向平铺。一開始先设置background-size:10%, 10%,(这个数值能够自由定义,但不介意设置过大,否则效果不明显), 最后更改backg-size:100%, 100%;这样会使背景图片充满整个屏幕,哦。对了不要忘记设置background-position:50%
50%;否则你会感觉怪怪的,设置background-position是为了是背景图片以中心点的位置来平铺,而系统默认会已左上角来平铺。

然后通过设置animation动画来调用动画就能够实现这样的效果了

<pre name="code" class="html">.honey {
			position: absolute;
			top: 0;
			left: 0;
			height: 100%;
			width: 100%;
			background: url(2.jpg) repeat;
			background-size: 30% 30%;
			background-position: center center;
			-webkit-animation: honeycomb 3s 1 linear;
		}

		@-webkit-keyframes honeycomb {
			0% {
				background-size: 10% 10%;
			}
			100% {
				background-size: 100% 100%;
			}
		}

使用css3来实现这样的蜂窝式的动画效果,原理简单。而且效果非常完美,可是唯一一点的不完美在于可能会有一部分手机不兼容。而且通过在animation中改动background-size,这样的行为非常少。尽管不会引起浏览器的重排,可是也会引起浏览器的局部重绘。

至于使用canvas来实现吗。这个纯属无聊,不建议大家使用这样的方法。在这里使用canvas来绘制。全然是属于我的无聊之举。只是若是你对canvas动画有意向。能够留意以下的canvas实现方案。canvas绘制的原理非常easy。通过传入width,height的百分比。来计算一共须要画多少个矩形,以及每一个矩形的中心点坐标。我把这个代码封装成了一个模块。大家能够一步一步的往下看,首先先定义一个对象honey对象吧

var Honey = function (options) {

		for (var i in options) {
			if (options.hasOwnProperty(i)) {
				this[i] = options[i];
			}
		}
		this.canvas = this.canvasId || document.getElementById(this.canvasId) || document.getElementById(‘#canvas‘);
		this.ctx = this.canvas.getContext(‘2d‘);
		this.canvasWidth = document.body.getBoundingClientRect().width;
		this.canvasHeight = document.body.getBoundingClientRect().height;

		this.canvas.width = this.canvasWidth;
		this.canvas.height = this.canvasHeight;

		this.stopped = true;
		this.width = options[‘width‘] || 10;
		this.height = options[‘height‘] || 10;
		this.dwidth = options[‘dwidth‘] || 1;
		this.dheight = options[‘dheight‘] || 1;
		this.img = options.img;
		/*if (!options.img) {
			console.log(‘没有传入图片地址‘);
		}*/
	};

以下在来定义这个对象中的一些属性,canvas的绘制图像默认是从左上角開始绘制,因此我们须要自己写一个方法来从中心点绘制,能够通过prototype来加入到属性中

drawImage : function (x, y, w, h) {
			var width = w * this.canvasWidth / 100,
				height = h * this.canvasHeight / 100;

			var top = y - height / 2,
				left = x - width / 2;
			var self = this;
			// var img = self.img;
			// img.onload = function () {
				self.ctx.drawImage(self.img, left, top, width, height);
			// }
		},

这种方法非常easy吧。仅仅只是是简单的偏移了一半的宽高。再调用canvas的默认绘制函数

接下来的方法是获取所须要绘制矩形的中心点位置了,先看代码:

		// 获取全部显示小图片的中心点位置
		getPoints : function (width, height) {
			// var width = parseInt(w), height = parseInt(h);
			var numW = Math.ceil(100 / width), numH = Math.ceil(100 / height);
			var result = [];

			for (var i = -Math.ceil(numW * 0.5); i <= Math.ceil(numW * 0.5); i++) {
				var x = 50 + width * i;
				for (var j = -Math.ceil(numH * 0.5); j <= Math.ceil(numH * 0.5); j++) {
					var y = 50 + height * j;
					result.push({x: x * this.canvasWidth / 100, y: y * this.canvasHeight / 100});
				}
			}

			return result;
		},

事实上原来就是从canvas的中心点50, 50出发,numW, numH分别表示在水平方向和垂直方向所须要画的矩形个数,这里要注意使用Math.ceil向上取整。是为了确保可以撑满整个canvas,然后x = 50 + width * i;代表在x方向上减去width的值,就等于中心点左边第几个x值,同理y方向上也一样,最后函数返回一个包括全部坐标点的数组。

接下来就是使用这个数组和上面提供的绘制方法,来一个一个的将全部图片绘制出来。

完整的模块源代码例如以下:

define(function (require, exports, module) {

	var RAF = window.requestAnimationFrame ||
			  window.webkietRequestAnimationFrame ||
			  function (callback) {
			  	setTimeout(callback, 1000/ 60);
			  };

	var Honey = function (options) {

		for (var i in options) {
			if (options.hasOwnProperty(i)) {
				this[i] = options[i];
			}
		}
		this.canvas = this.canvasId || document.getElementById(this.canvasId) || document.getElementById(‘#canvas‘);
		this.ctx = this.canvas.getContext(‘2d‘);
		this.canvasWidth = document.body.getBoundingClientRect().width;
		this.canvasHeight = document.body.getBoundingClientRect().height;

		this.canvas.width = this.canvasWidth;
		this.canvas.height = this.canvasHeight;

		this.stopped = true;
		this.width = options[‘width‘] || 10;
		this.height = options[‘height‘] || 10;
		this.dwidth = options[‘dwidth‘] || 1;
		this.dheight = options[‘dheight‘] || 1;
		this.img = options.img;
		/*if (!options.img) {
			console.log(‘没有传入图片地址‘);
		}*/
	};

	Honey.prototype = {

		// 以中心点来绘图
		drawImage : function (x, y, w, h) {
			var width = w * this.canvasWidth / 100,
				height = h * this.canvasHeight / 100;

			var top = y - height / 2,
				left = x - width / 2;
			var self = this;
			// var img = self.img;
			// img.onload = function () {
				self.ctx.drawImage(self.img, left, top, width, height);
			// }
		},

		// 获取全部显示小图片的中心点位置
		getPoints : function (width, height) {
			// var width = parseInt(w), height = parseInt(h);
			var numW = Math.ceil(100 / width), numH = Math.ceil(100 / height);
			var result = [];

			for (var i = -Math.ceil(numW * 0.5); i <= Math.ceil(numW * 0.5); i++) {
				var x = 50 + width * i;
				for (var j = -Math.ceil(numH * 0.5); j <= Math.ceil(numH * 0.5); j++) {
					var y = 50 + height * j;
					result.push({x: x * this.canvasWidth / 100, y: y * this.canvasHeight / 100});
				}
			}

			return result;
		},

		init : function () {
			var width = this.width,
				height = this.height,
				dwidth = this.dwidth,
				dheight = this.dheight,
				loaded = false;;
			var self = this;
			var img = this.img;

			if (!img) {
				console.log(‘没有传入图片地址‘);
				return;
			}
			if (typeof img == ‘string‘) {
				var image = new Image();
				image.src = img;
				img = image;
				this.img = img;
			}

			tick();

			function tick () {
				if (!self.stopped) {
					width += dwidth;
					height += dheight;

					// 防止图片过大缩放,自己主动设置停止标志位
					if (width >= 100) {
						width = 100;
					}
					if (height >= 100) {
						height = 100;
					}
					if (width >= 100 && height >= 100) {
						self.stopped = true;
					}
					// 绘图
					self.animate(width, height);
					RAF(function () {
						tick();
					})
				}
			}
		},

		animate : function (w, h) {
			var self = this;
			var points = self.getPoints(w, h);
			// console.log(points.length, w, h);
			self.clear();
			for (var i = 0, len = points.length; i < len; i++) {
				var point = points[i];
				// console.log(point.x, point.y , w * this.canvasWidth / 100, h * this.canvasHeight / 100);
				self.drawImage(point.x, point.y, w, h);
			}
		},

		clear : function () {
			this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
		}
	};

	return Honey;
})

这里使用requestAnimatioFrame来循环调用,而不是常见的setTimeout,详细原因大家还是Google吧。使用canvas来绘制会比較耗性能,不介意大家使用。可是假设是在写canvas动画时,大家能够考虑加入这么一个动画效果。

时间: 2024-10-12 18:08:19

用css3和canvas实现的蜂窝动画效果的相关文章

一款纯css3实现的机器人看书动画效果

今天要给大家介绍一款纯css3实现的机器人看书动画效果.整个画面完全由css3实现的绘制,没有使用任何图片元素.机器人的眼睛使用了动画元素.我们一起看下效果图: 在线预览   源码下载 实现的代码. html代码: <div class='szene'> <div class='image i1'> < HTML > <div class='nail'> </div> </div> <div class='image i2'&g

CSS3背景闪烁和图片缩放动画效果

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>CSS3感应鼠标的背景闪烁和图片缩放动态效

css3实现的3中loading动画效果

一.css3中animation动画各种属性详解: animation Value:     [<animation-name> || <animation-duration> || <animation-timing-function> || <animation-delay> || <animation-iteration-count> || <animation-direction> || <animation-fill-

CSS3实现照片墙的布局及动画效果

目标:实现照片墙布局和鼠标经过图片时的动画效果 涉及知识点:CSS3的动画.过渡.变形(缩放),绝对定位与相对定位 疑点:绝对定位与相对定位对页面元素显示层次的影响 参考极客学院布道师iwen的课程 源码—— html部分: <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8"> <title></title> <link

web前端入门到实战:css3循环,模拟拼多多动画效果

模拟拼多多动画效果,最终效果图如下: 我们看一下实现过程. 主框架是vue开发,做成了一个动画组件,因为涉及到多个页面引用,最主要的实现是css3语法实现过程,并且要做到循环播放. 左边出来动画时间是0.5秒,停留3秒往上走,然后动画时间0.5秒,停留3秒后然后消失,消失动画时间0.5秒,总共的时间消耗是7.5秒.可以得到以下计算比例 如果大家对编程,web前端感兴趣,想要学习,打算深入了解这个行业的朋友,可以加下我们的前端学习扣qun : 784783012 ,不论你是学生还是想转行的朋友,我

详解用CSS3制作圆形滚动进度条动画效果

内  容 先看一下效果图,会提升我们的学习兴趣哟: 对于圆形效果是重点,我将详细讲解. 第一种效果: html结构: <div id="progress"> <span></span> </div> css样式: #progress{ width: 50%; height: 30px; border:1px solid #ccc; border-radius: 15px; margin: 50px 0 0 100px; overflow:

CSS3实现加载中的动画效果

本篇文章由:http://xinpure.com/css3-implementations-of-loading-an-animation-effect/ Loading 的菊花图形组合的不太好,基本上实现这个功能了 动画解析 这个动画用到的 CSS3 特性: transform 主要使用 transform 属性的 rotate,将线条组合成 Loading 图形 (也就是常见的菊花图形) animation 实现将线条颜色由浅到深,再由深到浅来回变换的动画,通过 animation-dela

用CSS3制作50个超棒动画效果教程

CSS3为我们带来了令人惊叹的新特性,而最有趣的就是CSS动画.向大家推荐这50个CSS动画集合可以让你通过使用JavaScript函数来让动画更生动.为了能够预览到这些惊人的CSS3技术带来的动画特效,请大家使用如Safari和Chrome这类基于WebKit内核的浏览器.(IE浏览器谢绝观赏~) 1.CSS3实现钟表效果(基于jQuery) 使用CSS3的基本变形特性:rotate,并结合了jQuery这类javaScript框架制作的CSS3时钟效果. 2.模拟时钟 模拟时钟基于过渡web

CSS3 Loading(加载)动画效果

1.html 部分 <div class="spinner"> <div class="rect1"></div> <div class="rect2"></div> <div class="rect3"></div> <div class="rect4"></div> <div class=&