createJs简介
createJS分为四大部分:
1.easelJs(负责图形、事件、触控、滤镜等功能) -easel画架 黑板架
2.tweensJs(补间动画)
3.soundJs(音频控制)
4.preloadJs(文件加载)
easelJs
easelJs的目标是替代flash,它可以绘制复杂的图形UI并提供交互接口,无需插件即可在浏览器中运行。 easelJs有几个基本的概念:
-
DisplayObject(展示物体)
Easel中可以展现物体的抽象基类(所有可视物件(例如Bitmap、Shape、Text等)的最上层基类)。包括一些最基本最常用的属性(例如: 坐标, 旋转, x缩放, Y缩放, 扭转X, 扭转Y, 透明度, 阴影等等) -
Stage(舞台-包裹canvas)
可展示元素的根容器. 每当Stage的update()方法调用时, 会自动刷新所有待展示物体列表。easelJs里可以有一个以上的stage。 创建舞台、添加图形、更新舞台 -
Container(容器)
可交叉的展示容器, 可以将物体进行分组管理. -
Text(文本)
可以展示的文本对象. -
Bitmap(位图)
位图对象,视频,画布等等. -
BitmapAnimation(位图动画)
一系列动态的图片组成的动画,并提供了相应的操作API。 -
Graphics(图形)
提供了简单但是强大的绘制向量图形的API方法. -
Shape(形状)
使用Graphics绘制的向量艺术图形. -
DOMElement(DOM元素)
可以用来展示的DOM元素. -
Filter(过滤器)
包括其它过滤器的基过滤器(例如. BoxBlurFilter, ColorMatrixFilter等等)
示例1-扩展现有对象定义新的视觉类:
<canvas id="demo" width="500" height="300"></canvas>
<script type="text/javascript">
(function() {
//自定义一个button类
function Button(label, color) {
this.Container_constructor();
this.label = label;
this.color = color;
this.setup();
}
var p = createjs.extend(Button, createjs.Container);
p.setup = function() {
var text = new createjs.Text(this.label, "20px Arial", "#fff");
text.textAlign = "center";
var width = text.getMeasuredWidth() + 30;
var height = text.getMeasuredHeight() + 20;
text.x = width/2;
text.y = 10;
var background = new createjs.Shape();
background.graphics.beginFill(this.color).drawRoundRect(0,0,width,height,10);
this.addChild(background, text);
this.cursor = "pointer";
this.on("click", this.handleClick);
} ;
p.handleClick = function () {
alert(this.label + ":走开,不要点我");
}
window.Button = createjs.promote(Button, "Container"); //识别所有被button覆盖的container方法(包括构造函数)
}());
</script>
<script type="text/javascript">
window.onload = function () {
var stage = new createjs.Stage("demo");
var btn1 = stage.addChild(new Button("按钮一号", "#0F0"));
var btn2 = stage.addChild(new Button("按钮二号", "#0FF"));
btn1.y = 10;
btn2.y = 100;
createjs.Ticker.on("tick", stage);
}
</script>
关于prototype
作为一种脚本语言,javascript的设计者在设计时认为无需为其引入继承的机制,但是javascript里面一切皆对象,必须有一种机制将这些对象关联起来。
一旦有了类的概念,那javascript就变成了和c++及java这种一样完整的面向对象语言了(javascript的创造初衷是为了减少服务器端的压力,在前端解决掉一些表单验证等问题减少服务器端数据交互)。所以作者并不打算引入类的概念,但他确实引入了new关键字,但是javascript中new后面直接是构造函数,而非传统的“类“的构造函数”。
function Person (name) {
this.name = name;
this.sex = "女";
}
var personA = new Person("阿花");
var personB = new Person("小明");
personB.sex = "男";
console.log(personA.name + ":" + personA.sex + ";" + personB.name + ":" + personB.sex);
//阿花:女;小明:男 这两个对象的sex属性是独立的。
console.log("我是华丽丽的分割线------------");
为了实现数据共享,所以作者引入了prototype属性,prototype有一个prototype对象,所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面。
function Person (name) {
this.name = name;
}
Person.prototype = {
sex: "女"
};
var personA = new Person("阿花");
var personB = new Person("小明");
Person.prototype.sex = "男"; //注意是Person.prototype 直接访问原型链了
console.log(personA.name + ":" + personA.sex + ";" + personB.name + ":" + personB.sex);
//阿花:男;小明:男
console.log("我是华丽丽的分割线------------");
关于extend
extend方法常用于开发jquery插件。jQuery提供了两个方法,$.extend和$.fn.extend,简单来说:$.extend(),是用来扩展jQuery静态方法(把两个或者更多的对象合并到第一个当中,静态方法无法用实例调用);$.fn.extend()是用来扩展jQuery实例方法(把对象挂载到jQuery的prototype属性,来扩展一个新的jQuery实例方法)。
//扩展静态方法:
$.extend({
sayName:function (){
console.log("My name is jQuery");
}
});
$.sayName(); //"My name is jQuery"
//扩展实例方法:
$.fn.extend({
check: function() {
return this.each(function() {
this.checked = true;
});
}
});
$( "input[type='checkbox']" ).check(); //所有的checkbox都会被选择
//静态方法,直接使用$调用;扩展的实例方法,要用$()调用。
extend的参数: extend(dest,src1,src2…srcN);//可以传入N多个对象,将src1,src2…srcN的每一项合并为dest的每一项,并返回合并后的对象
var dest = {name:"job",age:20},src1 = {name:"tom",live:"Beijing"};
$.extend(dest,src1);
console.log(dest); //{name: "tom", age: 20,live:"Beijing"} 合并并覆盖 若不想改变dest本身可以使用下面方法创建新的对象
var newSrc = $.extend({},dest,src1,src2...srcN);
//可用于编写插件时设置默认值
(function ($){
$.fn.extend({
dialog:function (options){
//设置默认样式
var defualt = {
width:100,
height:100
};
//传过来的参数覆盖默认值
var style = $.extend({},defualt,options);
console.log(style); //defualt变为:{width: 200, height: 200}
console.log(defualt); //{width: 100, height: 100}
$("div").css(style)
}
});
})(jQuery);
$().dialog({
width: 200,
height: 200
});
当extend只有一个参数时:
$.extend(dest) //将dest的每一项合并到jQuery全局对象中
$.fn.extend(dest)将dest的每一项合并到jQuery的实例中
当extend第一个参数为布尔值时:Boolean为true时,为深层拷贝;Boolean为false时,为浅拷贝。
var src1 = {name:"tom",location:{city:"Beijing",county:"China"}};
var src2 = {name:"job",location:{live:"New York",county:"USA"}};
var src3 = $.extend(true,src1,src2);
//src3 = = src1
//src1为{name: "job", location: {city: "Beijing",county: "USA",live: "New York"}}
//元素又覆盖又合并
var src3 = $.extend(false,src1,src2);
//src3 !== src1 src3为{name: "job", location: {county: "USA", live:"New York"}}
//src1为{name: "tom", location: {city: "Beijing",county: "China"}}
//元素会覆盖不会合并
解析jQuery中extend方法
javascript中的静态方法和实例方法
示例2-简单的动画和时间类
easelJs提供了Ticker类(断续器),提供了常规的心跳,暂停和时间间隔,并且封装了setTimeout和requestAnimationFrame
window.onload = function () {
var stage = new createjs.Stage("demo");
var circle = new createjs.Shape();
circle.graphics.beginFill("DeepSkyBlue").drawCircle(0, 0, 50);
circle.x = 100;
circle.y = 100;
stage.addChild(circle);
// createjs.Ticker.setInterval(25); 1s / 25ms = 40fps
createjs.Ticker.setFPS(40);
createjs.Ticker.addEventListener("tick", function (e) {
circle.x += 5;
if (circle.x > stage.canvas.width) {
circle.x = 0;
}
stage.update(e); //必须 每次canvas有修改时必须update stage
});
} Timer可以使我们很方便动态的调整不同动画的帧率
<select onchange="createjs.Ticker.setFPS(Number(this.value));">
<option value="10">10 fps</option>
<option value="30">30 fps</option>
<option value="50">50 fps</option>
<option value="60">60 fps</option>
</select>
<canvas id="demo" width="500" height="500" style="border: 1px solid #eee;"></canvas>
<script type="text/javascript">
window.onload = function () {
var stage = new createjs.Stage("demo");
var circle = new createjs.Shape();
circle.graphics.beginFill("DeepSkyBlue").drawCircle(0, 0, 50);
circle.x = 50;
circle.y = 50;
var circleTick = new createjs.Shape();
circleTick.graphics.beginFill("red").drawCircle(0, 0, 50);
circleTick.x = 180;
circleTick.y = 180;
stage.addChild(circle, circleTick);
createjs.Ticker.setFPS(40);
createjs.Ticker.addEventListener("tick", function (e) {
circle.x += e.delta/1000*100; //保持初始设置 与帧率相关
circleTick.x += 10;
if (circle.x > stage.canvas.width) {
circle.x = 0;
}
if (circleTick.x > stage.canvas.width) {
circleTick.x = 0;
}
stage.update(e);
});
}
</script>
示例3-使用谷歌网字体 直接去谷歌下载字体放在样式中,创建文本对象时直接使用即可
var txt = new createjs.Text();
txt.font = "bold 96px Dorsa";
txt.color = "#000000";
txt.text = "Hello World!";
示例4-鼠标交互事件 easelJs的鼠标交互事件很容易,只要监听鼠标事件即可。事件包括 click, mousedown, mouseup, dblclick, pressmove, pressup, mouseover / mouseout, rollover / rollout。我们挑一些好玩的看看。
- 冒泡: 当一个鼠标事件绑定到目标对象上是,事件传播会经历三个阶段,即捕获阶段、目标阶段和冒泡阶段。盗图一张:
具体可参考我的另一篇文章javascript事件机制相关
easelJs阻止事件传播可以用object.mouseChildren = false; 禁止事件发生可以用object.mouseEnabled = false;
stagemousemove stagemouseup stagemousedown:stage上的任何地方可以发生stagemousedown,stagemouseup和stagemousemove这几种交互事件。之前见过的一个很喜欢的效果easelJs也可以轻松实现
window.onload = function () {
var stage, label, shape, oldX, oldY, size, color;
function init() {
stage = new createjs.Stage("demo");
label = new createjs.Text("涂鸦板块", "24px Arial");
label.x = label.y = 10;
shape = new createjs.Shape();
stage.addChild(shape, label);
// set up our defaults:
color = "#0FF";
size = 2;
// add handler for stage mouse events:
stage.on("stagemousedown", function(event) {
size = 10;
})
stage.on("stagemouseup", function(event) {
color = createjs.Graphics.getHSL(Math.random()*360, 100, 50);
size = 2;
})
stage.on("stagemousemove",function(evt) {
if (oldX) {
shape.graphics.beginStroke(color)
.setStrokeStyle(size, "round")
.moveTo(oldX, oldY)
.lineTo(evt.stageX, evt.stageY);
stage.update();
}
oldX = evt.stageX;
oldY = evt.stageY;
})
stage.update();
}
init();
}
pressmove:
window.onload = function () { var stage, output;
stage = new createjs.Stage("demo");
var circle = new createjs.Shape();
circle.graphics.beginFill("red").drawCircle(0, 0, 50);
var label = new createjs.Text("移动我", "bold 14px Arial", "#FFFFFF");
label.textAlign = "center";
label.y = -7;
var dragger = new createjs.Container();
dragger.x = dragger.y = 100;
dragger.addChild(circle, label);
stage.addChild(dragger);
dragger.on("pressmove",function(evt) {
console.log(evt);
evt.currentTarget.x = evt.stageX;
evt.currentTarget.y = evt.stageY;
stage.update();
});
stage.update();
}
soundJs
<body>
<button id="btn">开始播放</button>
<script type="text/javascript">
window.onload = function () {
var SoundDemo = function () {
this.soundId = "thunder";
};
SoundDemo.prototype = {
init: function () {
this.loadSound();
this.playSound();
},
loadSound: function () {
createjs.Sound.registerSound("/media/thunder.mp3", this.soundId);
},
playSound: function () {
var btn = document.getElementById("btn"),
self = this;
btn.addEventListener("click", function () {
createjs.Sound.play(self.soundId);
});
// createjs.Sound.addEventListener("fileload", function () {
// createjs.Sound.play(self.soundId);
// });
}
}
//浏览器是否支持初始化默认插件
if (createjs.Sound.initializeDefaultPlugins()) {
var sound = new SoundDemo();
sound.init();
} else {
return;
}
};
</script>
</body>
- 要想播放音频,我们必须确保音频文件加载完成,我们需要在文档加载完后调用registerSound()方法,该方法有两个参数,音频路径和音频的ID, 如果是多个音频文件可调用registerSounds()方法。
-
soundJs是基于事件模型的,我们可以点击按钮播放
var btn = document.getElementById("btn"), self = this; btn.addEventListener("click", function () { createjs.Sound.play(self.soundId); }); 也可以在文件加载后立即播放(iphone下的测试,微信内置浏览器可播放,Safari中无法自动播放,app内部无法自动播放),即 createjs.Sound.addEventListener("fileload", function () { createjs.Sound.play(self.soundId); }); 关于手持设备无法自动播放音频的原因在于,音频播放是很耗流量的,苹果认为自动播放是很不友好的行为,同时也是防止很多不友好的网站骚扰用户(PC端弹出来的音频广告都很让人受不了)。如果非要自动播放,参考[博文](http://www.cnblogs.com/givebest/p/4474403.html)可使用 ajax请求绕过系统检测(尚未验证),但是从用户的角度来说,还是不要采取自动播放可能更好,移动设备上的音频通常要求用户发起的事件(触摸)开始播放。