深刻之new的模仿完成,离线网页应用

日期:2019-10-04编辑作者:美高梅老虎机平台

全体源码

<!DOCTYPE html> <html> <head> <title>Flappy Bird</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript"> // Edit by xingoo // Fork on my github: var ctx; var cwidth = 400; var cheight = 600; var objects = []; var birdIndex = 0; var ver1 = 10; var ver2; var gravity = 2; var pipe_height = 200; var velocity = 10; var tid; var score = 0; var isScore = false; var birds = ["./images/0.gif","./images/1.gif","./images/2.gif"]; var back = new Background(0,0,400,600,"./images/bg.png"); var up_pipe = new UpPipe(0,0,100,200,"./images/pipe.png"); var down_pipe = new DownPipe(0,400,100,200,"./images/pipe.png"); var ground = new Background(0,550,400,200,"./images/ground.png"); var bird = new Bird(80,300,40,40,birds); objects.push(back); objects.push(up_pipe); objects.push(down_pipe); objects.push(ground); objects.push(bird); function UpPipe(x,y,width,height,img_src){ this.px = x; this.py = y; this.pwidth = width; this.pheight = height; this.img_src = img_src; this.draw = drawUpPipe; } function DownPipe(x,y,width,height,img_src){ this.px = x; this.py = y; this.pwidth = width; this.pheight = height; this.img_src = img_src; this.draw = drawDownPipe; } function drawUpPipe(){ var image = new Image(); image.src = this.img_src; ctx.drawImage(image,150,500,150,800,this.px,this.py,this.pwidth,this.pheight); } function drawDownPipe(){ var image = new Image(); image.src = this.img_src; ctx.drawImage(image,0,500,150,500,this.px,this.py,this.pwidth,this.pheight); } function Background(x,y,width,height,img_src){ this.bgx = x; this.bgy = y; this.bgwidth = width; this.bgheight = height; var image = new Image(); image.src = img_src; this.img = image; this.draw = drawbg; } function drawbg(){ ctx.drawImage(this.img,this.bgx,this.bgy,this.bgwidth,this.bgheight); } function Bird(x,y,width,height,img_srcs){ this.bx = x; this.by = y; this.bwidth = width; this.bheight = height; this.imgs = img_srcs; this.draw = drawbird; } function drawbird(){ birdIndex++; var image = new Image(); image.src = this.imgs[birdIndex%3]; ctx.drawImage(image,this.bx,this.by,this.bwidth,this.bheight); } function calculator(){ if(bird.by+bird.bheight>ground.bgy || ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&( bird.by<up_pipe.py+up_pipe.pheight))|| ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&( bird.by<up_pipe.py+up_pipe.pheight))|| ((bird.bx>down_pipe.px)&&(bird.by>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by<down_pipe.py+down_pipe.pheight))|| ((bird.bx>down_pipe.px)&&(bird.by+bird.bheight>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by+bird.bheight<down_pipe.py+down_pipe.pheight))){ clearInterval(tid); ctx.fillStyle = "rgb(255,255,255)"; ctx.font = "30px Accent"; ctx.fillText("You got "+score+"!",110,100) return; } ver2 = ver1+gravity; bird.by += (ver2+ver1)*0.5; if(up_pipe.px+up_pipe.pwidth>0){ up_pipe.px -= velocity; down_pipe.px -= velocity; }else{ up_pipe.px = 400; down_pipe.px = 400; up_pipe.pheight = 100+Math.random()*200; down_pipe.py = up_pipe.pheight+pipe_height; down_pipe.pheight = 600-down_pipe.py; isScore = true; } if(isScore && bird.bx>up_pipe.px+up_pipe.pwidth){ score += 1; isScore = false; if(score>0 && score%10 === 0){ velocity++; } } ctx.fillStyle = "rgb(255,255,255)"; ctx.font = "30px Accent"; if(score>0){ score%10!==0?ctx.fillText(score,180,100):ctx.fillText("Great!"+score,120,100); } } function drawall(){ ctx.clearRect(0,0,cwidth,cheight); var i; for(i=0;i<objects.length;i++){ objects[i].draw(); } calculator(); } function keyup(e){ var e = e||event; var currKey = e.keyCode||e.which||e.charCode; switch (currKey){ case 32: bird.by -= 80; break; } } function init(){ ctx = document.getElementById('canvas').getContext('2d'); document.onkeyup = keyup; drawall(); tid = setInterval(drawall,80); } </script> </head> <body onLoad="init();"> <canvas id="canvas" width="400" height="600" style="margin-left:200px;"> Your browser is not support canvas! </canvas> </body> </html>

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
144
145
146
147
148
149
150
151
152
153
154
<!DOCTYPE html>
<html>
<head>
    <title>Flappy Bird</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript">
        // Edit by xingoo
        // Fork on my github:https://github.com/xinghalo/CodeJS/tree/master/HTML5
        var ctx;
        var cwidth = 400;
        var cheight = 600;
        var objects = [];
        var birdIndex = 0;
        var ver1 = 10;
        var ver2;
        var gravity = 2;
        var pipe_height = 200;
        var velocity = 10;
        var tid;
        var score = 0;
        var isScore = false;
        var birds = ["./images/0.gif","./images/1.gif","./images/2.gif"];
        var back = new Background(0,0,400,600,"./images/bg.png");
        var up_pipe = new UpPipe(0,0,100,200,"./images/pipe.png");
        var down_pipe = new DownPipe(0,400,100,200,"./images/pipe.png");
        var ground = new Background(0,550,400,200,"./images/ground.png");
        var bird = new Bird(80,300,40,40,birds);
        objects.push(back);
        objects.push(up_pipe);
        objects.push(down_pipe);
        objects.push(ground);
        objects.push(bird);
        function UpPipe(x,y,width,height,img_src){
            this.px = x;
            this.py = y;
            this.pwidth = width;
            this.pheight = height;
            this.img_src = img_src;
            this.draw = drawUpPipe;
        }
        function DownPipe(x,y,width,height,img_src){
            this.px = x;
            this.py = y;
            this.pwidth = width;
            this.pheight = height;
            this.img_src = img_src;
            this.draw = drawDownPipe;
        }
        function drawUpPipe(){
            var image = new Image();
            image.src = this.img_src;
            ctx.drawImage(image,150,500,150,800,this.px,this.py,this.pwidth,this.pheight);
        }
        function drawDownPipe(){
            var image = new Image();
            image.src = this.img_src;
            ctx.drawImage(image,0,500,150,500,this.px,this.py,this.pwidth,this.pheight);
        }
        function Background(x,y,width,height,img_src){
            this.bgx = x;
            this.bgy = y;
            this.bgwidth = width;
            this.bgheight = height;
            var image = new Image();
            image.src = img_src;
            this.img = image;
            this.draw = drawbg;
        }
        function drawbg(){
            ctx.drawImage(this.img,this.bgx,this.bgy,this.bgwidth,this.bgheight);
        }
        function Bird(x,y,width,height,img_srcs){
            this.bx = x;
            this.by = y;
            this.bwidth = width;
            this.bheight = height;
            this.imgs = img_srcs;
            this.draw = drawbird;
        }
        function drawbird(){
            birdIndex++;
            var image = new Image();
            image.src = this.imgs[birdIndex%3];
            ctx.drawImage(image,this.bx,this.by,this.bwidth,this.bheight);
        }
        function calculator(){
            if(bird.by+bird.bheight>ground.bgy ||
                ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(    bird.by<up_pipe.py+up_pipe.pheight))||
                ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(    bird.by<up_pipe.py+up_pipe.pheight))||
                ((bird.bx>down_pipe.px)&&(bird.by>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by<down_pipe.py+down_pipe.pheight))||
                ((bird.bx>down_pipe.px)&&(bird.by+bird.bheight>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by+bird.bheight<down_pipe.py+down_pipe.pheight))){
                clearInterval(tid);
                ctx.fillStyle = "rgb(255,255,255)";
                ctx.font = "30px Accent";
                ctx.fillText("You got "+score+"!",110,100)
                return;
            }
            ver2 = ver1+gravity;
            bird.by += (ver2+ver1)*0.5;
            if(up_pipe.px+up_pipe.pwidth>0){
                up_pipe.px -= velocity;
                down_pipe.px -= velocity;
            }else{
                up_pipe.px = 400;
                down_pipe.px = 400;
                up_pipe.pheight = 100+Math.random()*200;
                down_pipe.py = up_pipe.pheight+pipe_height;
                down_pipe.pheight = 600-down_pipe.py;
                isScore = true;
            }
            if(isScore && bird.bx>up_pipe.px+up_pipe.pwidth){
                score += 1;
                isScore = false;
                if(score>0 && score%10 === 0){
                    velocity++;
                }
            }
            ctx.fillStyle = "rgb(255,255,255)";
            ctx.font = "30px Accent";
            if(score>0){
                score%10!==0?ctx.fillText(score,180,100):ctx.fillText("Great!"+score,120,100);
            }
        }
        function drawall(){
            ctx.clearRect(0,0,cwidth,cheight);
            var i;
            for(i=0;i<objects.length;i++){
                objects[i].draw();
            }
            calculator();
        }
        function keyup(e){
            var e = e||event;
               var currKey = e.keyCode||e.which||e.charCode;
               switch (currKey){
                case 32:
                    bird.by -= 80;
                    break;
            }
        }    
        function init(){
            ctx = document.getElementById('canvas').getContext('2d');
            document.onkeyup = keyup;
            drawall();
            tid = setInterval(drawall,80);
        }
    </script>
</head>
<body onLoad="init();">
<canvas id="canvas" width="400" height="600" style="margin-left:200px;">
    Your browser is not support canvas!
</canvas>
</body>
</html>

3. 使用Service Worker

ServiceWorker的施用套路是先挂号多少个Worker,然后后台就能运营一条线程,可以在那条线程运维的时候去加载一些能源缓存起来,然后监听fetch事件,在那个事件里拦截页面包车型大巴伸手,先看下缓存里有未有,倘使有一直回到,不然不奇怪加载。恐怕是一起首不缓存,每一种财富恳求后再拷贝一份缓存起来,然后下三回呼吁的时候缓存里就有了。

new

一句话介绍 new:

new 运算符创设一个客户定义的目的类型的实例或富有构造函数的停放对象类型之一

唯恐有一点难懂,大家在模仿 new 在此之前,先看看 new 实现了哪些职能。

举个例子:

// Otaku 御宅族,简称宅 function Otaku (name, age) { this.name = name; this.age = age; this.habit = 'Games'; } // 因为贫乏操练的缘故,身体强度令人担心 Otaku.prototype.strength = 60; Otaku.prototype.sayYourName = function () { console.log('I am ' + this.name); } var person = new Otaku('凯文', '18'); console.log(person.name) // 凯文 console.log(person.habit) // Gamesconsole.log(person.strength) // 60 person.sayYourName(); // I am 凯文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Otaku 御宅族,简称宅
function Otaku (name, age) {
    this.name = name;
    this.age = age;
 
    this.habit = 'Games';
}
 
// 因为缺乏锻炼的缘故,身体强度让人担忧
Otaku.prototype.strength = 60;
 
Otaku.prototype.sayYourName = function () {
    console.log('I am ' + this.name);
}
 
var person = new Otaku('Kevin', '18');
 
console.log(person.name) // Kevin
console.log(person.habit) // Games
console.log(person.strength) // 60
 
person.sayYourName(); // I am Kevin

从这一个例子中,大家得以看见,实例 person 能够:

  1. 做客到 Otaku 构造函数里的性质
  2. 拜谒到 Otaku.prototype 中的属性

接下去,咱们能够品味着模拟一下了。

因为 new 是重大字,所以不可能像 bind 函数同样平昔覆盖,所以我们写一个函数,命名称为 objectFactory,来模拟 new 的功力。用的时候是那般的:

function Otaku () { …… } // 使用 new var person = new Otaku(……); // 使用 objectFactory var person = objectFactory(Otaku, ……)

1
2
3
4
5
6
7
8
function Otaku () {
    ……
}
 
// 使用 new
var person = new Otaku(……);
// 使用 objectFactory
var person = objectFactory(Otaku, ……)

初始化chroma-key

doLoad()方法在XHTML文书档案开首加载时调用。这一个主意的意义是为chroma-key管理代码企图所需的变量,设置八个风云侦听器,当客商开头广播录制时我们能检验到。

JavaScript

doLoad: function() { this.video = document.getElementById("video"); this.c1 = document.getElementById("c1"); this.ctx1 = this.c1.getContext("2d"); this.c2 = document.getElementById("c2"); this.ctx2 = this.c2.getContext("2d"); let self = this; this.video.addEventListener("play", function() { self.width = self.video.videoWidth / 2; self.height = self.video.videoHeight / 2; self.timerCallback(); }, false); },

1
2
3
4
5
6
7
8
9
10
11
12
13
doLoad: function() {
    this.video = document.getElementById("video");
    this.c1 = document.getElementById("c1");
    this.ctx1 = this.c1.getContext("2d");
    this.c2 = document.getElementById("c2");
    this.ctx2 = this.c2.getContext("2d");
    let self = this;
    this.video.addEventListener("play", function() {
        self.width = self.video.videoWidth / 2;
        self.height = self.video.videoHeight / 2;
        self.timerCallback();
      }, false);
  },

这段代码获取XHTML文书档案中video元素和三个canvas成分的援用,还获得了四个canvas的图形上下文的引用。这个就要咱们兑现chroma-keying特效时利用。

add伊芙ntListener()监听video元素,当顾客按下录制上的播放按键时被调用。为了酬答客商重放,这段代码获取录制的幅度和惊人,并且减半(大家就要执行chroma-keying效果时将录像的轻重缓急减半),然后调用timerCallback()方法来运营摄像捕捉和视觉效果总结。

静态财富发表的痛点

咱俩通晓,缓存对于前端质量的优化是不行注重的,在职业揭露系列的时候,对于那个不平时退换的静态财富比方种种JS工具库、CSS文件、背景图片等等大家会设置三个一点都比十分的大的缓存过期时间(max-age),当顾客再次拜候那个页面的时候就足以一直选拔缓存并不是双重从服务器获取,那样不光能够缓慢解决服务端的压力,还足以节省互联网传输的流量,同一时候客商体验也更加好(客商张开页面越来越快了)。那样看起来很全面,你好自个儿好大家都好,but,理想是美好的,现实是残忍的,要是存在这样一个浏览器,强制缓存静态财富还不给您清除缓存的时机(微信,说的正是你!),该如何做?尽管你的服务端已履新,文件的Etag值已转移,不过微信正是不给你更新文件…请允许自个儿做二个痛楚的神色…

对于那几个难点,大家很自然的想法是在历次公布新本子的时候给具备静态能源的乞求后边加上四个本子参数或时刻戳,类似于/js/indx.js?ver=1.0.1,但是这么存在八个难点:

  1. 微信对于加参数的静态能源依然事先选取缓存版本(实际测量试验的情状是这么的)。
  2. 设若那样是卓有成效的,那么对于从未改换的静态资源也会重新从服务器获取并非读取缓存,未有充裕利用缓存。

那么有没有一种格局可以活动辨识出哪位文件发出了变动并让顾客端主动立异呢?答案是必然的。我们驾驭一个文书的MD5能够独一标志三个文书。若文件发出了调换,文件的指纹值MD5也跟着变动。利用这些特点大家就能够标记出哪些静态资源产生了变动,并让客商端主动改进。

FlappyBird原理解析

实则这一个游戏很轻便,一张图就可以看懂当中的神秘:

美高梅老虎机平台 1

个中背景和本地是不动的。

鸟儿只有上和下七个动作,能够透过垄断小鸟的y坐标完结。

左右的管仲只会向左移动,为了轻松达成,游戏中贰个画面仅仅会并发部分管仲,那样当管敬仲移出右侧包车型地铁背景框,就机关把管敬仲放在最侧面!

if(up_pipe.px+up_pipe.pwidth>0){ up_pipe.px -= velocity; down_pipe.px -= velocity; }else{ up_pipe.px = 400; down_pipe.px = 400; up_pipe.pheight = 100+Math.random()*200; down_pipe.py = up_pipe.pheight+pipe_height; down_pipe.pheight = 600-down_pipe.py; isScore = true; }

1
2
3
4
5
6
7
8
9
10
11
if(up_pipe.px+up_pipe.pwidth>0){
                up_pipe.px -= velocity;
                down_pipe.px -= velocity;
            }else{
                up_pipe.px = 400;
                down_pipe.px = 400;
                up_pipe.pheight = 100+Math.random()*200;
                down_pipe.py = up_pipe.pheight+pipe_height;
                down_pipe.pheight = 600-down_pipe.py;
                isScore = true;
            }

很简单吗!

出于该游戏一共就那多少个因素,因而把她们都放入三个Objects数组中,通过setInteral()方法,在自然间隔时间内,执行三次重绘

重绘的时候会先去掉画面中的全体因素,然后遵照新的因素的坐标二遍绘制图形,那样就能够油可是生活动的作用。

(2)Service Worker安装和激活

登记完之后,ServiceWorker就交易会开设置,那个时候会触发install事件,在install事件之中能够缓存一些能源,如下sw-3.js:

JavaScript

const CACHE_NAME = "fed-cache"; this.addEventListener("install", function(event) { this.skipWaiting(); console.log("install service worker"); // 创造和开垦三个缓存库 caches.open(CACHE_NAME); // 首页 let cacheResources = ["]; event.waitUntil( // 央求财富并加多到缓存里面去 caches.open(CACHE_NAME).then(cache => { cache.addAll(cacheResources); }) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const CACHE_NAME = "fed-cache";
this.addEventListener("install", function(event) {
    this.skipWaiting();
    console.log("install service worker");
    // 创建和打开一个缓存库
    caches.open(CACHE_NAME);
    // 首页
    let cacheResources = ["https://fed.renren.com/?launcher=true"];
    event.waitUntil(
        // 请求资源并添加到缓存里面去
        caches.open(CACHE_NAME).then(cache => {
            cache.addAll(cacheResources);
        })
    );
});

经过地点的操作,创立和增多了贰个缓存库叫fed-cache,如下Chrome调整台所示:

美高梅老虎机平台 2

ServiceWorker的API基本上都以重返Promise对象幸免堵塞,所以要用Promise的写法。上面在设置ServiceWorker的时候就把首页的呼吁给缓存起来了。在ServiceWorker的周转条件之中它有一个caches的大局对象,这些是缓存的入口,还应该有一个常用的clients的大局对象,七个client对应三个标签页。

在ServiceWorker里面能够应用fetch等API,它和DOM是割裂的,未有windows/document对象,不只怕直接操作DOM,不可能直接和页面交互,在ServiceWorker里面不能得知当前页面张开了、当前页面包车型大巴url是如何,因为二个ServiceWorker管理当前张开的多少个标签页,能够透过clients知道全数页面包车型地铁url。还会有能够由此postMessage的艺术和主页面相互传递音讯和数目,进而做些调整。

install完事后,就能够触发Service Worker的active事件:

JavaScript

this.addEventListener("active", function(event) { console.log("service worker is active"); });

1
2
3
this.addEventListener("active", function(event) {
    console.log("service worker is active");
});

ServiceWorker激活之后就可见监听fetch事件了,大家期望每拿到多个财富就把它缓存起来,就无须像上一篇涉嫌的Manifest须要先生成三个列表。

你可能会问,当本人刷新页面包车型客车时候不是又再次登记安装和激活了叁个ServiceWorker?就算又调了二遍注册,但并不会另行挂号,它发现”sw-3.js”那么些已经登记了,就不会再登记了,从而不会触发install和active事件,因为这几天ServiceWorker已是active状态了。当须求更新ServiceWorker时,如产生”sw-4.js”,可能改换sw-3.js的公文内容,就能再也注册,新的ServiceWorker会先install然后步向waiting状态,等到重启浏览器时,老的ServiceWorker就能被轮换掉,新的ServiceWorker步向active状态,假设不想等到再也起动浏览器可以像上边同样在install里面调skipWaiting:

JavaScript

this.skipWaiting();

1
this.skipWaiting();

深切种类

JavaScript浓厚连串目录地址:。

JavaScript深切类别臆想写十五篇左右,意在帮我们捋顺JavaScript底层知识,入眼解说如原型、作用域、施行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等困难概念。

假设有错误或然非常的大心的地点,请必须给予指正,拾叁分谢谢。如若喜欢仍然有所启发,接待star,对小编也是一种鞭挞。

本系列:

  1. JavaScirpt 深远之从原型到原型链
  2. JavaScript 深远之词法功用域和动态成效域
  3. 深刻之new的模仿完成,离线网页应用。JavaScript 深入之实施上下文栈
  4. JavaScript 深入之变量对象
  5. JavaScript 深远之成效域链
  6. JavaScript 长远之从 ECMAScript 规范解读 this
  7. JavaScript 深远之实行上下文
  8. JavaScript 深刻之闭包
  9. JavaScript 深刻之参数按值传递
  10. JavaScript 长远之call和apply的效仿完成
  11. JavaScript 深远之bind的模仿达成

    1 赞 1 收藏 评论

美高梅老虎机平台 3

机械漏刻回调

反应计时器回调函数在摄像发轫广播时被调用(当“播放”事件产生时),然后担任自身周期调用,为每一帧录像达成keying特效。

JavaScript

timerCallback: function() { if (this.video.paused || this.video.ended) { return; } this.computeFrame(); let self = this; setTimeout(function () { self.timerCallback(); }, 0); },

1
2
3
4
5
6
7
8
9
10
timerCallback: function() {
    if (this.video.paused || this.video.ended) {
      return;
    }
    this.computeFrame();
    let self = this;
    setTimeout(function () {
        self.timerCallback();
      }, 0);
  },

回调函数首先检查摄疑似否正在播放;若无,回调函数不做别的交事务并当即重临。

然后调用computeFrame()方法,该方式对最近视频帧奉行chroma-keying特效。

回调函数做的最终一件事便是调用setTimeout(),来让它本身尽快地被重新调用。在真正情形中,你也许会依赖摄像的帧率来设置调用频率。

有关小编:Natumsol

美高梅老虎机平台 4

Alibaba 前端技术员 个人主页 · 作者的文章 · 美高梅老虎机平台 , 5 ·    

美高梅老虎机平台 5

canvas之drawImage()

本篇的嬉戏支付中,重要使用的是依照图片绘制的api:drawImage(),它有七个宗旨的施用情势:

ctx.drawImage(image,this.bx,this.by,this.bwidth,this.bheight); ctx.drawImage(image,x,y,width,height,this.px,this.py,this.pwidth,this.pheight);

1
2
ctx.drawImage(image,this.bx,this.by,this.bwidth,this.bheight);
ctx.drawImage(image,x,y,width,height,this.px,this.py,this.pwidth,this.pheight);

先是个api中,钦点Image对象,然后给出绘制图片的x,y坐标以及宽度和惊人就可以。

其次个api中,第一组x,y,width,height则内定了裁剪图片的坐标尺寸,那在选取多成分的矢量图时很常用。举例:

美高梅老虎机平台 6

下面的图形中为了削减图片财富的伸手数量,把广大的元素放在了二个图纸中,此时就需求经过裁剪的法子,获取钦点的图纸成分。

5. 选择Web App Manifest加多桌面入口

只顾这里说的是其余贰个Manifest,那几个Manifest是四个json文件,用来放网址icon名称等音讯以便在桌面增多贰个Logo,以及创造一种张开这么些网页似乎展开App同样的功用。上边一向说的Manifest是被舍弃的Application Cache的Manifest。

本条Maifest.json文件能够如此写:

JavaScript

{ "short_name": "人人FED", "name": "人人网FED,静心于前边四个技巧", "icons": [ { "src": "/html/app-manifest/logo_48.png", "type": "image/png", "sizes": "48x48" }, { "src": "/html/app-manifest/logo_96.png", "type": "image/png", "sizes": "96x96" }, { "src": "/html/app-manifest/logo_192.png", "type": "image/png", "sizes": "192x192" }, { "src": "/html/app-manifest/logo_512.png", "type": "image/png", "sizes": "512x512" } ], "start_url": "/?launcher=true", "display": "standalone", "background_color": "#287fc5", "theme_color": "#fff" }

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
{
  "short_name": "人人FED",
  "name": "人人网FED,专注于前端技术",
  "icons": [
    {
      "src": "/html/app-manifest/logo_48.png",
      "type": "image/png",
      "sizes": "48x48"
    },
    {
      "src": "/html/app-manifest/logo_96.png",
      "type": "image/png",
      "sizes": "96x96"
    },
    {
      "src": "/html/app-manifest/logo_192.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "/html/app-manifest/logo_512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "start_url": "/?launcher=true",
  "display": "standalone",
  "background_color": "#287fc5",
  "theme_color": "#fff"
}

icon要求计划四种规范,最大需求512px * 512px的,那样Chrome会自动去选择合适的图形。假若把display改成standalone,从扭转的Logo展开就能够像张开贰个App同样,没有浏览器地址栏那多少个东西了。start_url钦命张开之后的进口链接。

下一场加多一个link标签指向这些manifest文件:

JavaScript

<link rel="manifest" href="/html/app-manifest/manifest.json">

1
<link rel="manifest" href="/html/app-manifest/manifest.json">

那样组合Service Worker缓存:
美高梅老虎机平台 7把start_url指向的页面用ServiceWorker缓存起来,那样当客户用Chrome浏览器展开这几个网页的时候,Chrome就能在尾巴部分弹叁个提示,询问客商是还是不是把这么些网页增加到桌面,如若点“增加”就能够变卦叁个桌面Logo,从这一个Logo点进去就如张开三个App同样。感受如下:

美高梅老虎机平台 8

相比较为难的是Manifest近期独有Chrome协理,並且只可以在安卓系统上行使,IOS的浏览器不能增添一个桌面Logo,因为IOS未有开放这种API,可是笔者的Safari却又是能够的。

综上,本文介绍了怎么用Service Worker结合Manifest做叁个PWA离线Web 应用软件,主假如用ServiceWorker调整缓存,由于是写JS,相比较灵敏,还足以与页面进行通讯,另外通过须求页面包车型客车立异时间来判断是或不是要求革新html缓存。ServiceWorker的宽容性不是特意好,不过前景相比较光明,浏览器都在预备接济。现阶段得以构成offline cache的Manifest做离线应用。

连带阅读:

  1. 为何要把网址晋级到HTTPS
  2. 哪些把网址晋级到http/2
  3. 自身是怎么着让网址用上HTML5 Manifest

1 赞 1 收藏 评论

美高梅老虎机平台 9

始于完毕

分析:

因为 new 的结果是一个新对象,所以在模仿完成的时候,我们也要创造三个新指标,若是这几个目的叫 obj,因为 obj 会具有 Otaku 构造函数里的天性,想想杰出三番两次的例证,大家得以选拔 Otaku.apply(obj, arguments)来给 obj 增添新的性质。

在 JavaScript 深刻连串第一篇中,大家便讲了原型与原型链,我们知晓实例的 __proto__ 属性会指向构造函数的 prototype,也正是因为创建起这么的关系,实例能够访谈原型上的品质。

现行反革命,大家得以品味着写第一版了:

// 第一版代码 function objectFactory() { var obj = new Object(), Constructor = [].shift.call(arguments); obj.__proto__ = Constructor.prototype; Constructor.apply(obj, arguments); return obj; };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 第一版代码
function objectFactory() {
 
    var obj = new Object(),
 
    Constructor = [].shift.call(arguments);
 
    obj.__proto__ = Constructor.prototype;
 
    Constructor.apply(obj, arguments);
 
    return obj;
 
};

在这一版中,大家:

  1. 用new Object() 的章程新建了二个指标 obj
  2. 收取第二个参数,就是大家要传播的构造函数。其余因为 shift 会修改原数组,所以 arguments 会被删除第二个参数
  3. 将 obj 的原型指向构造函数,那样 obj 就足以访谈到构造函数原型中的属性
  4. 动用 apply,退换构造函数 this 的指向到新建的靶子,这样 obj 就能够访谈到构造函数中的属性
  5. 返回 obj

愈来愈多关于:

原型与原型链,能够看《JavaScript长远之从原型到原型链》

apply,可以看《JavaScript深刻之call和apply的效仿完毕》

精彩再而三,能够看《JavaScript深刻之继续》

复制以下的代码,到浏览器中,大家能够做一下测验:

function Otaku (name, age) { this.name = name; this.age = age; this.habit = 'Games'; } Otaku.prototype.strength = 60; Otaku.prototype.sayYourName = function () { console.log('I am ' + this.name); } function objectFactory() { var obj = new Object(), Constructor = [].shift.call(arguments); obj.__proto__ = Constructor.prototype; Constructor.apply(obj, arguments); return obj; }; var person = objectFactory(Otaku, 'Kevin', '18') console.log(person.name) // Kevin console.log(person.habit) // Games console.log(person.strength) // 60 person.sayYourName(); // I am Kevin

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
function Otaku (name, age) {
    this.name = name;
    this.age = age;
 
    this.habit = 'Games';
}
 
Otaku.prototype.strength = 60;
 
Otaku.prototype.sayYourName = function () {
    console.log('I am ' + this.name);
}
 
function objectFactory() {
    var obj = new Object(),
    Constructor = [].shift.call(arguments);
    obj.__proto__ = Constructor.prototype;
    Constructor.apply(obj, arguments);
    return obj;
};
 
var person = objectFactory(Otaku, 'Kevin', '18')
 
console.log(person.name) // Kevin
console.log(person.habit) // Games
console.log(person.strength) // 60
 
person.sayYourName(); // I am Kevin

[]~( ̄▽ ̄)~**

拍卖摄像帧数据

computeFrame()方法,如下所示,实际上负担抓取每一帧的数额和实践chroma-keying特效。

JavaScript

computeFrame: function() { this.ctx1.drawImage(this.video, 0, 0, this.width, this.height); let frame = this.ctx1.getImageData(0, 0, this.width, this.height); let l = frame.data.length / 4; for (let i = 0; i < l; i++) { let r = frame.data[i * 4 + 0]; let g = frame.data[i * 4 + 1]; let b = frame.data[i * 4 + 2]; if (g > 100 && r > 100 && b < 43) frame.data[i * 4 + 3] = 0; } this.ctx2.putImageData(frame, 0, 0); return; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
computeFrame: function() {
    this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
    let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
    let l = frame.data.length / 4;
 
    for (let i = 0; i < l; i++) {
      let r = frame.data[i * 4 + 0];
      let g = frame.data[i * 4 + 1];
      let b = frame.data[i * 4 + 2];
      if (g > 100 && r > 100 && b < 43)
        frame.data[i * 4 + 3] = 0;
    }
    this.ctx2.putImageData(frame, 0, 0);
    return;
  }

当它被调用后,video成分将体现近年来的录制帧数据,如下所示:

美高梅老虎机平台 10

在第2行,录像帧被复制到第一个canvas ctx1的图形上下文中,中度和宽窄值内定为大家在此之前封存的帧大小的四分之二。注意,您能够因此传递video成分到绘图上下文的drawImage()方法来绘制当前录制帧。其结果是:

美高梅老虎机平台 11

第3行代码通过调用第贰个canvas上下文的getImageData()方法,来赢得原始图像数据当前录制帧的一个别本。它提供了土生土养的三12人像素图像数据,那样大家就可以举行操作。第4行代码通过将帧图像数据的路途度除以4,来测算图像的总像素数。

第6行代码循环扫描全部像素,获取各种像素的红、绿、蓝值,同临时候和预订义的背景象进行相比较,那一个背景色将用foo.png中程导弹入的背景图像替换。

被检测成背景的每三个像素,将它的阿尔法值替换为零,申明该像素是全然透明的。结果,最后的图像背景有个别是百分百透明的,那样在第13行代码,把它被绘制到指标的前后文中时,效果是内容叠合到静态背景上。

因此发出的图像看起来像那样:

美高梅老虎机平台 12

在录像播放时往往那样做,那样一帧接一帧管理,呈现出chroma-key的特效。

请看这几个实例。

1 赞 1 收藏 评论

怎么样消除?

由在此以前文的介绍,大家驾驭了能够使用文件的指纹值来标记必要客商端主动创新的文本,可是什么贯彻呢?经过自个儿的思维和调研后,大约思路为:

  1. 在每一回揭橥在此之前,利用Gulp对具备的静态财富拓宽预管理,重命名称叫原文件名 + 文件MD5值 + 文件后缀名的形式。比如index.js重命名称叫index-c6c9492ce6.js
  2. 变迁一份manifest,标注了预管理前后文件之间的呼应关系.manifest文件的理当如此为:
JavaScript

{ "index.js": "index-c6c9492ce6.js", "lib/jQuery/jQuery.js":
"lib/jQuery/jQuery-683c73084c.js", "require.js":
"require-c8e8015f8d.js", "style.css": "style-125d3a3f82.css",
"tools.js": "tools-5666ee48e9.js" }

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f4b6669294327058473-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b6669294327058473-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f4b6669294327058473-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b6669294327058473-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f4b6669294327058473-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b6669294327058473-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f4b6669294327058473-7">
7
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f4b6669294327058473-1" class="crayon-line">
{
</div>
<div id="crayon-5b8f4b6669294327058473-2" class="crayon-line crayon-striped-line">
  &quot;index.js&quot;: &quot;index-c6c9492ce6.js&quot;,
</div>
<div id="crayon-5b8f4b6669294327058473-3" class="crayon-line">
  &quot;lib/jQuery/jQuery.js&quot;: &quot;lib/jQuery/jQuery-683c73084c.js&quot;,
</div>
<div id="crayon-5b8f4b6669294327058473-4" class="crayon-line crayon-striped-line">
  &quot;require.js&quot;: &quot;require-c8e8015f8d.js&quot;,
</div>
<div id="crayon-5b8f4b6669294327058473-5" class="crayon-line">
  &quot;style.css&quot;: &quot;style-125d3a3f82.css&quot;,
</div>
<div id="crayon-5b8f4b6669294327058473-6" class="crayon-line crayon-striped-line">
  &quot;tools.js&quot;: &quot;tools-5666ee48e9.js&quot;
</div>
<div id="crayon-5b8f4b6669294327058473-7" class="crayon-line">
}
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 在渲染视图模版的时候,依据manifest,将预管理前的静态资置换为预管理后的静态能源。
  2. 假使在浏览器端用到了模块加载器(这里以促成了AMD规范的requireJS为例),在历次宣布的时候须要基于manifest对模块实行mapping,将配置文件以内联JS的款型写入到模版页面里面,类似于:
JavaScript

&lt;script&gt; requirejs.config({ "baseUrl": "/js", "map": { "*": {
"index": "index-c6c9492ce6", "jquery":
"lib/jQuery/jQuery-683c73084c", "require": "require-c8e8015f8d",
"tools": "tools-5666ee48e9" } } }); &lt;/script&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b666929d715705975-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b666929d715705975-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b666929d715705975-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b666929d715705975-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b666929d715705975-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4b666929d715705975-12">
12
</div>
<div class="crayon-num" data-line="crayon-5b8f4b666929d715705975-13">
13
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f4b666929d715705975-1" class="crayon-line">
&lt;script&gt;
</div>
<div id="crayon-5b8f4b666929d715705975-2" class="crayon-line crayon-striped-line">
requirejs.config({
</div>
<div id="crayon-5b8f4b666929d715705975-3" class="crayon-line">
    &quot;baseUrl&quot;: &quot;/js&quot;,
</div>
<div id="crayon-5b8f4b666929d715705975-4" class="crayon-line crayon-striped-line">
    &quot;map&quot;: {
</div>
<div id="crayon-5b8f4b666929d715705975-5" class="crayon-line">
        &quot;*&quot;: {
</div>
<div id="crayon-5b8f4b666929d715705975-6" class="crayon-line crayon-striped-line">
            &quot;index&quot;: &quot;index-c6c9492ce6&quot;,
</div>
<div id="crayon-5b8f4b666929d715705975-7" class="crayon-line">
            &quot;jquery&quot;: &quot;lib/jQuery/jQuery-683c73084c&quot;,
</div>
<div id="crayon-5b8f4b666929d715705975-8" class="crayon-line crayon-striped-line">
            &quot;require&quot;: &quot;require-c8e8015f8d&quot;,
</div>
<div id="crayon-5b8f4b666929d715705975-9" class="crayon-line">
            &quot;tools&quot;: &quot;tools-5666ee48e9&quot;
</div>
<div id="crayon-5b8f4b666929d715705975-10" class="crayon-line crayon-striped-line">
        }
</div>
<div id="crayon-5b8f4b666929d715705975-11" class="crayon-line">
    }
</div>
<div id="crayon-5b8f4b666929d715705975-12" class="crayon-line crayon-striped-line">
});
</div>
<div id="crayon-5b8f4b666929d715705975-13" class="crayon-line">
&lt;/script&gt;
</div>
</div></td>
</tr>
</tbody>
</table>

本文由澳门美高梅老虎机平台发布于美高梅老虎机平台,转载请注明出处:深刻之new的模仿完成,离线网页应用

关键词:

图表的能力,跨域访谈和防盗链基本原理

跨域访谈和防盗链基本原理(二) 2015/10/18 · HTML5 ·跨域,防盗链 原著出处: 童燕群(@童燕群)    JavaScript 深远之...

详细>>

由一道题通透到底弄懂,轻巧监听其余App自带再

3、笔者那边根本介绍下自家具体是怎么监听别的App自带的重回键,以及安卓机里的物理再次回到键。 这干什么笔者要...

详细>>

开源中最棒的Web开荒财富汇总【美高梅老虎机平

JavaScript 深远之功效域链 2017/05/14 · JavaScript·效果域链 原稿出处: 冴羽    给列表项目增加动画 2015/05/08 · CSS,HTML...

详细>>

创设高品质WEB之HTTP首部优化,Chrome开拓者工具不

前端当半夏件操作与上传 2017/12/07 · JavaScript· 1 评论 ·文件 最先的作品出处:人人网FED博客    前端不可能像原生应...

详细>>