前回から、

隊列を乱さない
ステージ上を素早くあちこちクリックすると、
これを避けるには、
Tween.removeTweens(対象オブジェクト);
前回のコード2のトゥイーンを定める関数には、
function setTween(target, nX, nY, duration) {
createjs.Tween.removeTweens(target);
createjs.Tween.get(target)
.to({x:nX, y:nY}, duration, createjs.Ease.bounceOut);
}
もっとも、
Tween.get(対象オブジェクト, {プロパティ:設定値, …})
第2引数はObjectインスタンスで渡す。オブジェクトには、
function setTween(target, nX, nY, duration) {
//createjs.Tween.get(target)
createjs.Tween.get(target, {override:true})
.to({x:nX, y:nY}, duration, createjs.Ease.bounceOut);
}
これで、

<script src="http://code.createjs.com/easeljs-0.6.0.min.js"></script>
<script src="http://code.createjs.com/tweenjs-0.4.0.min.js"></script>
<script>
var stage;
var circles = [];
var circleCount = 20;
var delay = 1 / circleCount;
function initialize() {
var canvasElement = document.getElementById("myCanvas");
stage = new createjs.Stage(canvasElement);
var nWidth = canvasElement.width;
var nHeight = canvasElement.height;
for (var i = 0; i < circleCount; i++) {
var nX = Math.random() * nWidth;
var nY = Math.random() * nHeight;
var circle = createCircle(10, "#113355", (i + 1) * 3);
setAppearance(circle, nX, nY, 1 - i * 0.025, "lighter");
setTween(circle, nWidth / 2, nHeight / 2, (0.5 + i * delay) * 1500);
circles.push(circle);
stage.addChild(circle);
}
stage.addEventListener("stagemouseup", startTween);
createjs.Ticker.addEventListener("tick", stage);
}
function createCircle(stroke, color, radius) {
var circle = new createjs.Shape();
var myGraphics = circle.graphics;
myGraphics.setStrokeStyle(stroke);
myGraphics.beginStroke(color);
myGraphics.drawCircle(0, 0, radius);
return circle;
}
function setAppearance(instance, nX, nY, nAlpha, composite) {
instance.x = nX;
instance.y = nY;
instance.alpha = nAlpha;
instance.compositeOperation = composite;
}
function startTween(eventObject) {
for (var i = 0; i < circleCount; i++) {
var circle = circles[i];
setTween(circle, stage.mouseX, stage.mouseY, (0.5 + i * delay) * 1500);
}
}
function setTween(target, nX, nY, duration) {
createjs.Tween.get(target, {override:true})
.to({x:nX, y:nY}, duration, createjs.Ease.bounceOut);
}
</script>
無駄遣いはしない
動きとしては、
前掲コード1では、
var circleCount = 20;
var activeCount;
function initialize() {
// ...[中略]...
for (var i = 0; i < circleCount; i++) {
// ...[中略]...
var circle = createCircle(10, "#113355", (i + 1) * 3);
setAppearance(circle, nX, nY, 1 - i * 0.025, "lighter");
setTween(circle, nWidth / 2, nHeight / 2, (0.5 + i * delay) * 1500);
// ...[中略]...
}
activeCount = circleCount;
stage.addEventListener("stagemouseup", startTween);
// createjs.Ticker.addEventListener("tick", stage);
createjs.Ticker.addEventListener("tick", tick);
}
function startTween(eventObject) {
for (var i = 0; i < circleCount; i++) {
var circle = circles[i];
setTween(circle, stage.mouseX, stage.mouseY, (0.5 + i * delay) * 1500);
}
activeCount = circleCount;
}
function setTween(target, nX, nY, duration) {
createjs.Tween.get(target, {override:true})
.to({x:nX, y:nY}, duration, createjs.Ease.bounceOut) // ;
.call(tweenComplete);
}
function tweenComplete(eventObject) {
activeCount--;
}
function tick() {
if (activeCount) {
stage.update();
}
}
この処理を加えたJavaScriptコード全体は、
つぎに、
そこで、
var stage;
var circles = [];
var circleCount = 20;
var activeCount;
var delay = 1 / circleCount;
function initialize() {
var canvasElement = document.getElementById("myCanvas");
stage = new createjs.Stage(canvasElement);
var nWidth = canvasElement.width;
var nHeight = canvasElement.height;
for (var i = 0; i < circleCount; i++) {
// var nX = Math.random() * nWidth * 50;
var nX = Math.random() * nWidth;
var nY = Math.random() * nHeight;
var circle = createCircle(10, "#113355", (i + 1) * 3);
setAppearance(circle, nX, nY, 1 - i * 0.025, "lighter");
setTween(circle, nWidth / 2, nHeight / 2, (0.5 + i * delay) * 1500);
circles.push(circle);
stage.addChild(circle);
}
activeCount = circleCount;
stage.addEventListener("stagemouseup", startTween);
createjs.Ticker.addEventListener("tick", tick);
}
function createCircle(stroke, color, radius) {
var circle = new createjs.Shape();
var myGraphics = circle.graphics;
myGraphics.setStrokeStyle(stroke);
myGraphics.beginStroke(color);
myGraphics.drawCircle(0, 0, radius);
return circle;
}
function setAppearance(instance, nX, nY, nAlpha, composite) {
instance.x = nX;
instance.y = nY;
instance.alpha = nAlpha;
instance.compositeOperation = composite;
}
function startTween(eventObject) {
for (var i = 0; i < circleCount; i++) {
var circle = circles[i];
setTween(circle, stage.mouseX, stage.mouseY, (0.5 + i * delay) * 1500);
}
activeCount = circleCount;
}
function setTween(target, nX, nY, duration) {
createjs.Tween.get(target, {override:true})
.to({x:nX, y:nY}, duration, createjs.Ease.bounceOut) // ;
.call(tweenComplete);
}
function tweenComplete(eventObject) {
activeCount--;
}
function tick() {
if (activeCount) {
stage.update();
}
}
このトゥイーンアニメーションを何度か試しながらよく見てみると、
function initialize() {
// ...[中略]...
for (var i = 0; i < circleCount; i++) {
// var nX = Math.random() * nWidth;
var nX = Math.random() * nWidth * 50;
// ...[中略]...
}
// ...[中略]...
}

帰るまでが遠足
前掲コード2で最後のリングが目的地にたどりつけないのは、
function tick() {
if (activeCount) { // 0になったら処理しない
stage.update();
}
}
最後にゴールする子まできちんと見届けようとするなら、
function tick() {
// if (activeCount) {
if (activeCount > 0) {
stage.update();
} else if (activeCount > -1) {
stage.update();
activeCount--;
}
}
ただこの処理は、
function startTween(eventObject) {
for (var i = 0; i < circleCount; i++) {
var circle = circles[i];
setTween(circle, stage.mouseX, stage.mouseY, (0.5 + i * delay) * 1500);
}
activeCount = circleCount;
createjs.Ticker.addEventListener("tick", tick); // 追加
}
function tick() {
if (activeCount > 0) {
stage.update();
} else { // if (activeCount > -1) {
stage.update();
// activeCount--;
createjs.Ticker.removeEventListener("tick", tick);
}
}
さらに見直せば、
<style type="text/css">
canvas {
background-color: #333333;
}
</style>

var stage;
var circles = [];
var circleCount = 20;
var activeCount;
var delay = 1 / circleCount;
function initialize() {
var canvasElement = document.getElementById("myCanvas");
stage = new createjs.Stage(canvasElement);
var nWidth = canvasElement.width;
var nHeight = canvasElement.height;
for (var i = 0; i < circleCount; i++) {
// var nX = Math.random() * nWidth * 50;
var nX = Math.random() * nWidth;
var nY = Math.random() * nHeight;
var circle = createCircle(10, "#113355", (i + 1) * 3);
setAppearance(circle, nX, nY, 1 - i * 0.025, "lighter");
setTween(circle, nWidth / 2, nHeight / 2, (0.5 + i * delay) * 1500);
circles.push(circle);
stage.addChild(circle);
}
activeCount = circleCount;
stage.addEventListener("stagemouseup", startTween);
createjs.Ticker.addEventListener("tick", tick);
}
function createCircle(stroke, color, radius) {
var circle = new createjs.Shape();
var myGraphics = circle.graphics;
myGraphics.setStrokeStyle(stroke);
myGraphics.beginStroke(color);
myGraphics.drawCircle(0, 0, radius);
return circle;
}
function setAppearance(instance, nX, nY, nAlpha, composite) {
instance.x = nX;
instance.y = nY;
instance.alpha = nAlpha;
instance.compositeOperation = composite;
}
function startTween(eventObject) {
for (var i = 0; i < circleCount; i++) {
var circle = circles[i];
setTween(circle, stage.mouseX, stage.mouseY, (0.5 + i * delay) * 1500);
}
activeCount = circleCount;
createjs.Ticker.addEventListener("tick", tick);
}
function setTween(target, nX, nY, duration) {
createjs.Tween.get(target, {override:true})
.to({x:nX, y:nY}, duration, createjs.Ease.bounceOut)
.call(tweenComplete);
}
function tweenComplete(eventObject) {
activeCount--;
}
function tick() {
if (activeCount > 0) {
stage.update();
} else {
stage.update();
createjs.Ticker.removeEventListener("tick", tick);
}
}