本記事は、株式会社 函館ラボラトリが運営する「Bラボ」における、大人向け「看板アプリ(デジタルサイネージ)を作るコース」用教材テキストです。
- 【Bラボデジタルサイネージ1】Processing+ラズパイでデジタルサイネージを作る!
- 【Bラボデジタルサイネージ2】ラズパイ初期設定
- 【Bラボデジタルサイネージ3】準備プログラム作成&機能実現の方針決定
- 【Bラボデジタルサイネージ4】レイアウトの基準になるグリッドを表示する「GridModule」
- 【Bラボデジタルサイネージ5】レイアウトの基準になる枠を表示する「PlaceholderModule」
- 【Bラボデジタルサイネージ6】画像を全画面表示する「FullImageModule」
- 【Bラボデジタルサイネージ7】ページの自動切り替え
- 【Bラボデジタルサイネージ8】設置されている場所の名前を表示する「LocationModule」
- 【Bラボデジタルサイネージ9】現在の時間を表示する「DateModule」
- 【Bラボデジタルサイネージ10】ページ切り替えの時間が分かる「ProgressBarModule」
- 【Bラボデジタルサイネージ11】現在の表示中のページが分かる「PageControlModule」
- 【Bラボデジタルサイネージ12】現在の天気を表示する「WeatherRModule」
- 【Bラボデジタルサイネージ13】直近2件のバス時刻表を表示する「BusRModule」
- 【Bラボデジタルサイネージ14】ごみ出しカレンダーを表示する「GomiRModule」
- 【Bラボデジタルサイネージ15】(発展編)ツイートを表示する「TwitterRModule」
- 【Bラボデジタルサイネージ16】開店/閉店を表示する「OpenCloseRModule」
- 【Bラボデジタルサイネージ17】部屋の温度を表示する「TemperatureRModule」
- 【Bラボデジタルサイネージ18】部屋の明るさを表示する「BrightnessRModule」
- 【Bラボデジタルサイネージ19】起動画面を表示する「LaunchingScreenModule」
- 【Bラボデジタルサイネージ20】RModuleの影を実装(本記事)
作るもの
今まで実装してきた「WeatherRModule」などの「RM」に分類されるモジュールの後ろに、薄い影を描画します。
影がある状態
影がない状態
影がある状態
影がない状態
影の作り方
RModuleのうしろに影を描画します。
影を作るには、RModuleの背景画像と同じように、PGraphicsを使います。
生成する影は下図のようなものです。
この影は、灰色の角丸四角をぼかしたものです。
影の手前に、例としてTemperatureRModule用の背景を描画してみます。
影のほうが一回り大きいので、RModuleの背景のうしろから、うっすらと灰色がにじんでいます。
このようにして、各RModuleに影をつけます。
影の画像を生成
影に関連する変数を定義します。
/* 略 */
// Shadow
final int SHADOW_ALPHA = 60;
final int SHADOW_PADDING = 20;
PGraphics moduleShadowS;
PGraphics moduleShadowM;
PGraphics moduleShadowL;
/* 略 */
影の透明度、RModuleの背景画像のまわりに確保するピクセル数、RModuleのサイズ別(S、M、L)の影画像用変数を定義しました。
SHADOW_PADDING=20
なので、影の画像は縦横ともに、40ピクセル(20ピクセルを左右、または上下)を余分に確保することになります。
次に、影の初期化用関数initializeShadow()
を新しくつくります。
/* 略 */
void initializeShadow() {
Size size;
int w;
int h;
// 影はモジュールよりも少し大きいサイズにする
size = Size.S;
w = moduleWidth(size) + SHADOW_PADDING * 2;
h = moduleHeight(size) + SHADOW_PADDING * 2;
// 影の画像を生成する
moduleShadowS = createGraphics(w, h);
moduleShadowS.beginDraw();
moduleShadowS.colorMode(HSB, 360, 100, 100, 100);
moduleShadowS.noStroke();
moduleShadowS.fill(0, 0, 0, SHADOW_ALPHA);
moduleShadowS.rect(SHADOW_PADDING, SHADOW_PADDING,
moduleWidth(size), moduleHeight(size),
MODULE_RECT_ROUND);
moduleShadowS.filter(BLUR, 8); // にじませる
moduleShadowS.endDraw();
// 影はモジュールよりも少し大きいサイズにする
size = Size.M;
w = moduleWidth(size) + SHADOW_PADDING * 2;
h = moduleHeight(size) + SHADOW_PADDING * 2;
// 影の画像を生成する
moduleShadowM = createGraphics(w, h);
moduleShadowM.beginDraw();
moduleShadowM.colorMode(HSB, 360, 100, 100, 100);
moduleShadowM.noStroke();
moduleShadowM.fill(0, 0, 0, SHADOW_ALPHA);
moduleShadowM.rect(SHADOW_PADDING, SHADOW_PADDING,
moduleWidth(size), moduleHeight(size),
MODULE_RECT_ROUND);
moduleShadowM.filter(BLUR, 8); // にじませる
moduleShadowM.endDraw();
// 影はモジュールよりも少し大きいサイズにする
size = Size.L;
w = moduleWidth(size) + SHADOW_PADDING * 2;
h = moduleHeight(size) + SHADOW_PADDING * 2;
// 影の画像を生成する
moduleShadowL = createGraphics(w, h);
moduleShadowL.beginDraw();
moduleShadowL.colorMode(HSB, 360, 100, 100, 100);
moduleShadowL.noStroke();
moduleShadowL.fill(0, 0, 0, SHADOW_ALPHA);
moduleShadowL.rect(SHADOW_PADDING, SHADOW_PADDING,
moduleWidth(size), moduleHeight(size),
MODULE_RECT_ROUND);
moduleShadowL.filter(BLUR, 8); // にじませる
moduleShadowL.endDraw();
}
PGraphicsを扱う記述のなかに出てきた下記の処理は、PGraphicsにぼかしを加えるための処理です。
moduleShadowS.filter(BLUR, 8); // にじませる
定義したinitializeShadow()
によって、RModuleの各サイズ(S、M、L)ごとに対応する影を生成します。
関数initialize()
内で呼び出すようにしておきましょう。
void initialize() {
initializeDate();
isInitializedDates = true;
initializeImage();
initializeGrid();
initializePlaceholder();
initializeShadow(); /* 追加 */
initializeRModuleBackground();
isInitializedImages = true;
isUpdatedWeather = updateWeather();
isInitializedWeather = true;
isUpdatedBus = updateBus();
isInitializedBus = true;
isUpdatedGomi = updateGomi();
isInitializedGomi = true;
isUpdatedTwitter = updateTwitter();
isInitializedTwitter = true;
isUpdatedOpenClose = updateOpenClose();
isUpdatedTemperature = updateTemperature();
isUpdatedBrightness = updateBrightness();
updateNowPageID(true);
}
/* 略 */
RModuleのサイズに対応した影を取得
RModuleの描画用関数内では、はじめにサイズを表す変数size
を定義しています。
void drawWeatherRModule(Area area) {
RModule module = RModule.Weather;
Size size = moduleSize(module);
size
にはSize.S
などの変数が入っています。
この変数を使い、すでに作成してあるmoduleShadowS
などの影を取得できるようにしましょう。
関数rmoduleShadowImage()
を定義します。
引数として取得したsize
ごとに、適した大きさの影を返す関数です。
/* 略 */
PGraphics rmoduleShadowImage(Size size) {
if (size == Size.S) return moduleShadowS;
if (size == Size.M) return moduleShadowM;
if (size == Size.L) return moduleShadowL;
return null;
}
rmoduleShadowImage(Size.S)
のようにして、影の画像を取得できるようになりました。
RModuleのうしろに影を描画
今まで実装したRModuleの描画用関数に、影を描画する処理を追記します。
追記が必要な関数は、以下の7つです。
- drawBrightnessWeatherRModule()
- drawBusRModule()
- drawGomiRModule()
- drawOpenCloseRModule()
- drawTwitterRModule()
- drawTemperatureRModule()
- drawWeatherRModule()
追記する場所は、RModuleの幅や高さを取得する処理の直後です。
void drawWeatherRModule(Area area) {
RModule module = RModule.Weather;
Size size = moduleSize(module);
int x = layoutGuideX(area);
int y = layoutGuideY(area);
int w = moduleWidth(size);
int h = moduleHeight(size);
image(rmoduleShadowImage(size), x-SHADOW_PADDING, y-SHADOW_PADDING); /* 追加 */
/* 略 */
影はRModuleの背景より一回り大きいので、20ピクセル分を左上にずらして描画しています。
すべてのRModuleに対して描画処理を追記できたら、プログラムを実行してみてください。
各RModuleに影がついているはずです。
最後に
デジタルサイネージの実装は、これですべて終わりました。
この記事までの20本では、実装する各処理はすべて関数を使って実現しました。
今までの関数を使った実装とは別バージョンで、classを使った実装をしたプログラムも公開しています。
もし別バージョンの実装に興味があれば、ソースコードを覗いてみてください。
お疲れ様でした!