商城网站很多时候会有类似刮刮乐的功能,网上看到的实现方式是通过两个canvas实现.总觉得比较low.于是自己封装了一个纯canvas底层实现刮刮乐模型当然功能没有封装的很全,比方说加个背景图/奖品为图片等等..当然这些功能都可以很简单的修改源码去实现了.下面提供一下制作思路在canvas绘制顺序应该是:绘制背景图片(这一步我没有做)->绘制蒙版->destination-out模式绘制擦除蒙版的线段->destination-over模式绘制奖品内容照例给个demo地址:刮刮乐demo效果:调用代码:/** * 刮刮卡 * @param {Object} opt * el: canvas id * text: 显示文字 * textColor: 文字颜色 默认 #000 * maskColor: 蒙版颜色 默认 #000 * lineWidth: 擦除线条宽度 默认 20 * fontStyle: 文字样式 默认 30px Georgia * callback: 用户第一次擦除回调(奖品在第一次擦除的时候获取.) * method * setValue: 奖品赋值 */ var mask = maskShape({ el: 'canvas', text: null, maskColor: "#ccc", textColor: '#000', lineWidth: 20, fontStyle: '30px Georgia', callback: function() { //第一次擦除回调函数. this指向对象本身 //return 如果奖品是第一次擦除时加载进来,在callback中写ajax取值 //如果超过200毫秒延迟体验会比较差,可以预先做一个生产队列 var self = this; setTimeout(function() { var arr = ['一等奖', '二等奖', '三等奖', '谢谢惠顾']; var z = Math.floor(Math.random() * arr.length); self.setText(arr[z]); }, 200); } }); //修改刮刮卡中值. //mask.setText('aaaa');
前端时间有在一个网站上看到css3的三维效果,感觉很棒,链接如下:NIPPON COLORS打开他的model开关,可以看到一个很炫的3D效果,下面是效果截图:是不是很棒...我也觉得很好,很心动,于是就动手模仿了.先看完成的效果吧.来看一下几个关键的部分:css3 3D效果,关键是下面几个属性,首先整个模型大概是: ...要展现3d部分的内容 ... 首先要有一个舞台:stage他有一个最重要的属性:perspective,可以理解成,观看的人,距离舞台,有多少远,比方说我这里设置了800px接着再来一个容器:container他也有一个重要的属性transform-style: preserve-3d; 告诉浏览器,这个容器是要显示3d效果的.再下面就要上具体的内容了.内容有一个重要的属性:transform他可以设置3个关键属性rotateX, rotateY, rotateZ用来判断当前物体的旋转角度如:transform: rotateX(180deg) rotateY(120deg) rotateZ(90deg) (X轴旋转180度,Y轴旋转120度,Z轴旋转90度) 然后现在就剩下最后一个关键属性了:translateZ如果不设置,那么物体就在舞台中间,也就是一开始我们给舞台设置的perspective值上,如800px数值越大,离我们就越近,当translateZ >= 800px的时候,物体就超过我们坐着的距离,就看不见他了.数值越小,离我们就越远.最终决定一个物体所在位置的4个值就是下面4个:transform: rotateX(180deg) rotateY(120deg) rotateZ(90deg) translateZ(100px)掌握上面这些,再通过css3的animation,transition两个动画神器我们就能做一点基本的小玩意啦^_^3d是不是没有想象中的那么复杂
受朋友之托,做一个小游戏--是男人就坚持20秒.一个很经典的exe小程序,想放到网页上做个小游戏互动.链接如下:是男人就撑过20秒大致看了一下,应该也没什么难度,撸起袖子直接干了.框架当然是用自己最熟悉的框架:createjs,adobe公司的开源canvas框架还是不错的.花了3 4天时间,基本功能都完成了,给个demo链接,大家可以去玩一下.是男人就坚持20秒demo游戏链接顺便再给几张游戏截图:中间碰到两个小算法.第1个是碰撞检测这个自己写太复杂了,我用了createjs的第三方开源检测库ndgmr.Collision.sprite.js这里提一下我在用的时候发现他会报错(官方自己的demo),虽然不影响使用,但是看到控制栏有红字就是不舒服...这里提一下报错的主要原因是calculateIntersection里面比较两个rect,得到的宽度或者高度为0,导致后面的canvas画布为0导致的.第2个是子弹飞行角度这个就比较简单了,就是已知两点,求两点的角度.本以为这个网上解决方案会有很多,结果找了一圈不知道是自己运气差还是怎么,竟然没找到!想了想正好练练手,再重温一下三角函数...下面是自己写的计算角度,可能有更好的算法自己没想到^_^ function getAngle(px, py, mx, my) { var x = Math.abs(px - mx); var y = Math.abs(py - my); var z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); if(z == 0) return 0; var cos = y / z; var radina = Math.acos(cos); //用反三角函数求弧度 var angle = 180 * radina / Math.PI; //将弧度转换成角度 //因为算出来的值是[0,90),需要转成[0,360) if(mx >= px) { if(my >= py) { angle = 90 - angle; } else { angle = 270 + angle; } } else { if(my >= py) { angle = 90 + angle; } else { angle = 270 - angle; } } return angle; } 这里的缺陷就是先算出了角度是[0,90),然后再转成了[0,360),个人感觉应该是有办法直接算成[0,360)的...如果有人知道,请千万告诉我一声....好了,睡觉去了...Zzz
看到野狗提供的实时通信引擎,心血来潮做了一个五子棋在线对战游戏.第一次做实时在线游戏,好多细节没有处理好...不过总算是做完了,虽然还有好多bug懒得去处理...样式什么的也不不想去处理了...~~(>_<)~~demo链接:在线五子棋对战ps:在浏览器里打开两个上面的网址,就可以自己邀战自己开始玩了.给个游戏截图:
平时没事上网的时候,看到围棋死活题的时候,总会算算怎么杀棋或者怎么活棋.可惜自己棋力不佳,总要摆一下才知道.可是网上却没有一个方便摆棋的地方想自己做一个又嫌太麻烦了懒的做= =,偶然间发现有一个jgoboard的围棋框架,那感觉真是太开心了......花了几天时间在这框架下开发了一个围棋小页面,杀棋,禁放点,悔棋都实现了,不过围棋的胜负做起来比较麻烦,没有做(主要是我自己只是用来摆死活题,不可能真的一个人在上面下棋对战是吧.没必要)这里放上个人制作的围棋打谱网页链接:围棋打谱放上页面图片:放上jgoboard框架链接https://github.com/jokkebk/jgoboard
由于在网上找的相关图片瀑布流的代码,封装性都不太高,并且都不支持自适应的效果(js在初始化的时候就确定了宽度,不支持放大缩小改变宽度)于是想着自己封装一个图片瀑布流的代码.暂时的做法是宽度都统一,高度自适应.等以后有时间的话,再想一下宽度是多列的思路.源码链接:图片瀑布流基本的思路是每个图片以绝对定位的方式一个一个的放到页面上.有一个数组记录每列的当前高度.做完之后看一下效果不错,主页面监听页面是否滚动到了底部去加载新的图片.但是偶尔却会出现.图片重叠的现象,非常奇怪.一开始认为是程序可能没有读取到图片的高度.写代码监听一下图片高度 var imageHeight = dom.find('img').height(); if (imageHeight < 50) debugger; 却发现从来都没跳到断点中来.判断应该不是没有读取到图片的高度.后来偶然间发现一个问题:虽然封装的对象中的方法:addImageList是一个一个加载图片的,不存在没有记录图片的高度,然后在对象外部页面是监听滚动条的方式去加载图片的,也就是说同一时间可能会调用多次加载图片的方法.这个情况下就会出现一张图片已经确定好位置,但是需要在图片加载结束后读取高度,记录这个图片占用的空间之前,另外一个图片也加载在同一个位置的情况.找到出问题的原因,剩下的就很好办了.外部不再直接调用addImageList方法.而是以堆栈的方式,将需要放置的图片放在一个对列中.//添加图片到对列中.(推入对列中统一处理) p.pushImages = function (opt_arr, callback) { var self = this; if (!(opt_arr instanceof Array)) { opt_arr = [opt_arr]; } for (var i = 0; i < opt_arr.length; i++) { var obj = { data: opt_arr[i], callback: callback }; self.plusImageList.push(obj); } }; 然后在创建对象的时候,启动方法_detailImage检测是否有需要处理的图片,这样就不会在同一时间多次调用增加图片的方法,外部只是往对象内部添加数组,真正的添加图片在对象内部处理.//处理对列中的图片 p._detailImage = function () { var self = this; if (self.plusImageList.length == 0) { //如果对列中没有图片,延迟100毫秒再来读取对列. window.setTimeout(function () { self._detailImage(); }, 100); } else { var temp = self.plusImageList.splice(0, 1)[0]; //取出一个图片对象. self.addImage(temp.data, function () { if (typeof temp.callback === 'function') temp.callback(); //继续对下一个对列中的图片进行处理.(如果让图片一张一张出来的效果可以这里加一个延迟) window.setTimeout(function () { self._detailImage(); }, 100); // self._detailImage(); }); } }; 这里记录一下走过的坑,以免下次再踩进去了,最终我想要做一个自定义表情包的页面,代码整理好后,再放上链接
基于学习使用createjs,博主准备在业余时间,做一个小游戏,因为在网上下载到了腾讯的全民飞机大战的素材包,决定用他的素材,做一个简化版的全民飞机大战游戏. 制作源码访问路径:全民飞机大战 还在制作当中,将持续更新,直到完成.首先做游戏第一步是加载图片素材以及音频素材,避免后面加载异步处理的麻烦. createjs中的LoadQueue对象是用来专门的类用来加载各种文件. 另外背景是多张相同的图片铺满整个canvas,当下降到一个背景的高度后又回到起来来实现的. 暂时就做了开始游戏的动画,后面的功能等做完了再来补充更新.这段时间公司项目比较忙,好不容易抽了点时间,把英雄子弹完成了. 首先子弹初始化时,应该有一个发射角度和样式.最后当子弹超出屏幕时,通过回收检查移除掉. (具体代码参考源码路径下的js/Bullet.js文件) 与飞机碰撞等功能在最后补上