Laravel で Christmas Illumination

# Laravel で Christmas Illumination

こんにちは！アドベントカレンダー最終日ですが， #2 のほうが空いてたので急遽一発ネタをぶち込むことにしました！！！

## 発想（アホ）

Laravel といえば [`Illuminate`](https://github.com/illuminate) だよね？
クリスマスといえばイルミネーションだよね？

↓

Laravel でイルミネーションをやろう（意味不明）

## 完成品

![Dec-25-2019 10-41-51.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25060/6ad06fb7-cb41-d2c9-0752-867b4e3fd536.gif)

https://jsfiddle.net/e2Lk9zwt/

# やり方

## 1. Laravel をインストール

```shell-session
user@host: ~$ laravel new illumination
user@host: ~$ cd illumination
```

## 2. パッケージ名を取得して `welcome.blade.php` に渡す

```diff:routes/web.php
diff --git a/routes/web.php b/routes/web.php
index 810aa34..80e8787 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -12,5 +12,10 @@
 */
 
 Route::get('/', function () {
-    return view('welcome');
+    $packages = [];
+    foreach (glob(base_path('vendor/laravel/framework/src/Illuminate/*/composer.json')) as $manifest) {
+        $manifest = json_decode(file_get_contents($manifest));
+        $packages[] = $manifest->name;
+    }
+    return view('welcome', compact('packages'));
 });
```

## 3. Google 先生から CSS 職人の一発芸をもらう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25060/ce5050f1-fae5-8949-03fa-204692f2ceee.png)

- [javascript - Text Fadein/Fadeout at Random Positions - Stack Overflow](https://stackoverflow.com/questions/21360198/text-fadein-fadeout-at-random-positions)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25060/a3f60081-3c65-081f-9a68-c9a3bf9ec1da.png)

- [Pure CSS Christmas Lights](https://codepen.io/tobyj/pen/QjvEex)

## 4. いい感じに移植

```diff:resources/sass/app.scss
diff --git a/resources/sass/app.scss b/resources/sass/app.scss
index 8337712..959e48a 100644
--- a/resources/sass/app.scss
+++ b/resources/sass/app.scss
@@ -1 +1,101 @@
-//
+$globe-width:   12px;
+$globe-height:  28px;
+$globe-spacing: 40px;
+$globe-spread:  3px;
+$light-off-opacity: 0.4;
+
+body {
+    background: #000;
+}
+.lightrope {
+    text-align: center;
+    white-space: nowrap;
+    overflow: hidden;
+    position: absolute;
+    z-index: 1;
+    margin: -15px 0 0 0;
+    padding: 0;
+    pointer-events: none;
+    width: 100%;
+    li {
+        position: relative;
+        animation-fill-mode: both;
+        animation-iteration-count:infinite;
+        list-style: none;
+        margin: 0;
+        padding: 0;
+        display: block;
+        width: $globe-width;
+        height: $globe-height;
+        border-radius: 50%;
+        margin: $globe-spacing/2;
+        display: inline-block;
+        background: rgba(0,247,165,1);
+        box-shadow: 0px $globe-height/6 $globe-width*2 $globe-spread rgba(0,247,165,1);
+        animation-name: flash-1;
+        animation-duration: 2s;
+        &:nth-child(2n+1) {
+            background: rgba(0,255,255,1);
+            box-shadow: 0px $globe-height/6 $globe-width*2 $globe-spread rgba(0,255,255,0.5);
+            animation-name: flash-2;
+            animation-duration: 0.4s;
+        }
+        &:nth-child(4n+2) {
+            background: rgba(247,0,148,1);
+            box-shadow: 0px $globe-height/6 $globe-width*2 $globe-spread rgba(247,0,148,1);
+            animation-name: flash-3;
+            animation-duration: 1.1s;
+        }
+        &:nth-child(odd) {
+            animation-duration: 1.8s;
+        }
+        &:nth-child(3n+1) {
+            animation-duration: 1.4s;
+        }
+        &:before {
+            content: "";
+            position: absolute;
+            background: #222;
+            width: ($globe-width - 2);
+            height: $globe-height/3;
+            border-radius: 3px;
+            top: (0 - ($globe-height/6));
+            left: 1px;
+        }
+        &:after {
+            content: "";
+            top: (0 - $globe-height/2);
+            left: $globe-width - 3;
+            position: absolute;
+            width: $globe-spacing + 12;
+            height: ($globe-height/3 * 2);
+            border-bottom: solid #222 2px;
+            border-radius: 50%;
+        }
+        &:last-child:after {
+            content: none;
+        }
+        &:first-child {
+            margin-left: -$globe-spacing;
+        }
+    }
+}
+
+@keyframes flash-1 {
+    0%, 100% { background: rgba(0,247,165,1);
+        box-shadow: 0px $globe-height/6 $globe-width*2 $globe-spread rgba(0,247,165,1);}
+    50% { background: rgba(0,247,165,$light-off-opacity);
+        box-shadow: 0px $globe-height/6 $globe-width*2 $globe-spread rgba(0,247,165,0.2);}
+}
+@keyframes flash-2 {
+    0%, 100% { background: rgba(0,255,255,1);
+        box-shadow: 0px $globe-height/6 $globe-width*2 $globe-spread rgba(0,255,255,1);}
+    50% { background: rgba(0,255,255,$light-off-opacity);
+        box-shadow: 0px $globe-height/6 $globe-width*2 $globe-spread rgba(0,255,255,0.2);}
+}
+@keyframes flash-3 {
+    0%, 100% { background: rgba(247,0,148,1);
+        box-shadow: 0px $globe-height/6 $globe-width*2 $globe-spread rgba(247,0,148,1);}
+    50% { background: rgba(247,0,148,$light-off-opacity);
+        box-shadow: 0px $globe-height/6 $globe-width*2 $globe-spread rgba(247,0,148,0.2);}
+}
```

```diff:resources/views/welcome.blade.php
diff --git a/resources/views/welcome.blade.php b/resources/views/welcome.blade.php
index 3fb48cc..66ad194 100644
--- a/resources/views/welcome.blade.php
+++ b/resources/views/welcome.blade.php
@@ -8,93 +8,83 @@
 
         <!-- Fonts -->
         <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
+        <link href="{{ mix('/css/app.css') }}" rel="stylesheet">
 
         <!-- Styles -->
         <style>
-            html, body {
-                background-color: #fff;
-                color: #636b6f;
-                font-family: 'Nunito', sans-serif;
-                font-weight: 200;
-                height: 100vh;
-                margin: 0;
+            .fadeIn1 {
+                display: none;
+                color: rgba(0,247,165,1);
+                animation-name: fadeIn-1;
+                animation-duration: 2s;
             }
-
-            .full-height {
-                height: 100vh;
-            }
-
-            .flex-center {
-                align-items: center;
-                display: flex;
-                justify-content: center;
+            .fadeIn2 {
+                display: none;
+                color: rgba(0,255,255,1);
+                animation-name: fadeIn-2;
+                animation-duration: 0.4s;
             }
-
-            .position-ref {
-                position: relative;
+            .fadeIn3 {
+                display: none;
+                color: rgba(0,255,255,1);
+                animation-name: fadeIn-3;
+                animation-duration: 1.1s;
             }
-
-            .top-right {
-                position: absolute;
-                right: 10px;
-                top: 18px;
+            @keyframes fadeIn-1 {
+                0%, 100% { color: rgba(0,247,165,1); }
+                50% { color: rgba(0,247,165,0.4); }
             }
-
-            .content {
-                text-align: center;
+            @keyframes fadeIn-2 {
+                0%, 100% { color: rgba(0,255,255,1);}
+                50% { color: rgba(0,255,255,0.4);}
             }
-
-            .title {
-                font-size: 84px;
-            }
-
-            .links > a {
-                color: #636b6f;
-                padding: 0 25px;
-                font-size: 13px;
-                font-weight: 600;
-                letter-spacing: .1rem;
-                text-decoration: none;
-                text-transform: uppercase;
-            }
-
-            .m-b-md {
-                margin-bottom: 30px;
+            @keyframes fadeIn-3 {
+                0%, 100% { color: rgba(247,0,148,1);}
+                50% { color: rgba(247,0,148,0.4);}
             }
         </style>
     </head>
     <body>
-        <div class="flex-center position-ref full-height">
-            @if (Route::has('login'))
-                <div class="top-right links">
-                    @auth
-                        <a href="{{ url('/home') }}">Home</a>
-                    @else
-                        <a href="{{ route('login') }}">Login</a>
+        <ul class="lightrope">
+            @for ($i = 0; $i < 42; ++$i)
+                <li></li>
+            @endfor
+        </ul>
+        @for ($i = 0; $i < 6; ++$i)
+            <div class="fadeIn fadeIn{{ ($i % 3) + 1 }}"></div>
+        @endfor
+        <script
+            src="https://code.jquery.com/jquery-3.4.1.min.js"
+            integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
+            crossorigin="anonymous"></script>
+        <script>
+            var packages = {!! json_encode($packages, JSON_UNESCAPED_SLASHES) !!};
 
-                        @if (Route::has('register'))
-                            <a href="{{ route('register') }}">Register</a>
-                        @endif
-                    @endauth
-                </div>
-            @endif
+            (function fadeInDiv(){
+                var divs = $('.fadeIn');
+                var divsize = ((Math.random()*100) + 50).toFixed();
+                var posx = (Math.random() * ($(document).width() - divsize)).toFixed();
+                var posy = (Math.random() * ($(document).height() - divsize)).toFixed();
+                var maxSize = 60;
+                var minSize = 15;
+                var size = (Math.random()*maxSize+minSize)
 
-            <div class="content">
-                <div class="title m-b-md">
-                    Laravel
-                </div>
+                var elem = divs.eq(Math.floor(Math.random()*divs.length));
 
-                <div class="links">
-                    <a href="https://laravel.com/docs">Docs</a>
-                    <a href="https://laracasts.com">Laracasts</a>
-                    <a href="https://laravel-news.com">News</a>
-                    <a href="https://blog.laravel.com">Blog</a>
-                    <a href="https://nova.laravel.com">Nova</a>
-                    <a href="https://forge.laravel.com">Forge</a>
-                    <a href="https://vapor.laravel.com">Vapor</a>
-                    <a href="https://github.com/laravel/laravel">GitHub</a>
-                </div>
-            </div>
-        </div>
+                if (!elem.is(':visible')){
+                    elem.fadeIn(Math.floor(Math.random()*1000),fadeInDiv);
+                    elem.css({
+                        'position':'absolute',
+                        'left':posx+'px',
+                        'top':posy+'px',
+                        'font-size': size+'px'
+                    });
+                    var pkg = packages[Math.floor(Math.random() * packages.length)];
+                    elem.text(pkg);
+                } else {
+                    elem.fadeOut(Math.floor(Math.random()*1000),fadeInDiv);
+                }
+            })();
+        </script>
     </body>
 </html>
```

jQuery 使ってますけど何か問題でも？？？？？？？？？？

## 5. ビルド

```shell-session
user@host: ~/illumination$ npm install
user@host: ~/illumination$ npm run dev
```

## 6. 完成！！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25060/0c0312e8-fd75-a11a-11ab-1cb89cd7dc9b.png)