soiz1 commited on
Commit
9b41d83
·
verified ·
1 Parent(s): 4c34935

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +230 -113
index.html CHANGED
@@ -9,7 +9,7 @@
9
  <link href="https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap" rel="stylesheet">
10
  <link rel="icon" href="icon.png" type="image/png">
11
  <style>
12
- body {
13
  display: flex;
14
  flex-direction: column;
15
  align-items: center;
@@ -323,126 +323,243 @@
323
  opacity: 0;
324
  }
325
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
  </style>
327
  </head>
328
 
329
  <body>
 
 
 
 
 
 
 
 
 
 
 
 
330
  <div id="ripple-container">
331
  </div>
332
  <script>
333
- document.addEventListener('DOMContentLoaded', function() {
334
- const container = document.getElementById('ripple-container');
335
-
336
- function createRipple() {
337
- const ripple = document.createElement('div');
338
- ripple.classList.add('ripple');
339
-
340
- // ランダムな位置
341
- const posX = Math.random() * 100;
342
- const posY = Math.random() * 100;
343
-
344
- // ランダムなサイズとアニメーション時間
345
- const maxSize = 400 + Math.random() * 500;
346
- const duration = 3 + Math.random() * 3;
347
-
348
- // 半透明の薄い水色のバリエーション
349
- const hue = 190 + Math.random() * 20 - 10; // 水色を中心に少し変化
350
- const saturation = 80 + Math.random() * 15;
351
- const lightness = 70 + Math.random() * 20;
352
- const opacity = 0.3 + Math.random() * 0.3;
353
-
354
- ripple.style.left = `${posX}%`;
355
- ripple.style.top = `${posY}%`;
356
- ripple.style.borderColor = `hsla(${hue}, ${saturation}%, ${lightness}%, ${opacity})`;
357
- ripple.style.animationDuration = `${duration}s`;
358
-
359
- // キーフレームを動的に変更
360
- const animationName = `ripple-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
361
- ripple.style.animationName = animationName;
362
-
363
- const style = document.createElement('style');
364
- style.innerHTML = `
365
- @keyframes ${animationName} {
366
- 0% {
367
- width: 0;
368
- height: 0;
369
- opacity: ${opacity};
370
- }
371
- 100% {
372
- width: ${maxSize}px;
373
- height: ${maxSize}px;
374
- opacity: 0;
375
- }
376
- }
377
- `;
378
- document.head.appendChild(style);
379
-
380
- container.appendChild(ripple);
381
-
382
- // アニメーション終了後に要素を削除
383
- ripple.addEventListener('animationend', function() {
384
- ripple.remove();
385
- style.remove();
386
- });
387
- }
388
-
389
- // 最初の波紋をいくつか作成
390
- for (let i = 0; i < 8; i++) {
391
- setTimeout(createRipple, i * 600);
392
  }
393
-
394
- // 定期的に新しい波紋を作成
395
- setInterval(createRipple, 1200);
396
-
397
- // クリックでも波紋を作成
398
- document.addEventListener('click', function(e) {
399
- createRippleAtPosition(e.clientX, e.clientY);
400
- });
401
-
402
- function createRippleAtPosition(x, y) {
403
- const ripple = document.createElement('div');
404
- ripple.classList.add('ripple');
405
-
406
- const maxSize = 400 + Math.random() * 500;
407
- const duration = 3 + Math.random() * 3;
408
- const hue = 190 + Math.random() * 20 - 10;
409
- const saturation = 80 + Math.random() * 15;
410
- const lightness = 70 + Math.random() * 20;
411
- const opacity = 0.3 + Math.random() * 0.3;
412
-
413
- ripple.style.left = `${x}px`;
414
- ripple.style.top = `${y}px`;
415
- ripple.style.borderColor = `hsla(${hue}, ${saturation}%, ${lightness}%, ${opacity})`;
416
- ripple.style.animationDuration = `${duration}s`;
417
-
418
- const animationName = `ripple-click-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
419
- ripple.style.animationName = animationName;
420
-
421
- const style = document.createElement('style');
422
- style.innerHTML = `
423
- @keyframes ${animationName} {
424
- 0% {
425
- width: 0;
426
- height: 0;
427
- opacity: ${opacity};
428
- }
429
- 100% {
430
- width: ${maxSize}px;
431
- height: ${maxSize}px;
432
- opacity: 0;
433
- }
434
- }
435
- `;
436
- document.head.appendChild(style);
437
-
438
- container.appendChild(ripple);
439
-
440
- ripple.addEventListener('animationend', function() {
441
- ripple.remove();
442
- style.remove();
443
- });
 
 
 
 
 
 
444
  }
 
 
 
 
 
 
 
 
445
  });
 
 
446
  </script>
447
  <h1>ラジオ体操動画プレイヤー
448
  <br>For Kushihara</h1>
@@ -682,14 +799,14 @@
682
  subtitleSizeInput.value = size;
683
  subtitleSize.value = size;
684
 
685
- // CSS変数で字幕サイズを制御
686
  document.documentElement.style.setProperty('--subtitle-scale', size);
687
 
688
  // VTTCueのlineプロパティには数値のみを設定('bottom'は無効)
689
  const track = subtitleTrackElement.track;
690
  if (track && track.cues) {
691
  for (let i = 0; i < track.cues.length; i++) {
692
- // 画面下部に表示するため、適切な数値を設定(例: 90
693
  track.cues[i].line = 90;
694
  track.cues[i].snapToLines = false; // ラインスナップを無効に
695
  }
 
9
  <link href="https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c&display=swap" rel="stylesheet">
10
  <link rel="icon" href="icon.png" type="image/png">
11
  <style>
12
+ body {
13
  display: flex;
14
  flex-direction: column;
15
  align-items: center;
 
323
  opacity: 0;
324
  }
325
  }
326
+
327
+ /* ローディングアニメーション */
328
+ .loading-overlay {
329
+ position: fixed;
330
+ top: 0;
331
+ left: 0;
332
+ width: 100%;
333
+ height: 100%;
334
+ background-color: rgba(0, 0, 0, 0.8);
335
+ display: flex;
336
+ justify-content: center;
337
+ align-items: center;
338
+ z-index: 9999;
339
+ transition: opacity 1s ease-out;
340
+ }
341
+
342
+ .spinner-box {
343
+ width: 300px;
344
+ height: 300px;
345
+ display: flex;
346
+ justify-content: center;
347
+ align-items: center;
348
+ background-color: transparent;
349
+ }
350
+
351
+ /* 軌道スタイル */
352
+ .leo {
353
+ position: absolute;
354
+ display: flex;
355
+ justify-content: center;
356
+ align-items: center;
357
+ border-radius: 50%;
358
+ }
359
+
360
+ .blue-orbit {
361
+ width: 165px;
362
+ height: 165px;
363
+ border: 1px solid #91daffa5;
364
+ animation: spin3D 3s linear .2s infinite;
365
+ }
366
+
367
+ .green-orbit {
368
+ width: 120px;
369
+ height: 120px;
370
+ border: 1px solid #91ffbfa5;
371
+ animation: spin3D 2s linear 0s infinite;
372
+ }
373
+
374
+ .red-orbit {
375
+ width: 90px;
376
+ height: 90px;
377
+ border: 1px solid #ffca91a5;
378
+ animation: spin3D 1s linear 0s infinite;
379
+ }
380
+
381
+ .white-orbit {
382
+ width: 60px;
383
+ height: 60px;
384
+ border: 2px solid #ffffff;
385
+ animation: spin3D 10s linear 0s infinite;
386
+ }
387
+
388
+ .w1 {
389
+ transform: rotate3D(1, 1, 1, 90deg);
390
+ }
391
+
392
+ .w2 {
393
+ transform: rotate3D(1, 2, .5, 90deg);
394
+ }
395
+
396
+ .w3 {
397
+ transform: rotate3D(.5, 1, 2, 90deg);
398
+ }
399
+
400
+ /* キーフレームアニメーション */
401
+ @keyframes spin3D {
402
+ from {
403
+ transform: rotate3d(.5,.5,.5, 360deg);
404
+ }
405
+ to {
406
+ transform: rotate3d(0,0,0, 0deg);
407
+ }
408
+ }
409
+
410
+ @keyframes spin {
411
+ from {
412
+ transform: rotate(0deg);
413
+ }
414
+ to {
415
+ transform: rotate(360deg);
416
+ }
417
+ }
418
  </style>
419
  </head>
420
 
421
  <body>
422
+ <!-- ローディングオーバーレイ -->
423
+ <div class="loading-overlay" id="loadingOverlay">
424
+ <div class="spinner-box">
425
+ <div class="blue-orbit leo"></div>
426
+ <div class="green-orbit leo"></div>
427
+ <div class="red-orbit leo"></div>
428
+ <div class="white-orbit w1 leo"></div>
429
+ <div class="white-orbit w2 leo"></div>
430
+ <div class="white-orbit w3 leo"></div>
431
+ </div>
432
+ </div>
433
+
434
  <div id="ripple-container">
435
  </div>
436
  <script>
437
+ // ローディングアニメーションをフェードアウト
438
+ window.addEventListener('load', function() {
439
+ setTimeout(function() {
440
+ const loadingOverlay = document.getElementById('loadingOverlay');
441
+ loadingOverlay.style.opacity = '0';
442
+ setTimeout(function() {
443
+ loadingOverlay.style.display = 'none';
444
+ }, 1000); // フェードアウト完了後に非表示にする
445
+ }, 1500); // ページ読み込み後1.5秒でフェードアウト開始
446
+ });
447
+
448
+ document.addEventListener('DOMContentLoaded', function() {
449
+ const container = document.getElementById('ripple-container');
450
+
451
+ function createRipple() {
452
+ const ripple = document.createElement('div');
453
+ ripple.classList.add('ripple');
454
+
455
+ // ランダムな位置
456
+ const posX = Math.random() * 100;
457
+ const posY = Math.random() * 100;
458
+
459
+ // ランダムなサイズとアニメーション時間
460
+ const maxSize = 400 + Math.random() * 500;
461
+ const duration = 3 + Math.random() * 3;
462
+
463
+ // 半透明の薄い水色のバリエーション
464
+ const hue = 190 + Math.random() * 20 - 10; // 水色を中心に少し変化
465
+ const saturation = 80 + Math.random() * 15;
466
+ const lightness = 70 + Math.random() * 20;
467
+ const opacity = 0.3 + Math.random() * 0.3;
468
+
469
+ ripple.style.left = `${posX}%`;
470
+ ripple.style.top = `${posY}%`;
471
+ ripple.style.borderColor = `hsla(${hue}, ${saturation}%, ${lightness}%, ${opacity})`;
472
+ ripple.style.animationDuration = `${duration}s`;
473
+
474
+ // キーフレームを動的に変更
475
+ //Math.random()で 0〜1 のランダムな数を生成。 .toString(36) で36進数(0-9 + a-z)に変換。
476
+ //.substr(2, 9) で先頭の "0." を除いた部分から9文字取り出し、 結果として英数字のランダムな9文字列を生成。
477
+ const animationName = `ripple-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
478
+ ripple.style.animationName = animationName;
479
+
480
+ const style = document.createElement('style');
481
+ style.innerHTML = `
482
+ @keyframes ${animationName} {
483
+ 0% {
484
+ width: 0;
485
+ height: 0;
486
+ opacity: ${opacity};
487
+ }
488
+ 100% {
489
+ width: ${maxSize}px;
490
+ height: ${maxSize}px;
491
+ opacity: 0;
492
+ }
 
 
 
493
  }
494
+ `;
495
+ document.head.appendChild(style);
496
+
497
+ container.appendChild(ripple);
498
+
499
+ // アニメーション終了後に要素を削除
500
+ ripple.addEventListener('animationend', function() {
501
+ ripple.remove();
502
+ style.remove();
503
+ });
504
+ }
505
+
506
+ // 最初の波紋をいくつか作成
507
+ for (let i = 0; i < 8; i++) {
508
+ setTimeout(createRipple, i * 600);
509
+ }
510
+
511
+ // 定期的に新しい波紋を作成
512
+ setInterval(createRipple, 1200);
513
+
514
+ // クリックでも波紋を作成
515
+ document.addEventListener('click', function(e) {
516
+ createRippleAtPosition(e.clientX, e.clientY);
517
+ });
518
+
519
+ function createRippleAtPosition(x, y) {
520
+ const ripple = document.createElement('div');
521
+ ripple.classList.add('ripple');
522
+
523
+ const maxSize = 400 + Math.random() * 500;
524
+ const duration = 3 + Math.random() * 3;
525
+ const hue = 190 + Math.random() * 20 - 10;
526
+ const saturation = 80 + Math.random() * 15;
527
+ const lightness = 70 + Math.random() * 20;
528
+ const opacity = 0.3 + Math.random() * 0.3;
529
+
530
+ ripple.style.left = `${x}px`;
531
+ ripple.style.top = `${y}px`;
532
+ ripple.style.borderColor = `hsla(${hue}, ${saturation}%, ${lightness}%, ${opacity})`;
533
+ ripple.style.animationDuration = `${duration}s`;
534
+
535
+ const animationName = `ripple-click-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
536
+ ripple.style.animationName = animationName;
537
+
538
+ const style = document.createElement('style');
539
+ style.innerHTML = `
540
+ @keyframes ${animationName} {
541
+ 0% {
542
+ width: 0;
543
+ height: 0;
544
+ opacity: ${opacity};
545
+ }
546
+ 100% {
547
+ width: ${maxSize}px;
548
+ height: ${maxSize}px;
549
+ opacity: 0;
550
+ }
551
  }
552
+ `;
553
+ document.head.appendChild(style);
554
+
555
+ container.appendChild(ripple);
556
+
557
+ ripple.addEventListener('animationend', function() {
558
+ ripple.remove();
559
+ style.remove();
560
  });
561
+ }
562
+ });
563
  </script>
564
  <h1>ラジオ体操動画プレイヤー
565
  <br>For Kushihara</h1>
 
799
  subtitleSizeInput.value = size;
800
  subtitleSize.value = size;
801
 
802
+ // 字幕サイズを制御
803
  document.documentElement.style.setProperty('--subtitle-scale', size);
804
 
805
  // VTTCueのlineプロパティには数値のみを設定('bottom'は無効)
806
  const track = subtitleTrackElement.track;
807
  if (track && track.cues) {
808
  for (let i = 0; i < track.cues.length; i++) {
809
+ // 画面下部に表示するため、適切な数値を設定。とりあえず90
810
  track.cues[i].line = 90;
811
  track.cues[i].snapToLines = false; // ラインスナップを無効に
812
  }