HTML5テクニカルノート
設定のオン・オフを切り替える - トグルボタンの論理組み立て
- ID: FN1512001
- Technique: HTML5 and JavaScript
- Library: EaselJS 0.8.1
ひとつのボタンで設定のオン・オフを切り替えたいことがあります。EaselJSで表示オブジェクトにドロップシャドウを掛けたり外したりする例で、その論理の組み立て方についてご説明しましょう。もちろん、考え方はCreateJSにかぎったものではありません。
01 DisplayObjectインスタンスにドロップシャドウを加える
同じ操作でふたつの状態を切り替える仕組みは「トグル」といい、オン・オフの切り替えボタンはトグルボタンと呼ばれます。EaselJSのDisplayObject
インスタンスは、DisplayObject.shadow
プロパティにShadow
オブジェクトを定めると、ドロップシャドウが加わります。ドロップシャドウを消すには、プロパティにnull
を与えます。
Shadow()
コンストラクタは、つぎのように4つの引数をとります。デフォルト値は色が黒("black")、あとの3つの引数については0です。
new Shadow (色, 水平のずれ, 垂直のずれ, ぼかし幅)
つぎのコードは、Shapeインスタンス(shape)にドロップシャドウ(shadow)を加えます(図001)。
var shape = new createjs.Shape(); var shadow = new createjs.Shadow("#000", 2, 2, 20); shape.shadow = shadow;
図001■Shapeインスタンスにドロップシャドウが加わった
02 ドロップシャドウのオン・オフを関数で切り替える
では、ドロップシャドウのオン・オフを関数で切り替えてみます。インスタンス(shape)のDisplayObject.shadow
プロパティの値がnull
であれば、ドロップシャドウが加えられていないと判定できます。したがって、以下のコード001のように関数(toggleShadow())を定め、if
条件で切り分けて、DisplayObject.shadow
プロパティにそれぞれの値を与えればよいでしょう。たとえば、Shapeインスタンスの"click"イベントにリスナー関数として加えれば、インスタンスをクリックするたびにドロップシャドウが掛かったり消えたりします。
shape.addEventListener("click", toggleShadow);
コード001■ドロップシャドウのオン・オフを切り替える関数
function toggleShadow() {
if (shape.shadow == null) {
shape.shadow = shadow;
} else {
shape.shadow = null;
}
}
03 関数でドロップシャドウがオンかオフかも定められるようにする
設定のオン・オフを関数で切り替えるようにした場合、オンにするのかオフにするのかどちらかひとつを選んで決めたいこともあります。そこで、関数にブール値の引数を加え、引数があればその値にしたがい、なければもとのままオンとオフを切り替えるということにしましょう。ドロップシャドウを掛けるのか消すのか、if
条件でふたつに切り分けようとすると、つぎのようなコードになるかもしれません。たしかに、これで正しく動きます。けれど、わかりにくいでしょう。
function toggleShadow(show) { if (show === true || (typeof show != "boolean" && shape.shadow == null)) { shape.shadow = shadow; } else if (show === false || (typeof show != "boolean" && shape.shadow != null)) { shape.shadow = null; } }
込み入った条件にすると、場合の拾い漏れが生じやすくなります。また、修正や追加も慎重にしなければ、バグが起こりがちです。そして、上記コードを細かく見ると、引数(show)がtrue
でなくかつブール値のときはfalse
に決まっているのに、改めてelse if
条件でfalse
かどうかを調べることになっていて無駄です。さらに、引数がブール値でなくかつインスタンスにすでにドロップシャドウが掛かっている場合には、if
とelse if
のすべての条件を評価した末にようやくシャドウが消されることになります。
コードの行数が増えても、つぎのコード002の方が見やすく、場合の拾い漏れも防げます。また、すべての場合がふたつの条件で仕分けられるため、無駄もありません。
コード002■関数にブール値の引数を与えるとその設定が行われてそうでない場合には切り替える
function toggleShadow(show) {
if (typeof show == "boolean") {
if (show) {
shape.shadow = shadow;
} else {
shape.shadow = null;
}
} else {
if (shape.shadow == null) {
shape.shadow = shadow;
} else {
shape.shadow = null;
}
}
}
04 条件演算子でコード行数を減らす
条件(三項)演算子:?
を使うと、前掲コード002と同じ論理の組み立てで、つぎのコード003のように行数は減らすことができます。条件演算子を用いれば多くの場合コードは減らせるものの、入れ子などあまり込み入った構成にするとわかりにくくなりがちなので注意しましょう。また、変数・プロパティへの代入が必ずしも要らない場合には、無駄な処理が生じることもありえます。代入をともなう条件判定の処理のとき、検討する価値があります。
コード003■関数にブール値の引数を与えるとその設定が行われてそうでない場合には切り替える(条件演算子を使用)
function toggleShadow(show) {
if (typeof show == "boolean") {
shape.shadow = show ? shadow : null;
} else {
shape.shadow = (shape.shadow == null) ? shadow : null;
}
}
05 ドロップシャドウのオン・オフを切り替える作例
前掲コード003の関数(toggleShadow())を使った作例がつぎのサンプル001です。円形のShapeインスタンスをクリックすると、ドロップシャドウは掛かったり消えたり設定が切り替わります。スクリプト全体は、以下のコード004にまとめました。
サンプル001■CreateJS 15/05/21: オブジェクトのクリックでドロップシャドウのオン・オフを切り替える
コード004■オブジェクトのクリックでドロップシャドウのオン・オフを切り替える
var stage;
var shape = new createjs.Shape();
var shadow = new createjs.Shadow("#000", 2, 2, 20);
function initialize(eventObject) {
var canvasElement = document.getElementById("canvas");
stage = new createjs.Stage(canvasElement);
stage.addChild(shape);
shape.x = canvasElement.width / 2;
shape.y = canvasElement.height / 2;
shape.addEventListener("click", change);
draw();
toggleShadow(true);
stage.update();
}
function draw() {
var graphics = shape.graphics;
graphics.beginFill("cyan")
.drawCircle(0, 0, 50);
}
function toggleShadow(show) {
if (typeof show == "boolean") {
shape.shadow = show ? shadow : null;
} else {
shape.shadow = (shape.shadow == null) ? shadow : null;
}
}
function change(eventObject) {
toggleShadow();
stage.update();
}
window.addEventListener("load", initialize);
同じ関数(toggleShadow())は、つぎのサンプル002でも使っています(左下のリンククリックでアニメーションの設定が、ドロップシャドウも含めて変えられます)。コード行数は前掲サンプル001よりずっと多いものの、ドロップシャドウのオン・オフはまったく同じ仕組みです。
サンプル002■CreateJS 15/05/21: Arc Rainbow
作成者: 野中文雄
作成日: 2015年12月1日
Copyright © 2001-2015 Fumio Nonaka. All rights reserved.