0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Bラボデジタルサイネージ20】RModuleの影を実装

Last updated at Posted at 2021-11-14

本記事は、株式会社 函館ラボラトリが運営する「Bラボ」における、大人向け「看板アプリ(デジタルサイネージ)を作るコース」用教材テキストです。

  1. 【Bラボデジタルサイネージ1】Processing+ラズパイでデジタルサイネージを作る!
  2. 【Bラボデジタルサイネージ2】ラズパイ初期設定
  3. 【Bラボデジタルサイネージ3】準備プログラム作成&機能実現の方針決定
  4. 【Bラボデジタルサイネージ4】レイアウトの基準になるグリッドを表示する「GridModule」
  5. 【Bラボデジタルサイネージ5】レイアウトの基準になる枠を表示する「PlaceholderModule」
  6. 【Bラボデジタルサイネージ6】画像を全画面表示する「FullImageModule」
  7. 【Bラボデジタルサイネージ7】ページの自動切り替え
  8. 【Bラボデジタルサイネージ8】設置されている場所の名前を表示する「LocationModule」
  9. 【Bラボデジタルサイネージ9】現在の時間を表示する「DateModule」
  10. 【Bラボデジタルサイネージ10】ページ切り替えの時間が分かる「ProgressBarModule」
  11. 【Bラボデジタルサイネージ11】現在の表示中のページが分かる「PageControlModule」
  12. 【Bラボデジタルサイネージ12】現在の天気を表示する「WeatherRModule」
  13. 【Bラボデジタルサイネージ13】直近2件のバス時刻表を表示する「BusRModule」
  14. 【Bラボデジタルサイネージ14】ごみ出しカレンダーを表示する「GomiRModule」
  15. 【Bラボデジタルサイネージ15】(発展編)ツイートを表示する「TwitterRModule」
  16. 【Bラボデジタルサイネージ16】開店/閉店を表示する「OpenCloseRModule」
  17. 【Bラボデジタルサイネージ17】部屋の温度を表示する「TemperatureRModule」
  18. 【Bラボデジタルサイネージ18】部屋の明るさを表示する「BrightnessRModule」
  19. 【Bラボデジタルサイネージ19】起動画面を表示する「LaunchingScreenModule」
  20. 【Bラボデジタルサイネージ20】RModuleの影を実装(本記事)

作るもの

今まで実装してきた「WeatherRModule」などの「RM」に分類されるモジュールの後ろに、薄い影を描画します。

影がある状態

0041.png

影がない状態

0017.png

影がある状態

0145.png

影がない状態

0021.png

影の作り方

RModuleのうしろに影を描画します。
影を作るには、RModuleの背景画像と同じように、PGraphicsを使います。
生成する影は下図のようなものです。

211114_201043_124.png

この影は、灰色の角丸四角をぼかしたものです。
影の手前に、例としてTemperatureRModule用の背景を描画してみます。

211114_202009_301.png

影のほうが一回り大きいので、RModuleの背景のうしろから、うっすらと灰色がにじんでいます。

このようにして、各RModuleに影をつけます。

影の画像を生成

影に関連する変数を定義します。

DigitalSignage.pde
/* 略 */

// 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()を新しくつくります。

Initialize.pde
/* 略 */

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()内で呼び出すようにしておきましょう。

Initialize.pde
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ごとに、適した大きさの影を返す関数です。

DigitalSignage.pde
/* 略 */

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の幅や高さを取得する処理の直後です。

RM_Weather.pde
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に影がついているはずです。

0041.png

0145.png

最後に

デジタルサイネージの実装は、これですべて終わりました。

この記事までの20本では、実装する各処理はすべて関数を使って実現しました。
今までの関数を使った実装とは別バージョンで、classを使った実装をしたプログラムも公開しています。
もし別バージョンの実装に興味があれば、ソースコードを覗いてみてください。

お疲れ様でした!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?