# アイマスハッカソン2024成果
再現シリーズ
---
# 自己紹介
<img width="150" src="https://pbs.twimg.com/profile_images/1819550031143370752/vrfBvT7B_400x400.jpg" />
.ごっち(フリーランスエンジニア)
X: @gggooottto
Bluesky: @yougoto.dev
---
## 自己紹介続き
<img width="150" src="https://pbs.twimg.com/profile_images/1819550031143370752/vrfBvT7B_400x400.jpg" />
#imas_mokumoku 会の主催してます。
- <small>学園アイドルマスター `6DBPWQP6`</small>
- <small>シンデレラガールズスターライトステージ `584226133`</small>
- <small>シャイニーカラーズ SONG for PRISM `W8XF4Q2VX`</small>
<img width="190" alt="image.png (189.4 kB)" src="https://img.esa.io/uploads/production/attachments/10836/2024/10/12/43446/42bcbac2-c00f-4674-bdb8-c2605c6c6c75.png">
---
# アイマスハッカソン2019成果
https://spamltheater-yougoto510.vercel.app/
<img width="300" alt="image.png (15.9 kB)" src="https://img.esa.io/uploads/production/attachments/10836/2024/10/12/43446/fe1c8419-6bac-4831-b687-d18e8bf7623e.png">
---
## (当時の)ミリシタUI
<img width="500" alt="image.png (1.5 MB)" src="https://img.esa.io/uploads/production/attachments/10836/2024/10/12/43446/1d318b8f-64fd-425a-8183-88146602a398.png">
全然メンテしていない。。
---
# 今回の成果物
https://hatsuboshi-logo.pages.dev/
<img width="300" alt="image.png (15.8 kB)" src="https://img.esa.io/uploads/production/attachments/10836/2024/10/12/43446/cc3563ca-18f2-48af-8757-949c9cea4261.png">
---
##
<img width="450" alt="image.png (94.5 kB)" src="https://img.esa.io/uploads/production/attachments/10836/2024/10/12/43446/afe5ed62-8ab3-4e4d-960d-410d15582a08.png">
---
## 学園アイドルマスター: 初星学園のロゴ
---
# ぎじゅつ
- Rust + wasm
- Cloudflare Pages
Rust言語でWASMするためのテンプレートがあります。ありがたや。
wasm-pack rust で検索すると見つかるはず。
https://rustwasm.github.io/docs/wasm-pack/tutorials/hybrid-applications-with-webpack/index.html
---
## 下準備
もくもく会を使って仕込んでいました。
<img width="200" src="https://hackmd.io/_uploads/By0KU2w1Jg.png" />
https://x.com/gggooottto/status/1836752572008558756
---
##
```rs
// browser.rs
use anyhow::{anyhow, Result};
use wasm_bindgen::JsCast;
use web_sys::{Document, HtmlCanvasElement, Window};
pub fn window() -> Result<Window> {
web_sys::window().ok_or_else(|| anyhow!("no window found"))
}
pub fn document() -> Result<Document> {
window()?
.document()
.ok_or_else(|| anyhow!("no document found"))
}
pub fn canvas() -> Result<HtmlCanvasElement> {
document()?
.get_element_by_id("canvas")
.ok_or_else(|| anyhow!("no canvas found"))?
.dyn_into::<HtmlCanvasElement>()
.map_err(|_| anyhow!("failed to cast to HtmlCanvasElement"))
}
pub fn context() -> Result<web_sys::CanvasRenderingContext2d> {
canvas()?
.get_context("2d")
.map_err(|_| anyhow!("Error getting 2d context"))?
.ok_or_else(|| anyhow!("No 2d context found"))?
.dyn_into::<web_sys::CanvasRenderingContext2d>()
.map_err(|element| {
anyhow!(
"Error converting {:#?} to CanvasRenderingContext2d",
element
)
})
}
```
---
##
```rs
// draw.rs
use crate::browser;
pub struct Draw;
pub struct DrawLogo;
impl Draw {
pub fn draw() {
let context = browser::context().unwrap();
DrawLogo::draw_diamond(&context);
DrawLogo::draw_middle_line(&context);
DrawLogo::draw_circle(&context);
DrawLogo::draw_h_in_circle(&context);
DrawLogo::draw_6lines(&context);
DrawLogo::curved_sparkle(&context);
DrawLogo::draw_arc(&context);
DrawLogo::draw_5lines_between_arc(&context);
}
}
impl DrawLogo {
const LINE_WIDTH: f64 = 10.0;
pub fn draw_diamond(context: &web_sys::CanvasRenderingContext2d) {
context.set_line_width(Self::LINE_WIDTH);
context.begin_path();
context.move_to(300.0, 50.0);
context.line_to(50.0, 300.0);
context.line_to(300.0, 550.0);
context.line_to(550.0, 300.0);
context.line_to(300.0, 50.0);
context.close_path();
context.stroke();
}
pub fn draw_middle_line(context: &web_sys::CanvasRenderingContext2d) {
context.set_line_width(Self::LINE_WIDTH);
context.begin_path();
context.move_to(175.0, 175.0);
context.line_to(425.0, 425.0);
context.stroke();
}
pub fn draw_circle(context: &web_sys::CanvasRenderingContext2d) {
context.set_line_width(Self::LINE_WIDTH);
context.begin_path();
context
.arc(168.0, 300.0, 78.0, 0.0, std::f64::consts::PI * 2.0)
.unwrap();
context.stroke();
}
pub fn draw_h_in_circle(context: &web_sys::CanvasRenderingContext2d) {
context.set_line_width(Self::LINE_WIDTH);
context.begin_path();
context.move_to(125.0, 365.0);
context.line_to(125.0, 235.0);
context.move_to(125.0, 300.0);
context.line_to(205.0, 300.0);
context.move_to(205.0, 235.0);
context.line_to(205.0, 365.0);
context.stroke();
}
pub fn draw_6lines(context: &web_sys::CanvasRenderingContext2d) {
let adjust = 127.0;
let gap = 23.0;
context.set_line_width(Self::LINE_WIDTH);
context.begin_path();
context.move_to(405.0, 405.0);
context.line_to(405.0 - adjust, 405.0 + adjust);
context.move_to(405.0 - 1.0 * gap, 405.0 - 1.0 * gap);
context.line_to(405.0 - 1.0 * gap - adjust, 405.0 - 1.0 * gap + adjust);
context.move_to(405.0 - 2.0 * gap, 405.0 - 2.0 * gap);
context.line_to(405.0 - 2.0 * gap - adjust, 405.0 - 2.0 * gap + adjust);
context.move_to(405.0 - 3.0 * gap, 405.0 - 3.0 * gap);
context.line_to(405.0 - 3.0 * gap - adjust, 405.0 - 3.0 * gap + adjust);
context.move_to(405.0 - 4.0 * gap, 405.0 - 4.0 * gap);
context.line_to(405.0 - 4.0 * gap - adjust, 405.0 - 4.0 * gap + adjust);
context.move_to(405.0 - 5.0 * gap, 405.0 - 5.0 * gap);
context.line_to(405.0 - 5.0 * gap - adjust, 405.0 - 5.0 * gap + adjust);
context.stroke();
}
pub fn curved_sparkle(context: &web_sys::CanvasRenderingContext2d) {
context.set_line_width(Self::LINE_WIDTH);
context.set_line_join("bevel");
context.begin_path();
context
.arc(
174.0,
48.5,
125.5,
std::f64::consts::PI * 0.0,
std::f64::consts::PI * 0.5,
)
.unwrap();
context
.arc(
174.0,
300.5,
125.5,
std::f64::consts::PI * 1.5,
std::f64::consts::PI * 2.0,
)
.unwrap();
context
.arc(
425.5,
300.5,
125.5,
std::f64::consts::PI * 1.0,
std::f64::consts::PI * 1.5,
)
.unwrap();
context
.arc(
425.5,
48.5,
125.5,
std::f64::consts::PI * 0.5,
std::f64::consts::PI * 1.0,
)
.unwrap();
context.stroke();
}
pub fn draw_arc(context: &web_sys::CanvasRenderingContext2d) {
context.set_line_width(Self::LINE_WIDTH);
context.begin_path();
context
.arc(
492.0,
365.0,
85.0,
std::f64::consts::PI * 0.75,
std::f64::consts::PI * 1.75,
)
.unwrap();
context.stroke();
}
pub fn draw_5lines_between_arc(context: &web_sys::CanvasRenderingContext2d) {
context.set_line_width(Self::LINE_WIDTH);
context.begin_path();
context.move_to(390.0, 180.0);
context.line_to(390.0 + 100.0, 180.0 + 100.0);
context.move_to(360.0, 190.0);
context.line_to(360.0 + 100.0, 190.0 + 100.0);
context.move_to(337.0, 207.0);
context.line_to(337.0 + 100.0, 207.0 + 100.0);
context.move_to(320.0, 230.0);
context.line_to(320.0 + 98.0, 230.0 + 98.0);
context.move_to(308.0, 262.0);
context.line_to(308.0 + 100.0, 262.0 + 100.0);
context.stroke();
}
}
```
---
##
```rs
// lib.rs
#[macro_use]
mod browser;
mod draw;
use draw::Draw;
use wasm_bindgen::prelude::*;
use web_sys::console;
#[wasm_bindgen(start)]
pub fn main_js() -> Result<(), JsValue> {
// This provides better error messages in debug mode.
// It's disabled in release mode so it doesn't bloat up the file size.
#[cfg(debug_assertions)]
console_error_panic_hook::set_once();
// Your code goes here!
console::log_1(&JsValue::from_str("Hello world!"));
Draw::draw();
Ok(())
}
```
---
# 苦労した点
---
## 見よう見まねで再現した!
以上!
Rustっぽい難しさは無かった。
---
# ...
---
## 本物
https://gakuen.idolmaster-official.jp/assets/img/common/logo_text.svg
<img src="https://gakuen.idolmaster-official.jp/assets/img/common/logo_text.svg" />
---
##
<img src="https://gakuen.idolmaster-official.jp/assets/img/common/logo_text.svg" />
<img width="300" alt="image.png (80.2 kB)" src="https://img.esa.io/uploads/production/attachments/10836/2024/10/12/43446/34adde6a-ec1e-459b-91d3-b995e9bdaa7b.png">
---
##
<img width="300" alt="diff.png (39.2 kB)" src="https://img.esa.io/uploads/production/attachments/10836/2024/10/12/43446/7d180c2e-4e28-4d5b-aa4d-3de794db4e03.png">
- 黒色が今回つくったもの
- 灰色が重なったもの(本物に不透明度50%重ねたもの)
- 白色が本物
---
## うーん
<img width="300" alt="diff.png (39.2 kB)" src="https://img.esa.io/uploads/production/attachments/10836/2024/10/12/43446/7d180c2e-4e28-4d5b-aa4d-3de794db4e03.png">
中らずと雖も遠からず
見よう見まねで作ったわりにはよかったのでは。
---
## ちゃんとやるなら
本物のSVGを解析するべし
https://gakuen.idolmaster-official.jp/assets/img/common/logo_text.svg
```svg
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300">
<path fill-rule="evenodd" fill="#FFF" d="
M299.1 141.522l-7.472 8.373-1.412-1.411 1.838-9.967-5.902 5.902-1.412-1.412 8.372-8.372 1.558 1.558-1.862 9.699 5.78-5.781.512 1.411z
m-13.604-12.069l-2.202 2.202 3.005 3.006-1.217 1.217-3.006-3.006-2.518 2.519 3.723 3.724-1.217 1.217-5.305-5.306 8.372-8.372 5.123 5.123-1.217 1.217-3.541-3.541z
m-11.681.951c-1.193.096-2.434-.439-3.638-1.643-1.132-1.133-1.74-2.374-1.631-3.627.122-1.46 1.119-2.458 1.825-3.164l5.038-5.038 1.607 1.606-5.294 5.294c-1.18 1.18-1.704 2.385-.243 3.845 1.46 1.461 2.665.937 3.845-.243l5.294-5.294 1.399 1.4-5.038 5.038c-.706.706-1.704 1.703-3.164 1.826z
m-9.027-7.349l-1.984-1.984.901-7.812-4.357 4.356-1.606-1.606 8.372-8.372 1.606 1.606-3.809 3.809 7.289-.328 1.717 1.715-7.253.195-.876 8.421z
m-10.963-10.962l1.363-2.702-3.164-3.164-2.726 1.339-1.46-1.461 11.39-5.354 1.716 1.716-5.403 11.341-1.716-1.715z
m4.515-8.969l-4.722 2.312 2.361 2.36 2.361-4.672z
m-5.925-6.29s-.548-1.229-1.655-2.337c-1.85-1.849-3.906-1.983-6 .11-2.105 2.105-2.044 4.235-.45 5.828a5.28 5.28 0 001.192.901l2.045-2.045-1.46-1.459 1.192-1.193 3.03 3.03-4.125 4.125s-1.557-.681-3.067-2.19c-2.603-3.504-3.054-5.707-.158-8.604 2.969-2.969 6.207-2.482 8.944.256 1.23 1.229 1.863 2.422 1.863 2.422l-1.254 1.253-.097-.097z
m-22.11-8.261l8.372-8.372 1.607 1.606-8.373 8.372-1.606-1.606z
m-4.72-4.72l3.736-3.736-3.602-3.602-3.736 3.736-1.606-1.606 8.372-8.373 1.606 1.607-3.419 3.419 3.602 3.602 3.419-3.42 1.607 1.607-8.372 8.372-1.607-1.606z
m-1.459-15.332s-.645-1.399-1.557-2.312c-.913-.912-1.728-.973-2.288-.413-1.631 1.63 2.568 5.001-.219 7.787-1.655 1.656-3.797 1.12-5.695-.778-1.302-1.302-1.825-2.58-1.825-2.58l1.253-1.253.085.085s.669 1.643 1.68 2.653c.949.949 1.934 1.083 2.616.401 1.752-1.752-2.434-5.135.207-7.776 1.448-1.448 3.419-1.181 5.293.694a10.18 10.18 0 011.752 2.385l-1.205 1.205-.097-.098z
m-18.361-4.172c-2.556-2.556-2.252-5.61.389-8.251 2.689-2.689 5.792-2.945 8.348-.389 2.555 2.555 2.251 5.61-.39 8.25-2.689 2.689-5.792 2.945-8.347.39z
m7.52-7.472c-1.46-1.46-3.298-1.205-5.403.901-2.105 2.105-2.361 3.942-.901 5.403 1.461 1.46 3.299 1.204 5.404-.901s2.36-3.943.9-5.403z
m-10.914-5.194s1.911 2.056-.085 4.051c-.961.962-2.02 1.12-3.005.889-1.205-.28-2.057-1.131-2.775-1.849l-2.824-2.824 8.373-8.372 2.799 2.799c.754.754 1.375 1.399 1.63 2.361.232.888.037 1.763-.779 2.579-1.691 1.692-3.334.366-3.334.366z
m-3.383-1.899l-2.604 2.604 1.205 1.205c.292.292.779.779 1.448.961.608.17 1.144 0 1.63-.486.548-.548.646-1.084.487-1.656-.182-.644-.596-1.058-.986-1.447l-1.18-1.181z
m5.294-1.351c-.134-.475-.463-.827-.779-1.143l-1.01-1.01-2.288 2.287 1.01 1.01c.341.341.645.645 1.132.791.474.134.998.049 1.484-.438.487-.487.584-1.022.451-1.497z
m-13.543-1.105c-1.193.096-2.434-.439-3.638-1.643-1.132-1.132-1.74-2.373-1.631-3.627.122-1.46 1.119-2.458 1.825-3.164l5.038-5.038 1.607 1.607-5.294 5.293c-1.18 1.181-1.704 2.385-.244 3.845 1.461 1.461 2.666.937 3.846-.243l5.293-5.293 1.4 1.399-5.038 5.038c-.706.706-1.704 1.704-3.164 1.826z
m-3.029-15.222s-.645-1.4-1.557-2.313c-.913-.912-1.728-.973-2.288-.413-1.631 1.63 2.568 5.001-.219 7.788-1.655 1.655-3.797 1.119-5.695-.779-1.302-1.302-1.825-2.579-1.825-2.579l1.253-1.254.085.085s.669 1.643 1.679 2.653c.95.949 1.935 1.083 2.617.401 1.752-1.752-2.434-5.135.207-7.776 1.448-1.448 3.419-1.18 5.293.694a10.202 10.202 0 011.753 2.385l-1.205 1.205-.098-.097z
m-9.088-9.479l-7.131 7.131-1.607-1.606 7.131-7.131-2.324-2.325 1.241-1.241 6.243 6.243-1.242 1.241-2.311-2.312z
m-13.519.744l1.363-2.702-3.164-3.164-2.726 1.339-1.46-1.46 11.39-5.355 1.716 1.716-5.403 11.342-1.716-1.716z
m4.515-8.969l-4.722 2.312 2.361 2.361 2.361-4.673z
m-14.31-.826l3.736-3.735-3.601-3.602-3.736 3.736-1.607-1.607 8.373-8.372 1.606 1.606-3.419 3.419 3.601 3.602 3.42-3.419 1.606 1.607-8.372 8.372-1.607-1.607z
m125.374 142.527l2.369 2.37L141.524 299.1 32.181 190.657l-.02-.018-.018-.019-32.147-32.147 32.158-32.158.007-.008a.057.057 0 00.008-.007L141.524 16.946l139.157 139.157h.001zM141.524 291.422l64.33-64.33-8.577-8.577-64.331 64.33 8.578 8.577z
m32.522-187.658a65.68 65.68 0 00-8.052 6.272l43.999 43.999a50.982 50.982 0 018.319-6.005l-44.266-44.266z
m49.996 41.417a51.783 51.783 0 0111.022-3.301l-45.612-45.613a65.548 65.548 0 00-10.015 4.309l44.605 44.605z
m-62.337-30.857a66.063 66.063 0 00-6.263 8.06l44.232 44.232a51.796 51.796 0 016.023-8.3l-43.992-43.992z
m33.167 93.208a51.718 51.718 0 01-2.198-14.974c0-.477.023-.951.035-1.426l-46.611-46.611a65.284 65.284 0 00-1.511 12.727l50.285 50.284z
m-1.364-24.178a51.156 51.156 0 013.287-11.038l-44.556-44.556a65.43 65.43 0 00-4.299 10.026l45.568 45.568z
m-.52 30.872l-8.577-8.577-64.331 64.33 8.577 8.577 64.331-64.33z
m-77.197 51.464l64.33-64.33-8.576-8.577-64.331 64.33 8.577 8.577z
m-12.866-12.866l64.33-64.33-8.576-8.577-64.331 64.33 8.577 8.577z
m-12.867-12.867l64.331-64.329-8.577-8.577-64.33 64.33 8.576 8.576z
m-12.866-12.866l64.331-64.329-8.577-8.577-64.33 64.33 8.576 8.576z
m15.011-96.494a39.946 39.946 0 00-3.616-3.191v62.134a40.002 40.002 0 003.606-3.181l.01-.01c15.371-15.371 15.371-40.382 0-55.752z
m-27.877 83.628l11.819-11.818a45.713 45.713 0 01-23.637 0l11.818 11.818z
m-18.195-20.766c5.552 2.896 11.754 4.437 18.195 4.437 6.442 0 12.644-1.541 18.196-4.437v-31.954H46.131v31.954zM8.573 158.473l11.861 11.86a45.803 45.803 0 010-23.721L8.573 158.473z
m31.493-31.067a39.793 39.793 0 00-3.616 3.191c-15.371 15.37-15.371 40.379-.002 55.75l.004.004a40.036 40.036 0 003.614 3.189v-62.134z
m6.065 28.034h36.391v-31.953c-5.552-2.896-11.754-4.438-18.196-4.438-6.441 0-12.643 1.542-18.195 4.438v31.953z
m6.376-40.901a45.724 45.724 0 0111.819-1.554c12.151 0 23.574 4.731 32.166 13.323 11.907 11.907 15.807 28.824 11.727 44.026l20.438-20.438-55.753-55.753-20.397 20.396z
m85.504 36.133c-3.566-29.938-27.367-53.739-57.305-57.305l57.305 57.305zM80.706 86.341c29.938-3.567 53.739-27.367 57.305-57.305L80.706 86.341z
m12.848 3.513c22.932 6.914 41.055 25.037 47.97 47.968 6.914-22.931 25.037-41.054 47.968-47.968-22.931-6.914-41.054-25.038-47.968-47.969-6.915 22.931-25.038 41.055-47.97 47.969z
m51.482-60.818c3.567 29.938 27.367 53.738 57.305 57.305l-57.305-57.305z
m63.882 63.882a65.45 65.45 0 00-12.741 1.498l46.651 46.651a51.78 51.78 0 0116.433 2.193l-50.343-50.342z
m3.144 67.475c-17.091 17.09-17.706 44.506-1.857 62.348l64.206-64.206c-17.841-15.847-45.257-15.233-62.349 1.858z
" />
</svg>
```
<img src="https://gakuen.idolmaster-official.jp/assets/img/common/logo_text.svg" />
---
# 時間が余ってたら
親愛度10のアイドルコミュのあとに流れる特別な演出のあれを作る予定だった。
---
## これ
![](https://gyazo.com/4ca4fa5ca6b9033f67ff10ed6a484314/max_size/1000)
---
## 時間が余ってたら。。。?
---
## もくもく会やります!!
<img width="1608" alt="image.png (251.1 kB)" src="https://img.esa.io/uploads/production/attachments/10836/2024/10/12/43446/c97d030d-584f-4f3b-a1cd-6990eea6ca81.png">
https://imastudy-mokumoku.connpass.com/event/334074/
<img width="450" alt="image.png (15.8 kB)" src="https://img.esa.io/uploads/production/attachments/10836/2024/10/12/43446/19789474-f6a2-4756-93fb-e1fc76f83c93.png">
---
# ありがとー
<img width="300" alt="image.png (2.0 MB)" src="https://img.esa.io/uploads/production/attachments/10836/2024/10/12/43446/ddce4e3b-1e3f-4ad1-9281-c4b895e6d260.png">
{"title":"アイマスハッカソン2024成果","description":"x","contributors":"[{\"id\":\"f26931b8-9746-4995-86b6-93cc66349b27\",\"add\":51388,\"del\":34035}]"}