<<javascript 高效图形编程>>笔记
来源:互联网 发布:linux内核源码 编辑:程序博客网 时间:2024/05/16 17:41
某天在学校图书馆里溜达的时候看见的这本书,感觉应该有点干货就借回来了.放了几天,今天干什么都不对劲,就把这本书拿出来看了看,发现一些有意思的东西.
第一个是一个递归绘图,之前见过类似的小动画,感觉很神奇,没想到在这本书里的代码就简简单单的一点.
对我来说最没想到的是这个代码就像平时的递归程序一样简单,我总觉得牵涉到图形的时候一切都悔变得复杂,就不愿意动脑了,这样不好.
<!DOCTYPE html><html> <head> <title>OK</title> <script type = "text/javascript" src = "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script type = "text/javascript"> var maxAngle = Math.PI / 7;//控制子树于亲树的角度偏转最大值 var drawTree = function(ctx, startX, startY, length, angle, depth, branchWidth) {//如同深度优先搜索一般简洁明了的程序 var newLength, endX, endY, newAngle; if (depth < 0) { return; } //枝杈终点 endX = startX + length * Math.cos(angle); endY = startY + length * Math.sin(angle); //绘出当前枝杈 ctx.beginPath(); ctx.moveTo(startX, startY); ctx.lineCap = "round"; ctx.lineWidth = branchWidth; ctx.lineTo(endX, endY); if (depth <= 2) {//根据是否靠近边缘决定颜色 ctx.strokeStyle = 'rgb(0, ' + (((Math.random() * 64) + 128) >> 0) + ', 0)';//strokestyle接受字符串 } else { ctx.strokeStyle = 'rgb(' + (((Math.random() * 64) + 64) >> 0) + ', 50, 25)'; } ctx.stroke(); //下级枝杈 branchWidth *= 0.7; newAngle = angle - Math.random() * maxAngle; newLength = length * (0.7 + Math.random() * 0.3); drawTree(ctx, endX, endY, newLength, newAngle, depth - 1, branchWidth); newAngle = angle + Math.random() * maxAngle; newLength = length * (0.7 + Math.random() * 0.3); drawTree(ctx, endX, endY, newLength, newAngle, depth - 1, branchWidth); }; </script> </head> <body> <script type = "text/javascript"> $(document).ready(function(){ var cvs = document.getElementById('myCanvas'); var ctx = cvs.getContext("2d"); drawTree(ctx, 400, 600, 60, -Math.PI/2, 14, 12); }); </script> <canvas id = "myCanvas" width = "800" height = "600" /> </body></html>上张效果图
第二个是一个大炮模拟程序,里面使用了向量,游戏对象,还有一些我之前没见过的API,对我启发很大.
要记一下的地方:
1 函数继承 形如 : var vector = function(){var that = {}; return that;};
2 对象字面量,以前一直没用过.
3 向量,还有向量的操作.
4 API
原来可以在元素节点上加事件监听,以前一直不知道.
ctx.save() && ctx.restore() 保存和重绘canvas, 在做有背景的动画时用这个绘制背景,不丢失动画元素渐变信息.
ctx.rotate(), 旋转ctx, 可以画倾斜的矩形了
canvas.getBoundingClientRect(), event里的坐标是相对于整个窗口的,我们要的是相对于画布的坐标,用此获得画布的坐标.
5 gameObjects数组,管理游戏元素
<!DOCTYPE html><html><head><title>GO !!!</title><script type = "text/javascript">window.onload = function(){var gameObjects = [];var canvas = document.getElementById("canvas");var ctx = canvas.getContext('2d');var vector2d = function(x, y){var vec = {vx : x,vy : y,//scale() method allows us to scale hte vector, eighter up or down.scale : function(scale){vec.vx *= scale;vec.vy *= scale;},//add() method adds a vector.add : function(vec2){vec.vx += vec2.vx;vec.vy += vec2.vy;},//sub() method substracts a vector.sub : function(vec2){vec.vx -= vec2.vx;vec.vy -= vec2.vy;},//negate() method points the vector in the opposite direction. negate : function(){vec.vx = -vec.vx;vec.vy = -vec.vy;},//length() method returns the length of the vector using Pythagoras.length : function(){return Math.sqrt(vec.vx * vec.vx + vec.vy * vec.vy);},//A faster length calucalation that returns the length squared.//Useful if all you want to know is that one vector is longer than another.lengthSquard : function(){return vec.vx * vec.vx + vec.vy * vec.vy;},//normalize() method turns the vector into a unit length vector pointing in the same direction.normalize : function(){var len = Math.sqrt(vec.vx * vec.vx + vec.vy * vec.vy);if(len){vec.vx /= len;vec.vy /= len;}return len;//Maybe useful.},//Rotate the vector by an angle specified in radians.rotate : function(angle){var vx = vec.vx;varvy = vec.vy;varcosVal = Math.cos(angle);varsinVal = Math.sin(angle);vec.vx = vx * cosVal - vy * sinVal;vec.vy = vx * sinVal + vy * cosVal;},//I like it.toString : function(){return '(' + vec.vx.toFixed(3) + ',' + vec.vy.toFixed(3) + ')';}};return vec;};var cannonBall = function(x, y, vector){var gravity = 0;var that = {x : x,y : y,removeMe : false,move : function(){vector.vy += gravity;gravity += 0.1;that.x += vector.vx;that.y += vector.vy;if(that.y > canvas.height - 150){that.removeMe = true;}},draw : function(){ctx.beginPath();ctx.arc(that.x, that.y, 5, 0, Math.PI * 2, true);ctx.fill();ctx.closePath();}}; return that;};var cannon = function(x, y){var mx = 0, my = 0;var angle = 0;var that = {x : x,y : y,angle : 0,removeMe : false,move : function(){angle = Math.atan2(my - that.y, mx - that.x);},draw : function(){ctx.save();ctx.lineWidth = 2;ctx.translate(that.x, that.y);ctx.rotate(angle);ctx.strokeRect(0, -5, 50, 10);ctx.moveTo(0, 0);ctx.beginPath();ctx.arc(0, 0, 15, 0, Math.PI * 2, true);ctx.fill();ctx.closePath();ctx.restore();}};//原来可以直接给heml元素加事件监听canvas.onmousedown = function(event){var vec = vector2d(mx - that.x, my - that.y);vec.normalize();vec.scale(25);gameObjects.push(cannonBall(that.x, that.y, vec));};canvas.onmousemove = function(event){var bb = canvas.getBoundingClientRect();mx = (event.clientX - bb.left);my = (event.clientY - bb.top);};return that;};var drawSkyAndGrass = function(){ctx.save();ctx.globalAlpha = 0.4;var linGrad = ctx.createLinearGradient(0, 0, 0, canvas.height);linGrad.addColorStop(0, "#00BFFF");linGrad.addColorStop(0.5, 'white');linGrad.addColorStop(0.5, '#55dd00');linGrad.addColorStop(1, 'white');ctx.fillStyle = linGrad;ctx.fillRect(0, 0, canvas.width, canvas.height);ctx.restore();};gameObjects.push(cannon(50, canvas.height - 150));setInterval(function(){drawSkyAndGrass();var gameObjectsFresh = [];for(var i = 0; i < gameObjects.length; i++){gameObjects[i].move();gameObjects[i].draw();if(gameObjects[i].removeMe == false){gameObjectsFresh.push(gameObjects[i]);}}gameObjects = gameObjectsFresh;}, 30);}; </script></head><body><canvas id = "canvas" width = 640 height = 480 /></body></html>
0 0
- <<javascript 高效图形编程>>笔记
- JavaScript 高效编程方法笔记
- windows图形编程笔记
- Windows图形编程笔记
- MySQL高效编程--学习笔记
- MySQL高效编程--学习笔记
- 《TCP/IP高效编程》笔记
- MySQL高效编程--学习笔记
- 高效JavaScript学习(2)--- DOM编程
- [学习笔记]JavaScript基础--图形绘制
- 《TCP/IP高效编程》 ---------阅读笔记
- 《MySQL高效编程》学习笔记--基础篇
- Python学习笔记·交互式图形编程
- JavaScript编程笔记
- 【Javascript】模块化编程笔记
- javascript编程笔记
- 高效 JavaScript
- 高效 JavaScript
- 文字
- 利用GDI+实现BMP、JPEG、GIF图像格式的转换
- 【环境搭建003】UBUNTU + ECLIPS + ANDROID 嵌入式系统编译环境搭建遇到的稀奇古怪的问题集合
- 新兴XML处理方法VTD-XML介绍
- C语言运算符优先级和口诀
- <<javascript 高效图形编程>>笔记
- Python和Decorator(装饰器)模式
- 长方柱类【C++ 类定义】
- Objective-C语法之NSArray和NSMutableArray
- 我的面试经历
- 每个Web开发者必备的9个软技能
- 一步步学习微软InfoPath2010和SP2010--第十二章节--管理和监控InfoPath Form Services(IPFS)(1)--在SP管理中心的IPFS设置
- Java 8简明教程
- java 实现 不限长整形字符串 相加