从app页面选择手机中的图片一般都比较大,动则N个M,然后页面就挂在那里玩了,接下来就是讨论解决方案,之道的img压缩方案就是使用canvas压缩图片,那现在问题变为canvas压缩图片后如何上传的问题了
1、从input file中读出图片的方法

View Code JAVASCRIPT
1
2
3
4
5
6
7
var loadImageFromFile = function(file, callback) {
    var reader = new FileReader();
    reader.onload = function (e) {
        callback(e.target.result);
    };
    reader.readAsDataURL(file);
};

参考链接:https://hacks.mozilla.org/2011/01/how-to-develop-a-html5-image-uploader/

2、使用canvas压缩图片同上链接已给出

3、canvas转为blob格式

View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var dataURItoBlob = function(dataURI){
    var byteString;
    if (dataURI.split(',')[0].indexOf('base64') >= 0)
        byteString = atob(dataURI.split(',')[1]);
    else
        byteString = unescape(dataURI.split(',')[1]);
    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
 
    // write the bytes of the string to a typed array
    var ia = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ia], {type:mimeString});
};

参考链接:http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata

4、异步上传,新建一个formdata对象,添加blob到formdata中

View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var formdata = new FormData();
formdata.append('imgfile', blob);
 
var url = "upload.php";
$.ajax({
    type:'POST',
    url:url,
    data:formdata,
    contentType:false,
    processData:false,
    success : function(jdata){
        console.log(jdata);
    }
});

综上所述给一个Helper

View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
var ScaleImageHelper = {
    //从FILE中加载img
    loadImageFromFile : function(file, callback) {
        var reader = new FileReader();
        reader.onload = function (e) {
            callback(e.target.result);
        };
        reader.readAsDataURL(file);
    },
 
    dataURItoBlob : function(dataURI){
        var byteString;
        if (dataURI.split(',')[0].indexOf('base64') >= 0)
            byteString = atob(dataURI.split(',')[1]);
        else
            byteString = unescape(dataURI.split(',')[1]);
 
        // separate out the mime component
        var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
 
        // write the bytes of the string to a typed array
        var ia = new Uint8Array(byteString.length);
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
 
        return new Blob([ia], {type:mimeString});
    },
 
    resizeImgToCanvas : function(img, maxHeight, maxWidth){
        maxHeight = maxWidth||640;
        maxWidth = maxWidth||640;
        var width = img.width;
        var height = img.height;
 
        if(width > height){
            if (width > MAX_WIDTH) {
                height *= MAX_WIDTH / width;
                width = MAX_WIDTH;
            }
        }else{
            if (height > maxHeight) {
                width *= maxHeight / height;
                height = maxHeight;
            }
        }
 
        var canvas = document.createElement('canvas')
        canvas.width = width;
        canvas.height = height;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0, width, height);
        return canvas;
    },
 
    canvasToBlob : function(canvas){
        var dataURL = canvas.toDataURL('image/jpeg', 0.5);
        return this.dataURItoBlob(dataURL);
    },
 
    post : function(url, formdata, callback){
        $.ajax({
            type:'POST',
            url:url,
            data:formdata,
            contentType:false,
            processData:false,
            success : function(jdata){
                console.log(jdata);
            }
        });
    }
};

测试案例如下:

1
<input type="file" id="J-file" accept="image/*">
View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//监听文件变化
$('#J-file').on('change', function(){
    if(this.files.length<1){
        return ;
    }
    var file = this.files[0];
    //从文件中加载图片
    ScaleImageHelper.loadImageFromFile(file, function(src){
        var img = document.createElement('img');
        //插入图片到body中
        //$(document.body).append(img);
        //图片加载完成
        img.onload = function(){
            //通过canvas缩放图片
            var canvas = ScaleImageHelper.resizeImgToCanvas(this, 10, 10);
            //把canvas转成blob格式
            var blob = ScaleImageHelper.canvasToBlob(canvas);
 
            //插入到form中异步上传
            var formdata = new FormData();
            formdata.append('imgfile', blob);
            ScaleImageHelper.post('./scale-canvas.php', formdata);
        };
        img.src = src;
    });
});

最近一个小应用需要做播放器,当然首选jplayer,由于是手机应用,还是用zepto代替了jquery,昨晚折腾了很晚,也没找到为何出错了,比较晚耐心也不好,最终放到了今天。

官方文档,硬是把使用zepto代替jquery的说明拆成了几段,一不小心就跳过了重点

View Code JAVASCRIPT
1
2
3
//如果使用了AMD module需要修改下面的代码
//替换define(['jquery'], factory); 为
define(['zepto'], factory);

那么zepto源码中是没有amd加载支持,这个时候我们需要补充一下

View Code JAVASCRIPT
1
define("zepto", [], function(){return Zepto;});

但发现其实还是使用不了,设置如下可以使jplayer打印出错误日志

View Code JAVASCRIPT
1
2
3
my_jPlayer.jPlayer({
    errorAlerts: true //显示错误信息
})

发现错误日志如下:

jPlayer 2.9.2 : id=’jquery_jplayer’ : Error!
Attempt to issue media playback commands, while no media url is set.
Use setMedia() to set the media URL.
Context: play

那么就是setMedia没有调用到,跟一下源码,在第57行代码var instance = $(this).data(name);得到的结果是”[object Object]”,一看zepto不支持data为object,然后我再看官方文档,重点来了

Zepto
Compatibility verified with:
Zepto 1.0 compiled with Data module

整个人都很难受,为何不仔细看文档,为何不仔细看文档

22 / 07 / 2015 buling

这几天一直在做XX活动,明天发,主要负责手Q平台,微信平台被人抢了,所以。有如下些点分享
1、页面字体大小,

1
2
3
html {font-size:62.5%}
/*未经调整的浏览器都符合: 1em=16px,所以10px=0.625em,设置html为62.5%,那1rem就是10px*/
/*之后页面布局均使用rem来布局,方便统一调整*/

2、音乐播放操作

1
2
<!--music dom; preload属性自行查阅-->
<audio id="audio" src="./static/WeAreYoung.mp3" loop preload="auto" autoplay="true"></audio>
View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
(function(){
    //audio dom
    var videoMusic = $('#audio')[0];
 
    //监听回调
    var videoLoaded = function(){
        //控制按钮
        var $controll = $('#J_music-controller');
        //设置音量
        videoMusic.volume = 0.5;
        //开始播放
        videoMusic.play();
 
        $controll.show().on('tap', function(){
            var $this = $(this);
            if($this.hasClass('music-close')){
                $this.removeClass('music-close');
                videoMusic.play();
            }else{
                $this.addClass('music-close');
                videoMusic.pause();
            }
        });
    };
 
    //监听是否加载完成可以播放
    videoMusic.addEventListener('canplay', videoLoaded);
    if(videoMusic.readyState==4){
        videoLoaded();
    }
}());

3、陀螺仪模拟摇一摇

View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
var AcceHelper = (function(){
    var lastAcceTime = 0, 
        lastAcceInfo = false,
        firstAcceInfo = false,
        lastDistance = 5000,
        isStart = false,
        stopTimer = 0,
        config = {
            timeLimit : 100, //两次感应间隔时间为200
            speedLimit : 80, //速度限制为80
            stopLimit : 400
        };
 
    var getDistance = function(a, l){
        var powDis = Math.pow(a.x-l.x, 2) + Math.pow(a.y-l.y, 2);
        return Math.sqrt(powDis);
    };
 
    var doAccelerationIncludingGravity = function(acceleration, oncallback, stopcallback){
        var curTime = (new Date()).getTime(),
            a = acceleration,
            l = lastAcceInfo,
            time = curTime-lastAcceTime;
 
        if(time>config.timeLimit && lastAcceInfo){
            //debugFunc('on acceleration call['+(a.x+'_'+a.y+'_'+a.z)+']');
 
            lastAcceTime = curTime;
 
            var distance = getDistance(a, l),
                speed = distance/time*1000;
 
            if(speed>config.speedLimit){
                isStart = true;
                if(stopTimer){ //清除结束
                    clearTimeout(stopTimer);
                }
 
                if(!firstAcceInfo){ //设置第一次
                    firstAcceInfo = {
                        x : a.x,
                        y : a.y,
                        z : a.z
                    };
                }
 
                var aDistance = getDistance(a, firstAcceInfo);
                debugFunc('on acceleration call['+(aDistance+'_'+lastDistance+'_'+distance)+']');
                if(aDistance<lastDistance){ //回退的时候回调
                    oncallback && oncallback.call(null, {
                        distance : distance,
                        time : time,
                        speed : speed
                    }, a);
                }
                lastDistance = aDistance;
 
            }else if(isStart){
                if(stopTimer){ //清除结束
                    clearTimeout(stopTimer);
                }
 
                isStart = false;
                stopTimer = setTimeout(function(){
                    firstAcceInfo = false;
                    lastAcceInfo = false;
                    lastDistance = 5000;
 
                    debugFunc('on acceleration stop!'); //回调
                    stopcallback && stopcallback.call(null, {
                        distance : distance,
                        time : time,
                        speed : speed
                    }, a);
                }, config.stopLimit);
            }
        }
 
        lastAcceInfo = {
            x : a.x,
            y : a.y,
            z : a.z
        };
    };
 
    var beginAccelerometer = function(oncallback, endcallback){
        if(false && mqq.support("mqq.sensor.startAccelerometer")){
            mqq.sensor.startAccelerometer(function(ret, x, y, z){
                doAccelerationIncludingGravity({
                    x:x, y:y, z:z
                }, oncallback, endcallback);
            });
            Helper.showAlert('启用Q的陀螺仪');
            return ;
        }
 
        //浏览器内调用自测用
        if(window.addEventListener){
            $(window).off('devicemotion').on('devicemotion',function(eventData){
                doAccelerationIncludingGravity(eventData.accelerationIncludingGravity, oncallback, endcallback);
                eventData.preventDefault();
            });
        }else{
            Helper.showAlert('不支持摇一摇功能');
        }
    };
 
    var endAccelerometer = function(oncall, endcall){
        var timer = 0,
            num = 0;
        beginAccelerometer(function(info, acceleration){
            num += 1;
            oncall && oncall.call(null, num, info, acceleration);
        }, function(info, acceleration){
            //$('#J_page-box-1').prepend('<div>[[[[['+num+'</div>');
            endcall && endcall.call(null, num, info, acceleration);
            num = 0;
        });
    };
 
    var removeAccelerometer = function(){
        $(window).off('devicemotion');
    };
 
    return {
        on  : endAccelerometer,
        remove : removeAccelerometer,
 
        init : function(options){
            $.extend(config, options);
        }
    };
}());
 
//使用方法
AcceHelper.on(function(num, info, acceleration){
    //晃动第几次
    debugFunc('on acceleration num:' + num);
 
}, function(num){ //结束
    //结束时回调总共摇动了几次
    debugFunc('on acceleration end num:' + num);
});

3、分享一些动画

无标签信息 0 条
06 / 06 / 2015 buling

1、单行超出省略号方法
限定高宽, 设置css:overflow: hidden; text-overflow:ellipsis; white-space:nowrap;

2、多行超出省略号方法
css:overflow: hidden; display: -webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;

3、rgba的向下兼容方法
css:background:#ccc; background:rgba(0, 0, 0, 0.8);

=========================JS============================
1、获取窗口大小

View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
function getWindowHeightAndWidth(){
    var obj = window,
        sname = 'inner';
    if(!('innerWidth' in window)){
        sname = 'client';
        obj = document.documentElement || document.body;
    }
    return {
        width : obj[sname+'Width'],
        height : obj[sname+'Height']
    };
}

2、array-like object 在jquery中的使用方法。如果需要让一个object在console.log时看起来像一个数组

View Code JAVASCRIPT
1
2
3
//The object has to have length and splice
var x = {length:2, '0':'foo', '1':'bar', splice:function(){}};
jQuery.fn.init.prototype.splice = [].splice;

3、摇一摇时禁止Iphone在页面提示“撤销键入”

View Code JAVASCRIPT
1
2
3
4
$(window).off('devicemotion').on('devicemotion',function(eventData){
    //dosomething(eventData.accelerationIncludingGravity);
    eventData.preventDefault(); //就是这句了
});

4、禁止页面被拖动
//去掉IOS滚动到顶部回弹一下的效果

1
<meta name="apple-mobile-web-app-capable" content="yes" />
View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
//这里是列表可以滚动
$('#J_userchat-list').on('touchmove', function(event){
    event.stopPropagation();
});
//全局阻止移动,防止页面被拽
$(document).on('touchmove', function(event){
    //$('#J_page-box-1').prepend('<div>move body</div>');
    event.preventDefault();
});
无标签信息 0 条

最近做了一个软管活动页面由于页面比较大,需要切小背景图,由于时间紧也就没有做太多思考,独立了一个div来做背景,其余做内容,上线后遇到两个问题

1、在缩小页面时,内容浮动和背景不一致
由于内容限制了1000px的宽度,而背景没有限制宽度,所以导致背景被overflow hidden掉了,而内容出现滚动条,解决很简单,背景也限制最小宽度即可,当然ie6那货不支持,我就直接放弃了

2、在iphone/ipad 的safari上访问时由于动画会改变页面的宽度,出现页面变形,头大,怎么会呢,下个pc版safari也没有问题,然后就开始google,stackoverflow:Does overflow:hidden applied to work on iPhone Safari?,好吧,解决了

1
2
3
4
5
/*create a wrapper on the whole website to achieve that; and add css*/
.wrapper{
    position:relative; //that's it
    overflow:hidden;
}

昨晚睡前看了一篇文章:有哪些经常被误用的 HTML、JavaScript、CSS 的元素、方法和属性?,文中提到清除浮动,以前经常用clearfix,但从来没有注意过原理,不过我也习惯用overflow来清除浮动,代码如下

1
2
.clearfix{*zoom:1;}
.clearfix:after{content:"\200B"; display:block; clear:both; height:0;}

用zoom来兼容IE6/IE7下不支持伪类after触发haslayout; after用于向float元素末端添加一个\200B的空元素,设置为block,clear both清除浮动,顺便设置height为0避免对布局造成影响。其实和在元素末尾添加
等同的效果

04 / 01 / 2015 buling

      之前看过很多去jquery开发的文章,前几天又看到,可惜没有了文章地址,大抵是说jQuery封装的实在太好以至于让我们变的越来越懒越来越愚钝。一直打算去jquery开发,但后来很多次都是迫于开发效率,还是使用了jquery来开发,最近又打算尝试去jquery化,刚开始使用工具库的方式提供大堆的工具函数,尤其是在对dom操作时,函数总是需要传入dom,显得很繁冗,最后就尝试向jquery靠拢,但后来写着写着就发现,其实去jquery的意义在于再建一个mini-jquery库而已,越开发越觉得没有意义,唯一的意义在于对底层的js更熟悉,兼容方法总结。下面来给之前还未写完的一些测试案例:

View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//test select
var itembox = $('div ul,.item-box', document.body)[0],
    lis = $('.item', itembox);
debug('selector > get dom length:'+lis.length, 'info');
 
//test json
var jsonobj = {name : 'hehe', age:12},
    jsonstr = $.stringify(jsonobj),
    njsonobj = $.parseJSON(jsonstr);
debug('json > parse get name:'+njsonobj.name, 'info');
 
//test each
$.each(lis, function(dom, i){
    debug('each > '+i+':'+dom.tagName, 'info');
});
 
//test extend
var nobj = $.extend(jsonobj, {desc: 'hello!'});
debug('extend > parse new object:'+$.stringify(nobj), 'info');
 
//test css
debug('css > get item-box height:'+$(itembox).css('height')+'; after 2 seconds change backgrund', 'info');
setTimeout(function(){
    $(lis).css({
        'background' : '#ff0',
        'color' : '#f00'
    });
 
    debug('css > get item-box color:'+$(lis).css('color')+';', 'info');
 
    $(itembox).fadeOut(function(){
        $(itembox).fadeIn(function(){
            //add class
 
            $(lis[0]).removeClass('item').addClass('bold');
        });
    });
}, 2000);
 
 
 
//test ajax
$.ajax({
    url : './ajax-api.php',
    timeout : 3500,
    method : 'post',
    data : {name:'hello', age:12},
    success : function(content, xhr){
        debug('json > get resonse header:'+xhr.getAllResponseHeaders());
        debug('json > get callback:'+content);
        var jobj = $.parseJSON(content);
        debug('json > get code:'+jobj.code);
    },
    error : function(info, xhr){
        debug('json > error callback:'+$.stringify(info), 'error');
    }
});
 
//test animat
//animate(callback, executeTime, intervalTime)
$.animate(function(percent, curtime){
    debug(percent);
}, 400, 200);

具体js代码如下,访问地址:http://mjix.com/code/varcom/
; 源码地址: http://mjix.com/code/varcom/uquery.src.js

昨晚睡觉前又看了一下:Javascript之旅系列 以及 《JavaScript高级程序设计》读书笔记,我也在看这本书,只是书中写的实在太细,没有能像这位整理的这么好,之后需要再把类继承章节重新阅读一次才行。

07 / 11 / 2014 buling

      港行iphone6预定有很多规则限制:1、每个apple id限抢一次;2、每个手机号码限抢一次;每个身份证限抢一次。第一次预定成功,结果通行证过期,只能放弃,之后又买了一张卡,连续早起N次都没有结果,昨天又买了一张卡,今天早上再次失败,痛定思痛,从脚本开始,跟黄牛比手工不靠谱。目前港行价格16G基本还是5000RMB左右,所以脚本来了

View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var storeNum = 'R428',            //ifc店
    modelNum = 'MG4H2ZP/A',  //银色64G
    govType  = 'entryExitPass',  //通行证
    govID    = 'C050XXXXX';      //证ID
 
//这里用于去除可用性检测
if(!window._fetchPostData){
    _fetchPostData = fetchPostData
    fetchPostData = function(eventId, params, callback){
       if(eventId=='availability'){
           return false;
       }
       _fetchPostData(eventId, params, callback);
    }
}
//选择店面
$('#productSelection [name=selectedStoreNumber]').val(storeNum ).change();
//选择iphone6
$('#product .box').eq(0).click();
$('#locked .box').eq(0).click();
//选择颜色,第一个银色
$('#color input.iPhone6').eq(0).parent().click();
//选择64G
$('#model').removeClass('disabled');
$('#model .loading-spinner').addClass('hidden');
$('#model .group').attr('style', '').find('input[value="'+modelNum+'"]').parent().click().parent().show();
//填写联系资料
$('#quantity [name="selectedQuantity"]').val(2);
$('#contact [name="selectedGovtIdType"]').val(govType);
$('#contact [name="govtId"]').val(govID);
//选择时间
$('.button-container a, #time').removeClass('disabled');
$('#time select option').eq(2).prop('selected', true);
//提交
$('#productSelection')[0].submit();

      如果预定成功,我再来更新成自动化脚本,如果没成功就算了,来,嘿、嘿、嘿,加油!

      有时候在ipad或者android等移动设备上需要查看网页源代码,但移动设备本身是不支持查看,只能通过代码方式,之前一直用国外一款工具(忘了名字),但感觉有点慢,所以就根据geshi提供的api,自己搭建了一个,访问地址:http://www.mjix.com/code/viewsource/

      有时候看一些电影下载网站,页面看不到下载链接,只能通过查看源代码的方式获取链接地址,在ipad上很是不方便,通过这个工具查看源代码就方便很多。

怎么安装呢?
方法一:通过电脑收藏夹同步到IPAD等设备。拖动下面的链接到你的收藏夹中:
View Source
方法二:直接添加到收藏夹
1、添加当前页面到你的收藏夹中
2、点击  这个文件查看收藏夹代码  并且复制代码
3、修改刚刚添加到收藏夹中的“查看源代码”,粘贴代码到URL中,保存。

提供api为:http://www.mjix.com/code/viewsource/?uri=$url

      之前一直想做一个文字粒子效果的淡出淡进,这两天事情不多就写了一下代码,效果地址:http://www.mjix.com/code/canvas-text/,按F11进入全屏,做屏保还可以,预览图

======================已更新==========================
      由于之前版本,像素点是通过fillRect来实现,性能有严重问题,会卡顿,cpu直接能飙到25左右,新版通过生成imagedata,再putImageData来达到更新效果。

      主要是在粒子(文字像素点)的位移问题上的处理方法。淡进前需要先获取到像素点的初始位置极其透明度,这个东东运用到数学左边换算问题,要遇到数学有点头大就跳过吧

View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
     //获取渐进前的像素点位置
    getInData : function(data, min, offset){
        var xs = [],
            ys = [];
        this.each(data, function(info, index){
            xs.push(info[0]);
            ys.push(info[1]);
        });
 
        var max = Math.max.apply(xs, xs),
            mix = Math.min.apply(xs, xs),
            may = Math.max.apply(ys, ys),
            miy = Math.min.apply(ys, ys),
            //找出近似中间点
            midx = (max+mix) / 2, 
            midy = (may+miy) / 2;
 
        var self = this,
            dis  = 0,
            len = 0,
            prop = 0,
            newData = [];
        this.each(data, function(info, index){
            alp = -self.random(0.1, 1);
            len = min+self.random(offset);
            dis = Math.sqrt(self.getDistance(info, [midx, midy]));
 
            prop = len/(dis+len);
            newData.push([]);
            var xy = Math.ceil((info[0]-prop*midx)/(1-prop));
            newData[index][0] = xy; 
            xy = Math.ceil((info[1]-prop*midy)/(1-prop));
            newData[index][1] = xy; 
            newData[index][2] = info[2].concat();
            newData[index][2][3] = alp;
        });
        return newData;
    },

      然后是更新像素点位置,方法是,随机一个前进长度,根据当前点和目标点及移动不长确定下一个移动目标点的位置,如下

View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
    //获取指定长度点目标点位置
    getDestDot : function(data1, data2, length){
        if(data2[1]==data1[1] && data2[0]==data1[0]){
            return data2;
        }
 
        var xdis = Math.sqrt(this.getDistance(data1, data2)),
            prop = length/xdis;
 
        x = Math.ceil(prop*(data2[0]-data1[0])) + data1[0];
        y = Math.ceil(prop*(data2[1]-data1[1])) + data1[1];
        return [x, y];
    },

      直到所有的像素全部归位后,设置延迟,再淡出,淡出我就草草处理了,意思意思,效果自己看,源码就不说了。如所有的代码一样可能存在各种兼容性,BUG等等不可预料问题,留言反馈。

      之前1.0版本性能有严重问题,作为反例提供给大家:http://www.mjix.com/code/canvas-text/index1.0.html

      额,连续第三天中午写blog了,中午大家休息,抽空来更新一下,最近这几天自己学习了很多。一直以来很想学习游戏中地图的加载,物体碰撞的检测等等。前晚睡觉前看了一下园子,有人发了一篇重力小球的文章,就顺便研究了一下,原文地址:HTML5重力感应小球冲撞动画实现教程,当然我接下来要说的这个和原文的不是一个东东,是小球的碰撞检测。

      相对于很多不规则图形来讲,小球的碰撞检测要相对简单很多,稍微学过物理数学就很容易做速度分解,我参考了这篇文章: 碰撞检测算法优化 ,主要是说一下其中的几个点吧

      1、优化算法。文章说的格子优化算法,把屏幕中的小球分为大小相同的N个格子,碰撞检测只检测,每个格子中的小球是否碰撞,和相邻格子是否有碰撞过程,在检测过程中,应该计算:(i,j),(i-1,j-1),(i,j-1),(i-1,j),(i-1,j+1)这四个,而非对应(i,j)的上下左右四个格子,仔细想想就明白了

      2、动画帧使用requestAnimationFrame,如果没有使用settimeout 1000/60,60是指刷新频率,也可以参考:Javascript高性能动画与页面渲染

      3、在写Too类时,当把类的prototype用{}覆盖后,需要设置 Too.prototype.constructor = Too; 其实理论上不设置也不会有任何问题,也不会影响new时候的构造函数,参考文章: Javascript面向对象编程 以及文章 Why is it necessary to set the prototype constructor?

      废话少说,效果图来,测试地址:http://www.mjix.com/code/canvas-ball.html

无标签信息 0 条