1. 程式人生 > >HTML5 之 Canvas (案例)

HTML5 之 Canvas (案例)


**星星閃動動畫**

1、如何輪播一張圖片上的序列幀

2、canvas的幾個主要繪圖API:drawImage()、save()、restore()。

3、如何處理滑鼠事件

筆記:

Window API

迴圈呼叫三種方法:
requestAnimFrame(fcuntion(){}); //根據電腦效能確定每次回撥的時間(迴圈時間),更科學,提高效率
setTimeout(function(){},time); //等待再執行;是在x秒結束後執行
setInterval(funtion(){},time); //執行再等待;是先執行了,然後再x秒後再次執行

drawImage()

drawImage (x,y)

drawImage (img,x,y,width,height)

drawImage(img, 圖片.sx, 圖片.sy, 圖片.swidth, 圖片.sheight, canves.x, canvas.y, canvan.width, canvas.height);

drawImage (img,實現,使用,swidth,sheight,x,y)

滑鼠控制事件(主要程式碼):

1、

定義一個類:

var starObj = function() {
   this.x;
   this.y;
   this.ySpd;
   this.picNo;
   this.timer;
   this.beta;
}

2、

document.addEventListener("mousemove",mousemove,false);
function mousemove(e){//檢測滑鼠的移動
if(e.offsetX || e.layerX){
var px = e.offsetX == undefined?e.layerX:e.offsetX;
var py = e.offsetY == undefined?e.layerXY:e.offsetY;
//console.log(px);
}
}

3、

globalAlpha全域性透明度
列印:

console.log(switchy);
API:
save();
restore();

可以控制在save和restore之間任何的屬性都只作用在這塊內容之上,而對於之外的內容並不起作用

實現原始碼:

Star.html:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Star Girl</title>
</head>
<body onload = "init()">
<audio src="src/Aimer - 六等星の夜.mp3" autoplay loop></audio>
<script type = "text/javascript" src = "js/main.js"></script>
<script type = "text/javascript" src = "js/stars.js"></script>
<script type = "text/javascript" src = "js/commonFunctions.js"></script>
<div>
    <canvas id = "canvas" width = "800px" height = "600px">
    </canvas>
</div>

</body>
</html>
Star.js
//建立類
var starObj = function() {
	this.x;
	this.y;

	this.ySpd;

	this.picNo;

	this.timer;

	this.beta;
}
//定義方法
//初始化
starObj.prototype.init = function() {
	this.x = Math.random() * girlWidth + padLeft;
	this.y = Math.random() * girlHeight + padTop;

	this.ySpd = Math.random() * 0.6 - 0.3; //[0,2) [-1, 1)
	this.xSpd = Math.random() * 0.2 - 0.1; //[0,2) [-1, 1)

	this.picNo = Math.floor(Math.random() * 7);
	this.timer = 0;

	this.beta = Math.random() * Math.PI * 0.5;
}

starObj.prototype.update = function() {
	this.xSpd = Math.random() * 0.2 - 0.1; //[0,2) [-1, 1)
	this.x += this.xSpd;
	this.y += this.ySpd;

	if (this.x > (padLeft + girlWidth) || this.x < (padLeft - 10))
		this.init();
	else if (this.y > (padTop + girlHeight) || this.y < (padTop - 10))
		this.init();

	this.timer += deltaTime;
	if (this.timer > 30) {
		this.picNo += 1;
		this.picNo %= 7;
		this.timer = 0;
	}
}

starObj.prototype.draw = function() {
	this.beta += deltaTime * 0.005;
	ctx.save();
	ctx.globalAlpha = Math.sin(this.beta) * alive;
	console.log(alive);
	console.log(ctx.globalAlpha);
	ctx.drawImage(starPic, this.picNo * 7, 0, 7, 7, this.x, this.y, 17, 17);
	ctx.restore();
}



function drawStars() {
	for (var i = 0; i < num; i++) {
		stars[i].update();
		stars[i].draw();//每個成員都會繪製在cavans上
	}
}

function aliveUpdate() {
	if (switchy) {
		alive += 0.03;
		if (alive > 0.7) {
			alive = 0.7;
		}
	} else {
		alive -= 0.03;
		if (alive < 0) {
			alive = 0;
		}
	}
}

main.js

var can;
var ctx;

var w;
var h;

var padLeft =10;
var padTop = 10;

var girlWidth =780;
var girlHeight = 580;

var deltaTime;
var lastTime;

var girlPic = new Image();
var starPic = new Image();

var stars = [];
var num = 120;

var alive = 0;

var switchy = false;

function init() {
	can = document.getElementById("canvas");
	ctx = can.getContext("2d");

	w = can.width;
	h = can.height;

	document.addEventListener('mousemove', mousemove, false);

	girlPic.src = "src/girl.jpg";
	starPic.src = "src/star.png";
//使用類的方法
	for (var i = 0; i < num; i++) {
		stars[i] = new starObj();//定義一個變數
		stars[i].init();
	}

	lastTime = Date.now();
	gameLoop();
}

function gameLoop() {
	window.requestAnimFrame(gameLoop);
	var now = Date.now();
	deltaTime = now - lastTime;
	lastTime = now;

	fillCanvas();
	drawGirl();

	drawStars();

	aliveUpdate();
}

function fillCanvas() {
	ctx.fillStyle = "#FFCCFF";
	ctx.fillRect(0, 0, w, h);
}

function drawGirl() {
	ctx.drawImage(girlPic, padLeft, padTop, girlWidth, girlHeight);
}

function mousemove(e) {
	if (e.offsetX || e.layerX) {

		var px = e.offsetX == undefined ? e.layerX : e.offsetX;
		var py = e.offsetY == undefined ? e.layerY : e.offsetY;

		if (px > padLeft && px < (padLeft + girlWidth) && py > padTop && py < (padTop + girlHeight)) {
			switchy = true;
		} else {
			switchy = false;
		}
	}
}
commonFunctions.js
window.requestAnimFrame = (function() {
	return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
		function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
			return window.setTimeout(callback, 1000 / 60);
		};
})();

//計算長度的平方
function calLength2(x1, y1, x2, y2) {
	return Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2);
}

//獲得隨機顏色
function randomColor() {
	var col = [0, 1, 2];
	col[0] = Math.random() * 100 + 155;
	col[0] = col[0].toFixed();
	col[1] = Math.random() * 100 + 155;
	col[1] = col[1].toFixed();
	col[2] = Math.random() * 100 + 155;
	col[2] = col[2].toFixed();
	var num = Math.floor(Math.random() * 3);
	col[num] = 0;
	return "rgba(" + col[0] + "," + col[1] + "," + col[2] + ",";
}

//角度
function lerpAngle(a, b, t) {
	var d = b - a;
	if (d > Math.PI) d = d - 2 * Math.PI;
	if (d < -Math.PI) d = d + 2 * Math.PI;
	return a + d * t;
}

function inOboundary(arrX, arrY, l, r, t, b) { //在l r t b範圍內的檢測
	return arrX > l && arrX < r && arrY > t && arrY < b;
}

function rgbColor(r, g, b) {
	r = Math.round(r * 256);
	g = Math.round(g * 256);
	b = Math.round(b * 256);
	return "rgba(" + r + "," + g + "," + b + ",1)";
}

function rgbNum(r, g, b) {
	r = Math.round(r * 256);
	g = Math.round(g * 256);
	b = Math.round(b * 256);
	return "rgba(" + r + "," + g + "," + b;
}

function rnd(m) {
	var n = m || 1;
	return Math.random() * n;
}

function rateRandom(m, n) {
	var sum = 0;
	for (var i = 1; i < (n - m); i++) {
		sum += i;

	}

	var ran = Math.random() * sum;

	for (var i = 1; i < (n - m); i++) {
		ran -= i;
		if (ran < 0) {
			return i - 1 + m;
		}
	}
}

function distance(x1, y1, x2, y2, l) {
	var x = Math.abs(x1 - x2);
	var y = Math.abs(y1 - y2);
	if (x < l && y < l) {
		return true;
	}
	return false;
}

function AABBbox(object1, w1, h1, object2, w2, h2, overlap) {
	A1 = object1.x + overlap;
	B1 = object1.x + w1 - overlap;
	C1 = object1.y + overlap;
	D1 = object1.y + h1 - overlap;

	A2 = object2.x + overlap;
	B2 = object2.x + w2 - overlap;
	C2 = object2.y + overlap;
	D2 = object2.y + h2 - overlap;

	if (A1 > B2 || B1 < A2 || C1 > D2 || D1 < C2) return false;
	else return true;
}


function dis2(x, y, x0, y0) {
	var dx = x - x0;
	var dy = y - y0;
	return dx * dx + dy * dy;
}

function rndi2(m, n) {
	var a = Math.random() * (n - m) + m;
	return Math.floor(a);
}