如何用CreateJS创建动态网页内容

324 阅读11分钟

用CreateJS创建动态网页内容

CreateJS是一套Javascript库,可以帮助你创建互动内容。它可以方便地进行画布操作、动画、声音效果和资产加载。CreateJS由四个库组成:EaselJS、TweenJS、SoundJS和PreloadJS。你可以独立或组合使用它们。

简介

网络已经有了很大的发展,如今,它允许更多生动的内容。特别是,HTML5引入了动态图形和声音的新功能。这使得创建很酷的内容变得更加容易,从信息图表到小游戏。有一个工具可以帮助你做到这一点,那就是CreateJS。

在本指南中,我们将介绍这些库的一些关键功能,以便你可以使用它们来创建有趣的网页内容。

前提条件

要跟上本指南,你应该有中级的Javascript知识。这包括回调函数箭头函数对象的知识。

每个库都是做什么的?

正如我们前面提到的,CreateJS由四个库组成:EaselJS、TweenJS、SoundJS和PreloadJS。这些库中的每一个都是独立的,但它们可以一起使用。EaselJS以画布图形操作为中心。它允许用户绘制图形,移动图形,添加事件监听器,以及操作精灵。

TweenJS是一个用于创建复杂动画的库。它通过使用数学函数操作属性来实现。你指定你想让你的对象过渡到哪个属性值,以及一个函数来指定它如何达到那个状态。你甚至可以用它来改变CSS样式属性。

接下来,PreloadJS用于为你的应用程序预装资产。这可以是任何东西,从声音到图像。最后,SoundJS,顾名思义,是用来加载、播放和操作声音的。尽管你可以将声音加载委托给PreloadJS。

设置CreateJS

CreateJS的设置非常简单。只需要一个空白的HTML页面,并加上以下脚本标签。


<script src="https://code.createjs.com/1.0.0/createjs.min.js"></script>

然后,当然你需要创建一个空白的main.js 文件,并将其链接到我们的HTML。

加载资产

PreloadJS使加载图像和声音资产变得超级容易,只需几个步骤。首先,我们需要在我们的main.js 文件中初始化一个createjs.LoadQueue 对象。

然后像这样调用该对象的installPlugin 方法。

let queue = new createjs.LoadQueue();

queue.installPlugin(createjs.Sound);

我们需要这样调用installPlugin 方法的原因是,我们可以加载声音资产,让它与SoundJS 。接下来,我们需要调用LoadQueue 对象的loadManifest 方法来加载我们的资产。

这个方法接收一个对象的数组,每个对象都有一个id和一个src属性。id是为了在我们要使用这些资产的时候引用它们。

同时,src属性指定了资产文件的位置。

queue.loadManifest([
	{ id: "cloud", src: "./assets/cloud.png" },
	{ id: "wind", src: "./assets/wind.m4a" },
]);

然后我们可以调用queue 对象的on 方法,为资产加载时传递一个回调。

queue.on("complete", (_) => {
	console.log("finished loading");
});

现在,如果你在浏览器中测试这个,你会看到在控制台中打印出加载完毕。此外,如果你在你的开发工具中检查网络标签,你应该看到类似这样的东西。

successful asset loading

注意我们有两个GET请求,分别是wind.m4acloud.png 。其中一个的状态是200,另一个是304。这意味着我们成功加载了我们的资产。如果你不知道,你可以通过右键单击并选择检查检查元素来打开开发工具。

播放声音

如果我们不使用资产,在我们的页面上加载资产是没有意义的。让我们来看看如何播放我们刚刚添加的声音。SoundJS让我们的声音播放变得很简单。

在加载完成后的回调函数中,我们所需要的只是一个单一的方法调用。

// Play the wind sound. The string passed is the id we used when loading the sound.
createjs.Sound.play("wind");

现在,如果你想操作声音,play 方法返回一个代表你想播放的声音的对象。你可以改变一些属性,比如它的音量,你想循环多少次,它是否暂停,等等。我们不会在这里讨论如何操作这些东西,因为它应该和改变属性一样简单。

一个有趣的事情是,这个声音对象也有和加载队列一样的on 方法。你可以用它来对声音加载*(完成*)或声音加载失败*(失败*)等事件做出反应。

绘制图像

接下来,让我们看看如何绘制我们加载的图像。我们将把它绘制到HTML5画布上,这样我们也可以展示EaselJS。

首先,我们需要在HTML中添加一个画布元素来绘制图片。


<canvas id="my-canvas" width="800px" height="800px"></canvas>

然后,在我们的Javascript文件中,我们可以使用它的id来创建一个引用。


let stage = new createjs.Stage('my-canvas');

然后,让我们创建一个名为stageInit 的函数,在画布上绘制我们的云。在该函数中,我们需要创建一个新的createjs.Shape 实例。

使用该实例的graphics 对象,我们可以告诉它用一个特定的尺寸来画我们的云。

let shape = new createjs.Shape();
shape.graphics
	.beginBitmapFill(queue.getResult("cloud"))
	.drawRect(0, 0, 100, 100);

然后,为了把它放在舞台上,我们设置x和y属性,并调用我们舞台对象的addChild 方法。

shape.x = 100;
shape.y = 100;
stage.addChild(shape);

所有这些完成后,该函数应该是这样的。

function stageInit() {
	let stage = new createjs.Stage("my-canvas");

	let shape = new createjs.Shape();
	shape.graphics
		.beginBitmapFill(queue.getResult("cloud"))
		.drawRect(0, 0, 100, 100);

	shape.x = 100;
	shape.y = 100;
	stage.addChild(shape);
}

从那里,我们只需要在资产加载完毕后的回调中调用它。现在,如果你在浏览器中运行这个功能,你还不能看到云。这是因为每次我们改变舞台上的东西时,都需要调用一个更新方法。

我们要做的是使用CreateJS提供的Ticker 类来解决这个问题,在一定的帧速率下调用这个更新方法。这个股票的默认帧率是每秒20帧。你可以使用framerateinterval 属性来改变这个。

要在每一帧上调用更新方法,只是像我们之前做的那样,添加一个事件监听器。

createjs.Ticker.on("tick", (_) => {
	stage.update();
});

现在有了这个补充,云层终于可以正常渲染了。

用TweenJS给图片做动画

目前,我们的云仍然在画布上,在一个地方。我们可以用TweenJS为它创建一个来回摆动的动画。这个动画将出现在一个叫做animateCloud 的函数中,该函数将代表我们的云的形状作为云的参数。我们将在资产加载时,在回调函数的末尾调用该函数。

为了开始,我们调用createjs.Tween 类中的静态get 方法。

createjs.Tween.get(cloud, { loop: true });

我们把我们的云参数作为第一个参数传给它,告诉它要改变该对象的属性。理论上,你可以在这里传递任何对象,TweenJS会改变它的属性,以尝试对它进行动画处理。下一个对象是一个单一的属性,说我们要循环播放动画。

接下来,我们像这样调用get 的返回值的to 方法。

createjs.Tween.get(cloud, { loop: true }).to(
	{ x: 500 },
	2000,
	createjs.Ease.getPowInOut(4)
);

在这里,第一个参数指定了我们的cloud 对象的哪些属性我们要改变,以及改变到什么值。在这种情况下,我们要把它的x属性改变为500的值。然后,我们指定该动画将在2000毫秒(2秒)内播放。

然后,我们指定我们的缓和函数为一个进出的四元函数(一个最大项为4次方的多项式)。你无法用语言准确地理解这一点,所以请看这个可视化图。A

call 一旦完成了这些,我们就可以通过调用to 的返回值来告诉TweenJS播放我们的风声。

createjs.Tween.get(cloud, { loop: true })
	.to({ x: 500 }, 2000, createjs.Ease.getPowInOut(4))
	.call(playWindSound);

注意,playWindSound 参数是一个函数,可以像我们上面做的那样播放风声。现在,我们可以让我们的云回到它原来的地方,用同样的缓解函数,然后再一次播放声音。

createjs.Tween.get(cloud, { loop: true })
	.to({ x: 500 }, 2000, createjs.Ease.getPowInOut(4))
	.call(playWindSound)
	.to({ x: 100 }, 2000, createjs.Ease.getPowInOut(4))
	.call(playWindSound);

总的来说,我们刚才写的函数应该是这样的。

function animateCloud(cloud) {
	createjs.Tween.get(cloud, { loop: true })
		.to({ x: 500 }, 2000, createjs.Ease.getPowInOut(4))
		.call(playWindSound)
		.to({ x: 100 }, 2000, createjs.Ease.getPowInOut(4))
		.call(playWindSound);
}

与精灵一起工作

作为本指南的一个有趣的结束方式,让我们看看如何创建动画精灵。在我们的指南中,我们将使用我制作的这个精灵表来制作一个棍状物的动画。

sprite sheet

前两帧我们将用作运行动画,而后两帧将是空闲动画。当然,在我们开始之前,我们需要将我们的精灵图谱作为资产加载。

把我们的精灵图谱添加到我们给PreloadJS的清单中。

queue.loadManifest([
	{ id: "cloud", src: "./assets/cloud.png" },
	{ id: "wind", src: "./assets/wind.m4a" },
	{ id: "spritesheet", src: "./assets/sprite-sheet.png" },
]);

在这里,让我们创建一个名为spriteInit 的方法。这将创建我们的棒形图和它的动画,并将它们放置在一起。

为了做到这一点,我们需要创建一个包含我们的精灵表信息的对象。

let data = {
	images: [queue.getResult("spritesheet")],
	frames: { width: 14, height: 21, regX: 0, regY: 0, spacing: 0, margin: 0 },
	animations: {
		idle: [2, 3, "idle"],
		run: [0, 1, "run"],
	},
};

images 属性是一个数组,包含我们的精灵将用于其动画的所有图像。然后,frames 属性指定了关于精灵图谱中每一帧的细节。这包括尺寸、其注册点的坐标(regX,regY )、间距和空白。

顺便说一下,注册点的作用有点像精灵的旋转中心。不仅如此,当你把精灵放在舞台上时,你放置精灵的坐标将是你的注册点的位置。如果我们有一个Sprite 对象,并将其x和y属性设置为10,那么它将在10,10点上画出注册点。

然后,精灵的其余部分将相对于注册点。如果你还不太明白这意味着什么,不要担心,这不会成为本指南的一个因素。如果你想了解更多信息,玩玩注册点应该会对你有帮助。animations 属性是一个包含我们动画信息的对象。

例如,idle属性定义了一个数组,代表我们的空闲动画。数组的前两个元素代表动画的开始和结束帧。CreateJS所做的是,根据我们的frames 对象,将我们的sprite sheet分割成适当的帧,并像数组一样给它编号。

在我们的例子中,它将在精灵表中对我们的帧进行编号,像这样。

frame indexing example

我们的空闲动画的开始帧(2)和结束帧(3)对应于我们精灵表的最后两帧。同样地,运行动画的开始帧(0)和结束帧(1)是前两帧。

回到空闲数组,最后一个元素是一个字符串,是我们想在完成后过渡到的动画的名称。在这个例子中,空闲动画是循环的,因为我们把字符串idle放在了最后。

对于我们的运行动画也是如此。作为一个额外的说明,你可以给代表数组的属性起任何你想要的名字。然后,当你想播放动画时,它们会被用作参考。最后还有一个可选的元素,你也可以添加到你的数组中,以加快或减慢动画的速度。

例如,如果你在字符串的后面加上0.25,那么它将把动画的速度放慢到25%。同样地,如果你在最后加上2,它将使动画的速度增加一倍。

有了创建的精灵表数据,重置就很简单了。我们用这些数据来创建一个精灵对象,然后把它放在画布上。

let data = {
	images: [queue.getResult("spritesheet")],
	frames: { width: 14, height: 21, regX: 0, regY: 0, spacing: 0, margin: 0 },
	animations: {
		idle: [2, 3, "idle"],
		run: [0, 1, "run"],
	},
};

let spriteSheet = new createjs.SpriteSheet(data);
// create the sprite object using our sprite sheet, have it start off in the idle animation
let sprite = new createjs.Sprite(spriteSheet, "idle");

sprite.x = 40;
sprite.y = 40;

最后,让我们把它变成这样:按d键会触发我们的运行动画,按a键会触发空闲动画。

window.addEventListener("keydown", (ev) => {
	if (ev.key === "d") {
		sprite.gotoAndPlay("run");
	} else if (ev.key === "a") {
		sprite.gotoAndPlay("idle");
	}
});

现在我们实现了spriteInit 方法,我们需要在我们的回调函数的末尾调用它,以便在加载资产时使用。

总结

在本指南中,我们学习了用createJS创建内容的一些基础知识。我们讨论了它所组成的库,加载资产,绘制图形和动画。从这里开始,你应该能够开始使用这些工具来构建画布艺术或游戏。