feature image

2026年7月22日 | ブログ記事

躍動写真アプリ「shaQ」 2026 年春ハッカソン 02 班

作ったもの

今回の春ハッカソンのテーマである「かん」「きゅう」。私たちは、写真における「緩急(かんきゅう)」と、撮影という「瞬“間”(かん)」の取り方に焦点を当て、traPの伝統文化である「躍動」の写真を“簡”単に撮影・共有できるSNS「shaQ(シェイク)」を開発しました!

そもそも躍動とは

traP部内で語り継がれる「躍動(yakudo)」とは、以下のような意味で使われます。

スマホで写真を撮る際、シャッターを押す瞬間にカメラを前後に勢いよく振ることによって、手動で得ることのできる(放射状の)ブラーの演出のこと(下の写真を参考)。まるで集中線をおいたかのような存在感、躍動感が見る者の草:w:を誘う!アプリなどを使うことなく手軽に躍動感を演出できる一方で、綺麗な放射状のブラーを得るには、カメラを振るタイミングやその角度を適切に制御する必要があり、見た目以上に難しい。そのため、美しく大胆な躍動感を演出するにはそれなりの熟練が必要になる。一発撮りが美徳とされているらしい。
-traP wiki Dictionaryより

(参考 : あなたの知らない躍動の世界 )

躍動写真の例

現代における課題

しかし、現代においてこの文化を実践しようとすると、様々な「課題」に直面します。

shaQでできること

shaQは、特別な技術を必要とせず、誰でも“簡単”に躍動写真を撮影できるWebアプリです。

shaQ 撮影時の画像

shaQ が動作する様子

shaQ タイムラインの画像

技術的概要

フロントエンド

フレームワークにはVueを使用し、Vue Router を用いてSPA(リロードを伴わないページ遷移)として実装した以外は、ほぼバニラという感じの構成になっています。これは 決して事前に技術スタックの検討をする時間が取れなかったからではなく、 部内で開催される「Webエンジニアになろう講習会」で採用されている構成との差異をなるべく小さくして開発初心者の壁を低くすることが目的です。

shaQのフロントエンドで特筆すべき点は、やはりアプリの機能の核を満たすためにハードウェア(デバイス)のカメラやセンサーの値を複数種類活用しているところです。

カメラへのアクセス

まず、写真投稿アプリとしてのshaQは当然デバイスのカメラにアクセスする必要があります。そこでWebアプリからカメラにアクセスするアプローチについて調べたところ、主に次に述べる2通りの方法があり、それぞれに長短があるということがわかりました。

デバイスに備わるカメラシステムを使用する方法

ブラウザでチャットツールなどを開いて利用すると、送信ボタンの近くに写真を撮影するボタンがついていることがあり、ブラウザからカメラを起動させることができます。このボタンは次のような input 要素として表現されます。

<input type="file" accept="image/*" capture="enviroment" />

これを用いて、次のような手順でWebアプリからカメラを起動し、ユーザーに写真を撮影させて利用することができます。

  1. 要素をタップしてデバイスのカメラを起動
  2. デバイスに備わるカメラシステムで写真を撮影
  3. ユーザーが撮影結果について決定操作をしたのち、アプリ側に制御が戻ってくる

この方法には、撮影部分を信頼できるデバイスのカメラシステムに丸投げすることで、導入が容易、バグを減らせる、さらに写真の画質もよくなるといった様々なメリットがあります。ただ一点 撮影中にアプリが一切介入できない というデメリットを重く見て、shaQでは次に述べる方法を採用することにしました。

カメラの映像をページ上にリアルタイムで映す方法

onMounted(async () => {
  videoRef.value.srcObject = navigator.mediaDevices.getUserMedia(constraints)
})

これを記述したコンポーネントが読み込まれると、自動的にユーザーに対してブラウザ上でカメラの使用許可が求められ、ユーザーが許可すればWebアプリはカメラの動画をページ上に写しながら使用することができます。MeetのようなWeb会議ツールにもおそらく同様の権限が与えられているはずです。

  1. ページ上にカメラの動画を映す
  2. 撮影ボタンを用意し、押されたタイミングでページ上の動画部分をキャプチャ

これならアプリが常に制御を保っているので、撮影ボタンを押した瞬間に次のページへ遷移したりできます。手順が一つ減り、ユーザー体験は向上します。ところで、ページ上の限られた領域をキャプチャするわけなので、得られる写真はふつう500KBに満たない小さくて画質の悪いものになります。しかしshaQに限っては結局ぼかし加工を施すことになるので撮影直後の写真の画質の良し悪しはほとんど問題になりません。むしろ、画像サイズの小ささが読み込みにかかる時間を短縮し、ユーザー体験にプラスの影響を与えることになりました。

加速度・角速度センサーへのアクセス

shaQはその読み方(シェイク)の通り「振る」ことによって撮影した写真にぼかし加工を加えていきます。デバイスが振られていることを検知するには、デバイスの加速度・角速度センサーにアクセスして値を監視する必要があります。

ちなみに本番コードでは開発のてんてこ舞いの中でなぜか acceleration ではなく accelerationIncludingGravity の方が使われてしまっているのですが、重力加速度が手でデバイスを振る速度より小さかったおかげか、とくに誤検知らしきものはなく、振った分だけ画像がブレるという素直な挙動を見せてくれています。

画像のぼかし加工

ぼかし加工そのものは canvas 要素 に半透明な画像をたくさん重ねていくことで表現しています。画像を重ねながら拡大していけば放射ぼかしを、縦横に移動させていけばモーションぼかしを表現することができます。

Photo taken by Blessing Ri from Unsplash

さて、躍動のステレオタイプは写真に放射ぼかしをかけることで表現されますが、概念実証の段階で様々な画像に放射ぼかしをかけてみた結果「なんとなくつまらない」という感想を抱きました。おそらく原因は

といったことにあったのだろうと思います。

躍動には様々な種類があります。ベーシックな放射ぼかしの躍動のみならず、被写体が移動しているように写るモーション躍動、被写体が回転しているように写るローリング躍動など色々あり、これらの合わせ技もあり、それがゆえのカオスが評価され、躍動という文化を今日まで存えさせてきました。この表現の多様性をshaQが反映しないわけにはいきません。

議論の結果、開発の途中で acceleration の情報に加えて rotationRate の情報を合わせた6自由度を全て用いてぼかし加工を調整するという方針に切り替えました。shaQの完成披露後にユーザーによって投稿されるたくさんの写真はさながら従来のやり方(デバイスを振りながらシャッターボタンを押す)で撮影したかのように見事にてんでばらばらな躍動をしていて、この方針に切り替えた判断を強く肯定するものでした。

バックエンド

Go で書いています。サーバーのライブラリは Echo 、DB へのクエリには sqlx を使っています。例年通り Web エンジニアになろう講習会と同じ構成です。

shaQ の通常のアプリとは異なる部分は、画像を扱う必要がある点です。今回は、部内のオブジェクトストレージに画像データを保存しました。画像を配信する際は、サーバーアプリで直接配信するとアプリ側の帯域と CPU を消費してしまうことが考えられたので、アプリはオブジェクトストレージ上の画像の Presigned URL をレスポンスで返し、フロントエンドには直接オブジェクトストレージにアクセスしてもらいました。今度はオブジェクトストレージ側の帯域が足りるか心配でしたが、ハッカソンの試遊期間でも問題なく動きました。もっとアクセスが増える場合は CDN を噛ませるなどの工夫が必要になると思います。

感想

hachimitsu

バックエンドを担当しました。1年生の時に、春ハッカソン、ワンマンソン、冬ハッカソンとWebで参加してきましたが、少しずつできることが増えてきて成長を感じました。今回では、ワンマンソンの時にはうまくできなかったNeoShowcaseの認証部分を初めて実装しました。この調子で一歩ずつできることを増やしていきたいです。

haruki_0920

初めてのハッカソンでしたが、とても楽しむことができました!プログラミングの経験も浅く心配も多かったですが、02班の皆さんが優しく教えてくださったのでなんとかやり切ることができました。この経験を糧にしてこれからも自分のスキルを磨きつつ開発を頑張っていきたいと思います!

ikura-hamu

リーダーをしました。今回は自分はあまり実装に手を回さず、他のメンバーに実装を頑張って自分はレビューなどをしました。いきなり一番難しそうな仕事を割り振ってしまうなどして、失敗したなと思いました。メンバー全員が頑張ってくれて、最終的に完成したので良かったです。

kaomojikun

ハッカソンにWebで参加するのは二回目ですが、昨年度はフロントエンドとして、参加させていただいたので、バックエンドを担当するのは初めてでした。アイデア出しの際に、お題に沿った面白い案がたくさん出てきて、楽しかったです!これを機にフロントエンドもバックエンドもどちらも頑張っていきたいです!!

kitsne

shaQはカメラや加速度といったハードウェアの情報と密に連携するWebアプリであり、私には類するWebアプリの実装経験がなかったので、この部分の調査と実装をねこりせくんとはるきくんにお願いすることにしました。結果としてハッカソン開始直後から全員にタスクがある状態になってよかったと思っています。例によって最後に駄目を詰める作業が遅滞して危なかったですが、なんとか完成に漕ぎつけられてよかったです。

neko_reset1024

初参加のハッカソンで、web開発ほぼ未経験の状態で参加させてもらいました。アイデア出しの段階では、漠然とした実装への不安がありましたが、先輩方のお陰で仕事をもらえ、自分の担当したところは形にはできたと思います(issueは先輩方に:solved:してもらいました)。当たり前に思っていたSNSの機能の実装を、納得できるクオリティにまで持っていくのにはこんなに労力がいるんだと思い知らされました。今後のイベントにも参加したいので、今回の実装を振り返りつつ経験を積んでいきます。

ikura-hamu icon
この記事を書いた人
ikura-hamu

SysAd班、ゲーム班 いろいろやりたい

kitsne icon
この記事を書いた人
kitsne

24B / Web開発 ボカロ イラストなど

kaomojikun icon
この記事を書いた人
kaomojikun

hachimitsu icon
この記事を書いた人
hachimitsu

neko_reset1024 icon
この記事を書いた人
neko_reset1024

haruki_0920 icon
この記事を書いた人
haruki_0920

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2021年8月12日
CPCTFを支えたWebshell
mazrean icon mazrean
2021年5月19日
CPCTF2021を実現させたスコアサーバー
xxpoxx icon xxpoxx
2026年2月4日
2025年度 1-Monthon 12 班: 総合進捗環境『Progres』
uni_kakurenbo icon uni_kakurenbo
2026年2月2日
2025年度冬ハッカソン 16班 部内経済基盤『Plutus』
o_o icon o_o
2024年6月21日
ハッカソン参加記 4班"Slide Center"
Alt--er icon Alt--er
2024年3月15日
個人開発として2週間でWebサービスを作ってみた話 〜「LABEL」の紹介〜
Natsuki icon Natsuki
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記