(本文不是一篇详细介绍Chrome Extension编写的文章,只是讨论其中一些关键点)。
Chrome与Firefox一样,在可扩展性方面都做得不错(Extension与Plugin)。Extension主要的开发语言就是HTML与javascript,可利用的API除了javascript核心API及DOM API之外,不同的浏览器提供的不同API(如:WebKit APIs & V8 APIs)。
从编程者的角度来看,首先需要了解的就是Chrome Extension的源码目录结构。总体结构为: manifest.json ==》Extension的描述文(title & icon ...); .html文件 ==》Extension的逻辑及UI; .js文件 ==》主要是在html文件中引用; .json文件 ==》用作国际化。 接下来看一个实际例子(Google's Sample ==》 Gmail):
这个例子中有二个亮点: 1.开始载入时的动画:采用了最基本的动画设计方法(paintFrame() 与 update()),其中update()负责修改动 画状态(本例中是'.'的位置),同时本例中的update()是蕴含在paintFrame()中的,paintFrame()前面部 分生成待绘制的字符串(形如:" . "),接着就是调用 chrome.* API 了; - /**
-
* XXX: utility of this program: animation director
-
*
-
* A "loading" animation displayed while we wait for the first response from
-
* Gmail. This animates the badge text with a dot that cycles from left to right.
-
*/
-
function LoadingAnimation() {
-
this.timerId_ = 0;
-
this.maxCount_ = 8; // Total number of states in animation
-
this.current_ = 0; // Current state
-
this.maxDot_ = 4; // Max number of dots in animation
-
}
-
-
/* design of this animation is good */
-
LoadingAnimation.prototype.paintFrame = function() {
-
var text = "";
-
for (var i = 0; i < this.maxDot_; i++) {
-
text += (i == this.current_) ? "." : " ";
-
}
-
if (this.current_ >= this.maxDot_)
-
text += "";
-
-
chrome.browserAction.setBadgeText({text:text});
-
this.current_++;
-
if (this.current_ == this.maxCount_)
-
this.current_ = 0;
-
}
-
-
LoadingAnimation.prototype.start = function() {
-
if (this.timerId_)
-
return;
-
-
var self = this;
-
this.timerId_ = window.setInterval(function() {
-
self.paintFrame();
-
}, 100);
-
}
-
-
LoadingAnimation.prototype.stop = function() {
-
if (!this.timerId_)
-
return;
-
-
window.clearInterval(this.timerId_);
-
this.timerId_ = 0;
-
}
2.轮询未读邮件:轮询间隔时间为min(randomness * pollIntervalMin * exponent, pollIntervalMax),其中 exponent = pow(2, requestFailureCount); 也就是说当轮询未得到XML的次数越多,轮询间隔就越大,这 是比较合理的,因为当失败次数越多说明当前的网络状况越差,这时应该过较长时间再去轮询查看未读邮件 数; - /* choose a timepoint to request again randomly */
-
function scheduleRequest() {
-
var randomness = Math.random() * 2;
-
var exponent = Math.pow(2, requestFailureCount);
-
var delay = Math.min(randomness * pollIntervalMin * exponent,
-
pollIntervalMax);
-
delay = Math.round(delay);
-
-
window.setTimeout(startRequest, delay);
-
}
==更新== 还有一个地方很不错: 当未读邮件数发生更改时的动画:它的每一帧中,图标的角度在不断变化(有多种改变方案),从而制作出了旋转的效果,通过将旋转绘制到canvas中,然后再绘制到browseAction的Icon上; - function drawIconAtRotation() {
-
canvasContext.save();
-
canvasContext.clearRect(0, 0, canvas.width, canvas.height);
-
canvasContext.translate(
-
Math.ceil(canvas.width/2),
-
Math.ceil(canvas.height/2));
-
canvasContext.rotate(2*Math.PI*ease(rotation));
-
//canvasContext.rotate(2*Math.PI*(rotation));
-
canvasContext.drawImage(loggedInImage,
-
-Math.ceil(canvas.width/2),
-
-Math.ceil(canvas.height/2));
-
canvasContext.restore();
-
-
chrome.browserAction.setIcon({imageData:canvasContext.getImageData(0, 0,
-
canvas.width,canvas.height)});
-
-
}
另外,就是第二个两点中的轮询间隔时间并没有考虑未读邮件数更新频率,因为当更新频率较高时,为了体现时效性,间隔时间应越小;反之越大。更新频率可以用“单位时间内未读邮件数较上次更改的次数”来表示。 ==EOF==
接下来,再来看另一个例子:
参考站点: |