|
<!DOCTYPE html> |
|
<html lang="ja"> |
|
|
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<!-- Google Tag Manager --> |
|
<script> |
|
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': |
|
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], |
|
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= |
|
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); |
|
})(window,document,'script','dataLayer','GTM-PJXRKX3F'); |
|
</script> |
|
<!-- End Google Tag Manager --> |
|
<title>Scratch for school</title> |
|
<script src="https://unpkg.com/alpinejs@3.14.9/dist/cdn.min.js" defer></script> |
|
<link href="https://fonts.googleapis.com/css2?family=Yomogi&display=swap" rel="stylesheet"> |
|
<style> |
|
:root { |
|
--primary-color: |
|
--primary-hover: |
|
--accent-color: |
|
--text-color: |
|
--bg-color: |
|
--card-bg: |
|
--border-color: |
|
--shadow: 0 4px 6px rgba(0, 0, 0, 0.1); |
|
--transition: all 0.3s ease; |
|
--scrollbar-features: |
|
--scrollbar-video: |
|
} |
|
|
|
|
|
body { |
|
scrollbar-width: none; |
|
-ms-overflow-style: none; |
|
overflow-x: hidden; |
|
} |
|
body::-webkit-scrollbar { |
|
display: none; |
|
} |
|
|
|
.scroll-progress { |
|
position: fixed; |
|
top: 0; |
|
left: 0; |
|
width: 0; |
|
height: 3px; |
|
background: linear-gradient(90deg, var(--scrollbar-features) 0%, var(--scrollbar-video) 100%); |
|
z-index: 1000; |
|
transition: width 0.1s ease-out; |
|
} |
|
|
|
body { |
|
margin: 0; |
|
padding: 0; |
|
font-family: 'Yomogi', cursive; |
|
background-color: var(--bg-color); |
|
color: var(--text-color); |
|
line-height: 1.6; |
|
scroll-behavior: smooth; |
|
} |
|
|
|
|
|
.fixed-header { |
|
position: fixed; |
|
top: -100px; |
|
left: 0; |
|
width: 100%; |
|
background-color: rgba(255, 255, 255, 0.9); |
|
box-shadow: var(--shadow); |
|
z-index: 999; |
|
transition: top 0.3s ease; |
|
display: flex; |
|
justify-content: center; |
|
padding: 10px 0; |
|
} |
|
|
|
.fixed-header.visible { |
|
top: 0; |
|
} |
|
|
|
.fixed-header .buttons { |
|
margin: 0; |
|
} |
|
|
|
|
|
.header-container { |
|
position: relative; |
|
width: 100%; |
|
height: 100vh; |
|
overflow: hidden; |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
text-align: center; |
|
} |
|
|
|
.header-video { |
|
position: absolute; |
|
top: 0; |
|
left: 0; |
|
width: 100%; |
|
height: 100%; |
|
object-fit: cover; |
|
z-index: -1; |
|
filter: brightness(0.5); |
|
} |
|
|
|
.header-content { |
|
position: relative; |
|
z-index: 1; |
|
color: white; |
|
padding: 2rem; |
|
max-width: 800px; |
|
margin: 0 auto; |
|
} |
|
|
|
|
|
.video-scroll-section { |
|
position: relative; |
|
width: 100%; |
|
height: 100vh; |
|
overflow: hidden; |
|
} |
|
|
|
.scroll-video { |
|
position: fixed; |
|
top: 0; |
|
left: 0; |
|
width: 100%; |
|
height: 100%; |
|
object-fit: cover; |
|
z-index: -1; |
|
} |
|
|
|
|
|
|
|
|
|
</style> |
|
</head> |
|
|
|
<body> |
|
<!-- カスタムスクロールバー --> |
|
<div class="scroll-progress" id="scrollProgress"></div> |
|
|
|
<!-- 固定ヘッダー --> |
|
<div class="fixed-header" id="fixedHeader"> |
|
<div class="buttons"> |
|
<a href="https://soiz1-s4s-editor.hf.space/editor.html" target="_blank">→エディターを開く</a> |
|
<a href="#features">→機能一覧</a> |
|
<a href="#video">→紹介動画</a> |
|
</div> |
|
</div> |
|
|
|
<!-- ローディングアニメーション --> |
|
<div class="loading-overlay" id="loadingOverlay"> |
|
<div class="loader"></div> |
|
</div> |
|
|
|
<!-- Google Tag Manager (noscript) --> |
|
<noscript> |
|
<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PJXRKX3F" height="0" width="0" style="display:none;visibility:hidden"> |
|
</iframe> |
|
</noscript> |
|
<!-- End Google Tag Manager (noscript) --> |
|
|
|
<!-- ヘッダーセクション with ビデオ背景 --> |
|
<div class="header-container"> |
|
<video autoplay muted loop class="header-video"> |
|
<source src="https://huggingface.co/datasets/soiz1/scratch-for-school/resolve/main/vi.mp4?download=true" type="video/mp4"> |
|
<!-- ビデオがサポートされていない場合のフォールバック --> |
|
Your browser does not support the video tag. |
|
</video> |
|
<div class="header-content"> |
|
<h1><img src="https://huggingface.co/datasets/soiz1/scratch-for-school/raw/main/logo-text.svg"></img></h1> |
|
<p class="description">学校の一人一台端末用にカスタマイズされたScratch。Googleドライブへの保存機能やプロジェクトの共有、カスタマイズされた便利なエディターや高度なブロック、画像分類やフェイストラッキング、ハンドトラッキング、ポーズ認識の拡張機能などの様々な追加機能</p> |
|
<div class="buttons"> |
|
<a href="https://soiz1-s4s-editor.hf.space/editor.html" target="_blank">→エディターを開く</a> |
|
<a href="#features">→機能一覧</a> |
|
<a href="#video">→紹介動画</a> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<!-- スクロール連動ビデオセクション --> |
|
<div class="video-scroll-section" id="videoScrollSection"> |
|
<video muted class="scroll-video" id="scrollVideo"> |
|
<source src="https://huggingface.co/datasets/soiz1/scratch-for-school/resolve/main/vi2.mp4?download=true" type="video/mp4"> |
|
Your browser does not support the video tag. |
|
</video> |
|
</div> |
|
|
|
|
|
<section id="features"> |
|
<h2>機能一覧</h2> |
|
|
|
<div class="feature-list"> |
|
<li>プロジェクトの保存・共有</li> |
|
<ul> |
|
<li>プロジェクトをGoogleドライブに保存</li> |
|
<li>特定の人とだけの共有</li> |
|
<li>プロジェクトの短縮URLの作成</li> |
|
<li>プラットフォームへの共有</li> |
|
</ul> |
|
</div> |
|
|
|
<div class="feature-list"> |
|
<li>カスタマイズされたエディター</li> |
|
<ul> |
|
<li>オフスクリーンレンダリングによる高速化</li> |
|
<li>フォルダにプロジェクトを保存</li> |
|
<li>フォルダをZIPとして読み込む</li> |
|
<li>ライトテーマとダークテーマ</li> |
|
<li>デバイスのフォントの使用とカスタムフォントを使用した文字の作成</li> |
|
<li>文字の位置を設定</li> |
|
<li>新しい背景とコスチュームとサウンド</li> |
|
<li>背景、コスチューム、サウンドの検索</li> |
|
<li>カラーピッカーの透明度の設定</li> |
|
<li>変数とリストを分離</li> |
|
<li>拡張機能の検索とカテゴリー別のフィルター</li> |
|
<li>値を返したり色をカスタマイズしたりできるブロック定義</li> |
|
<li>部位同士の重なった部分の抽出・削除</li> |
|
<li>100個を超える新しいブロック</li> |
|
<li>高度な設定</li> |
|
<ul> |
|
<li>ステージのサイズを変更</li> |
|
<li>FPS設定</li> |
|
<li>ペンできれいに描画する</li> |
|
<li>ワープタイマー</li> |
|
<li>クローン、動く範囲と大きさなどの制限を解除</li> |
|
<li>オフスクリーンレンダリングの有効・無効化</li> |
|
</ul> |
|
</ul> |
|
</div> |
|
|
|
<div class="feature-list"> |
|
<li>100個を超える拡張機能</li> |
|
|
|
<button class="toggle-button" aria-expanded="false" aria-controls="moreExtensions">もっと見る</button> |
|
<div id="moreExtensions" class="expandable-content"> |
|
<ul> |
|
<li>独自の拡張機能の読み込み</li> |
|
<li>画像内のオブジェクトの認識</li> |
|
<li>ハンドトラッキング</li> |
|
<li>フェイストラッキング</li> |
|
<li>高精度な画像認識AIを作成</li> |
|
<li>プロジェクト内で画像認識AIの学習と認識</li> |
|
<li>ポーズ認識</li> |
|
<li>p5.jsによるアートノイズ生成</li> |
|
<li>ステージ内のカメラ移動</li> |
|
<li>ファイルのアップロード</li> |
|
<li>ZIPを編集</li> |
|
<li>高度なペン</li> |
|
<li>音声のグループ化</li> |
|
<li>複雑なオーディオ操作とエフェクト</li> |
|
<li>音の作成</li> |
|
<li>動き、イベント、制御、演算カテゴリーの拡張</li> |
|
<li>更に高度な定義ブロック</li> |
|
<li>コメントの拡張</li> |
|
<li>JSON配列の制御</li> |
|
<li>Swift JSONの制御</li> |
|
<li>パーティクルの作成</li> |
|
<li>変数のスタイルの変更</li> |
|
<li>物理演算の簡易化</li> |
|
<li>スムーズなアニメーション</li> |
|
<li>追従と整列</li> |
|
<li>スプライトをグリッド上に配置</li> |
|
<li>ステージ全体への視覚効果</li> |
|
<li>クローンブロックの拡張</li> |
|
<li>スプライトを他の画像として表示</li> |
|
<li>個別のタイマー</li> |
|
<li>ブロックスタック内のみの変数</li> |
|
<li>ランタイムまたはスレッド内のみの変数</li> |
|
<li>スクラッチオブジェクトの編集</li> |
|
<li>フォントの管理</li> |
|
<li>プロジェクトを閉ても維持するストレージ</li> |
|
<li>HTTPリクエスト</li> |
|
<li>WebSocket</li> |
|
<li>コンパイルされたスクリプトを並列で実行</li> |
|
<li>Penguinmod API</li> |
|
<li>三次元用に拡張された演算</li> |
|
<li>乱数の拡張</li> |
|
<li>文字の圧縮と解凍</li> |
|
<li>便利なブロック</li> |
|
<li>ログの記録と変数</li> |
|
<li>Iframeの作成</li> |
|
<li>カラーピッカーの表示</li> |
|
<li>色の計算</li> |
|
<li>ブロックのすべてのメニューを抽出</li> |
|
<li>コメント</li> |
|
<li>パーリンノイズ</li> |
|
<li>ゲームパッド</li> |
|
<li>印刷</li> |
|
<li>ステージの切り抜き</li> |
|
<li>マウスカーソルの固定</li> |
|
<li>カーソルの見た目の変更</li> |
|
<li>Scratch認証</li> |
|
<li>Javascriptを実行</li> |
|
<li>配列</li> |
|
<li>スプライトとクローンへの直接アクセス</li> |
|
<li>非常に大きな数の計算</li> |
|
<li>色のユーティリティ</li> |
|
</ul> |
|
</div> |
|
</li> |
|
<ul> |
|
<li>拡張機能エディター</li> |
|
</ul> |
|
</div> |
|
|
|
<div class="feature-list"> |
|
<li>60個を超えるSharkpoolの拡張機能</li> |
|
|
|
<button class="toggle-button" aria-expanded="false" aria-controls="moreSharkpool">もっと見る</button> |
|
<div id="moreSharkpool" class="expandable-content"> |
|
<ul> |
|
<li>更に拡張された定義ブロック</li> |
|
<li>0znzwに触発させて特定のスクリプトの実行</li> |
|
<li>「見た目」カテゴリーの拡張</li> |
|
<li>ポップアップの表示</li> |
|
<li>様々なユーリティ</li> |
|
<li>時差の計算ブロック</li> |
|
<li>Scratchの統計</li> |
|
<li>ランダムシード番号や地形の生成</li> |
|
<li>複雑なオーディオ操作とエフェクト</li> |
|
<li>新しい動きブロック</li> |
|
<li>YoutubeAPI</li> |
|
<li>GeometryDashAPI</li> |
|
<li>オシレーターの演奏</li> |
|
<li>「調べる」カテゴリーの拡張</li> |
|
<li>高度なキー検出</li> |
|
<li>ビデオセンシング拡張機能の拡張</li> |
|
<li>クローン無しでパーティクルを作成</li> |
|
<li>SVG、スプライト、ステージにエフェクトを適用</li> |
|
<li>画像にエフェクトやフィルターを適用</li> |
|
<li>画像のピクセルデータの作成と編集</li> |
|
<li>ピクセルユーティリティ</li> |
|
<li>マイクの録音</li> |
|
<li>Newgroundsから音声を取得</li> |
|
<li>スプライトをリンクさせて親の動きに追従</li> |
|
<li>衝突検出</li> |
|
<li>ボックスの衝突検出</li> |
|
<li>ファイル拡張機能の拡張</li> |
|
<li>スプライト、スレッド、プロジェクト用の一時変数</li> |
|
<li>新しい変数モニター</li> |
|
<li>リストのカスタマイズ</li> |
|
<li>ゲームパッド拡張機能の拡張</li> |
|
<li>タイルグリッド上にスプライトを配置</li> |
|
<li>「2000年以降」ブロックの拡張</li> |
|
<li>アニメーションキーフレームの作成</li> |
|
<li>プロジェクト、スクリプト、スプライトを一時停止</li> |
|
<li>TikTokAPIの音声読み上げ</li> |
|
<li>メッセージブロック</li> |
|
<li>高度なメッセージブロック</li> |
|
<li>高度なFetch</li> |
|
<li>ユーザーの現在位置の取得</li> |
|
<li>Spotifyの音楽を再生</li> |
|
<li>SoundCloudAPI</li> |
|
<li>Googleスプレッドシートの読み書き</li> |
|
<li>通貨情報</li> |
|
<li>高度なテキストの表示</li> |
|
<li>色のユーティリティーと変換</li> |
|
<li>QRコードの作成と読み取り</li> |
|
<li>実行時にイベントを検出</li> |
|
<li>カスタマイズ可能な吹き出し</li> |
|
<li>プロジェクトのフォント管理</li> |
|
<li>レイヤーの操作</li> |
|
<li>ペン、背景、ビデオカメラ、スプライトなどのビジュアル</li> |
|
<li>タイムゾーン変換</li> |
|
<li>パーリンノイズ</li> |
|
<li>高度な制御ブロック</li> |
|
<li>新しい強力な演算</li> |
|
<li>クライアントベースのキャプチャ</li> |
|
<li>コメントのカスタマイズ</li> |
|
<li>スプライトとクローンの管理</li> |
|
<li>DOMの取得</li> |
|
<li>SVGスプライトの作成とエクスポート</li> |
|
<li>プロジェクトの宣伝</li> |
|
<li>GIFの作成と分割</li> |
|
<li>超高速JSON配列</li> |
|
<li>カスタムドロップダウンの作成</li> |
|
<li>スキン拡張機能の改良</li> |
|
<li>Unityのようなシーンを作成</li> |
|
<li>ペンレイヤーの作成</li> |
|
</ul> |
|
</div> |
|
</li> |
|
</div> |
|
|
|
<div class="feature-list"> |
|
<li>40個を超えるPenguinmodの拡張機能</li> |
|
<ul> |
|
<li>WebSocket</li> |
|
<li>Pen+</li> |
|
<li>物理処理</li> |
|
<li>高速なJSON処理</li> |
|
<li>ファイルの更新(直接編集)</li> |
|
<li>3D数学</li> |
|
<li>スコープ変数</li> |
|
<li>音声を文字起こし</li> |
|
<li>背景除去</li> |
|
<li>エンドツーエンド暗号化</li> |
|
<li>WebRTC</li> |
|
<li>ランダムユーティリティ</li> |
|
<li>ユーザーの位置情報</li> |
|
<li>値の型を追加</li> |
|
<li>PenguinAI(chatGPTやDALL E3など)</li> |
|
<li>スプライトシート</li> |
|
<li>webhook</li> |
|
<li>アラート</li> |
|
<li>数値ユーティリティ</li> |
|
<li>高度な数学</li> |
|
<li>小数点以下の拡張による高精度演算</li> |
|
<li>GithubAPI</li> |
|
<li>Google認証</li> |
|
<li>PenguinmodAPI</li> |
|
<li>Discord</li> |
|
<li>Twitch</li> |
|
<li>チェス</li> |
|
<li>天気予報</li> |
|
<li>CORS PROXY Fetch</li> |
|
<li>生の拡張機能へのアクセス</li> |
|
<li>プロジェクトページの操作(一部はs4sで使用できない)</li> |
|
<li>すべてのメニュー</li> |
|
<li>フィールド</li> |
|
<li>Beepbox</li> |
|
<li>ファイルをネットに保存</li> |
|
<li>URLの#以降の取得</li> |
|
<li>Scratchブロックの生成</li> |
|
<li>猫に関するブロック</li> |
|
<li>Scratchで削除されたカウンターブロック</li> |
|
<li>文字から行数を取得</li> |
|
<li>Wssサーバー</li> |
|
<li>TTStool APIによる読み上げ</li> |
|
<li>画面やカメラを共有</li> |
|
<li>エディターでマウスについてくる猫</li> |
|
<li>Web GPU</li> |
|
<li>数値の書式</li> |
|
<li>プロジェクトにインターフェースを追加</li> |
|
<li>ブロックAI</li> |
|
</ul> |
|
</div> |
|
|
|
<div class="feature-list"> |
|
<li>90個を超えるTurbowarpの拡張機能</li> |
|
</div> |
|
</section> |
|
|
|
<section id="video"> |
|
<h2>紹介動画</h2> |
|
<iframe width="560" height="315" src="https://www.youtube.com/embed/" title="解説動画" frameborder="0" allowfullscreen></iframe> |
|
</section> |
|
|
|
<script> |
|
// ローディングアニメーション |
|
window.addEventListener('load', function() { |
|
setTimeout(function() { |
|
document.getElementById('loadingOverlay').classList.add('hidden'); |
|
}, 800); |
|
}); |
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
const toggleButtons = document.querySelectorAll('.toggle-button'); |
|
|
|
toggleButtons.forEach(button => { |
|
button.addEventListener('click', function() { |
|
const expanded = this.getAttribute('aria-expanded') === 'true'; |
|
const targetId = this.getAttribute('aria-controls'); |
|
const target = document.getElementById(targetId); |
|
|
|
this.setAttribute('aria-expanded', !expanded); |
|
|
|
if (!expanded) { |
|
target.classList.add('show'); |
|
} else { |
|
target.classList.remove('show'); |
|
} |
|
}); |
|
}); |
|
}); |
|
|
|
|
|
document.addEventListener('click', function(e) { |
|
if (e.target.classList.contains('buttons') || e.target.closest('.buttons a')) { |
|
return; |
|
} |
|
|
|
const buttons = document.querySelectorAll('.buttons a'); |
|
buttons.forEach(button => { |
|
button.addEventListener('click', function(e) { |
|
e.preventDefault(); |
|
const href = this.getAttribute('href'); |
|
|
|
// リップルエフェクトを作成 |
|
const ripple = document.createElement('span'); |
|
ripple.classList.add('ripple'); |
|
this.appendChild(ripple); |
|
|
|
// アニメーション後に移動 |
|
setTimeout(() => { |
|
if (href.startsWith('http')) { |
|
window.open(href, '_blank'); |
|
} else { |
|
document.querySelector(href).scrollIntoView({ |
|
behavior: 'smooth' |
|
}); |
|
} |
|
ripple.remove(); |
|
}, 300); |
|
}); |
|
}); |
|
}); |
|
|
|
|
|
const scrollVideo = document.getElementById('scrollVideo'); |
|
const videoScrollSection = document.getElementById('videoScrollSection'); |
|
const fixedHeader = document.getElementById('fixedHeader'); |
|
let isVideoPlaying = false; |
|
let videoDuration = 0; |
|
let videoStartScroll = 0; |
|
let videoEndScroll = 0; |
|
|
|
|
|
scrollVideo.addEventListener('loadedmetadata', function() { |
|
videoDuration = scrollVideo.duration; |
|
|
|
|
|
const headerHeight = document.querySelector('.header-container').offsetHeight; |
|
videoStartScroll = headerHeight; |
|
videoEndScroll = videoStartScroll + (window.innerHeight * 100); |
|
|
|
|
|
window.addEventListener('scroll', handleScroll); |
|
|
|
|
|
const sections = document.querySelectorAll('section'); |
|
|
|
function checkScroll() { |
|
sections.forEach(section => { |
|
const sectionTop = section.getBoundingClientRect().top; |
|
const windowHeight = window.innerHeight; |
|
|
|
if (sectionTop < windowHeight * 0.75) { |
|
section.classList.add('visible'); |
|
} |
|
}); |
|
} |
|
|
|
window.addEventListener('scroll', checkScroll); |
|
window.addEventListener('load', checkScroll); |
|
}); |
|
|
|
function handleScroll() { |
|
const scrollY = window.scrollY; |
|
|
|
|
|
const headerHeight = document.querySelector('.header-container').offsetHeight; |
|
|
|
if (scrollY > headerHeight) { |
|
fixedHeader.classList.add('visible'); |
|
} else { |
|
fixedHeader.classList.remove('visible'); |
|
} |
|
|
|
|
|
const scrollProgress = document.getElementById('scrollProgress'); |
|
const scrollHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight; |
|
const scrollPercentage = (scrollY / scrollHeight) * 100; |
|
|
|
scrollProgress.style.width = scrollPercentage + '%'; |
|
scrollProgress.style.background = 'var(--primary-color)'; |
|
|
|
|
|
if (scrollY >= videoStartScroll && scrollY <= videoEndScroll) { |
|
if (!isVideoPlaying) { |
|
isVideoPlaying = true; |
|
scrollVideo.style.display = 'block'; |
|
document.body.style.overflow = 'hidden'; |
|
} |
|
|
|
|
|
const scrollRatio = (scrollY - videoStartScroll) / (videoEndScroll - videoStartScroll); |
|
const videoTime = scrollRatio * videoDuration; |
|
|
|
|
|
if (Math.abs(scrollVideo.currentTime - videoTime) > 0.1) { |
|
scrollVideo.currentTime = videoTime; |
|
} |
|
|
|
|
|
if (scrollRatio >= 0.99) { |
|
isVideoPlaying = false; |
|
scrollVideo.style.display = 'none'; |
|
document.body.style.overflow = ''; |
|
} |
|
} else { |
|
if (isVideoPlaying) { |
|
isVideoPlaying = false; |
|
scrollVideo.style.display = 'none'; |
|
document.body.style.overflow = ''; |
|
} |
|
} |
|
} |
|
|
|
|
|
scrollVideo.addEventListener('click', function() { |
|
this.muted = !this.muted; |
|
}); |
|
</script> |
|
</body> |
|
</html> |