Browse Source

Gestion d'un nombre arbitraire de sous catégories + transitions

upgrade-electron
William Petit 4 years ago
parent
commit
d6dad43b3f
5 changed files with 143 additions and 35 deletions
  1. 69
    11
      css/style.css
  2. 19
    2
      default-profile.json
  3. 10
    6
      index.html
  4. 24
    0
      js/anim.js
  5. 21
    16
      js/app.js

+ 69
- 11
css/style.css View File

@@ -3,21 +3,51 @@
3 3
 }
4 4
 
5 5
 html, body {
6
-  padding: 1Opx 10px;
6
+  padding: 0;
7 7
   margin: 0;
8 8
   font-family: 'Droid Sans', 'Ubuntu Sans', sans-serif;
9 9
   background: url('../img/background.png') no-repeat;
10 10
   background-size: contain;
11 11
   background-position: center;
12 12
   background-color: rgb(34, 107, 160);
13
+  width: 100%;
14
+  height: 100%;
15
+  color: white;
16
+  overflow-x: hidden;
13 17
 }
14 18
 
15
-body, ul.apps-list {
19
+/* Launcher View */
20
+
21
+.launcher {
22
+  display: flex;
16 23
   width: 100%;
17 24
   height: 100%;
25
+  flex-direction: column;
26
+}
27
+
28
+.launcher .category-header {
29
+  padding: 40px 50px 0;
30
+  font-size: 50px;
31
+}
32
+
33
+.launcher .category-header a.goback {
34
+  text-decoration: none;
35
+  color: white;
36
+}
37
+
38
+.launcher .category-header a.goback:hover {
39
+  -webkit-animation: 500ms pulse-large infinite;
40
+}
41
+
42
+.launcher .category-header > .category-label {
43
+  float: right;
18 44
 }
19 45
 
20
-ul.apps-list {
46
+.launcher .category-header .goback {
47
+  font-weight: normal;
48
+}
49
+
50
+.launcher ul.apps-list {
21 51
   display: block;
22 52
   margin: 0;
23 53
   padding: 0;
@@ -28,10 +58,10 @@ ul.apps-list {
28 58
   justify-content: center;
29 59
   align-items: center;
30 60
   align-content: center;
61
+  flex-grow: 1;
31 62
 }
32 63
 
33
-li.app-item {
34
-  background-color: red;
64
+.launcher li.app-item {
35 65
   margin: 5px;
36 66
   border-radius: 5px;
37 67
   background-color: rgba(0,0,0,0.4);
@@ -43,10 +73,10 @@ li.app-item {
43 73
   transition: 150ms linear;
44 74
   position: relative;
45 75
   overflow: hidden;
46
-  min-width: 10%; 
76
+  min-width: 150px;
47 77
 }
48 78
 
49
-li.app-item::after {
79
+.launcher li.app-item::after {
50 80
   content: ' ';
51 81
   display: block;
52 82
   border-radius: 50%;
@@ -58,22 +88,24 @@ li.app-item::after {
58 88
   top: -75%;
59 89
 }
60 90
 
61
-li.app-item:hover {
91
+.launcher li.app-item:hover {
62 92
   background-color: rgba(0,0,0,0.6);
63 93
 }
64 94
 
65
-li.app-item > .app-icon {
95
+.launcher li.app-item > .app-icon {
66 96
   width: 70%;
67 97
   height: auto;
68 98
 }
69 99
 
70
-li.app-item > .app-label {
100
+.launcher li.app-item > .app-label {
71 101
   display: block;
72 102
   text-align: center;
73 103
   color: white;
74 104
 }
75 105
 
76
-li.app-item.loading {
106
+/* Animations */
107
+
108
+.pulse {
77 109
   -webkit-animation: 1s pulse infinite;
78 110
 }
79 111
 
@@ -82,3 +114,29 @@ li.app-item.loading {
82 114
   50% { transform: scale(1.1); }
83 115
   100% { transform: scale(1); }
84 116
 }
117
+
118
+@-webkit-keyframes pulse-large {
119
+  0% { transform: scale(1); }
120
+  50% { transform: scale(1.5); }
121
+  100% { transform: scale(1); }
122
+}
123
+
124
+@-webkit-keyframes slide-in-left {
125
+  0% { transform: translateX(-100%); }
126
+  100% { transform: translateX(0%); }
127
+}
128
+
129
+@-webkit-keyframes slide-in-right {
130
+  0% { transform: translateX(100%); }
131
+  100% { transform: translateX(0%); }
132
+}
133
+
134
+@-webkit-keyframes slide-out-left {
135
+  0% { transform: translateX(0%); }
136
+  100% { transform: translateX(-100%); }
137
+}
138
+
139
+@-webkit-keyframes slide-out-right {
140
+  0% { transform: translateX(0%); }
141
+  100% { transform: translateX(100%); }
142
+}

+ 19
- 2
default-profile.json View File

@@ -1,11 +1,11 @@
1 1
 {
2 2
   "items": [
3 3
     {
4
-      "label": "Root",
4
+      "label": "Level 1",
5 5
       "icon": "/usr/share/icons/Mint-X/apps/48/chromium-browser.png",
6 6
       "items": [
7 7
         {
8
-          "label": "Level 1",
8
+          "label": "Level 2-1",
9 9
           "icon": "/usr/share/icons/Mint-X/apps/48/chromium-browser.png",
10 10
           "items": [
11 11
             {
@@ -14,6 +14,23 @@
14 14
               "exec": "/usr/bin/chromium-browser"
15 15
             }
16 16
           ]
17
+        },
18
+        {
19
+          "label": "Level 2-2",
20
+          "icon": "/usr/share/icons/Mint-X/apps/48/chromium-browser.png",
21
+          "items": [
22
+            {
23
+              "label": "Level 3-1",
24
+              "icon": "/usr/share/icons/Mint-X/apps/48/chromium-browser.png",
25
+              "items": [
26
+                {
27
+                  "label": "Chromium Browser",
28
+                  "icon": "/usr/share/icons/Mint-X/apps/48/chromium-browser.png",
29
+                  "exec": "/usr/bin/chromium-browser"
30
+                }
31
+              ]
32
+            }
33
+          ]
17 34
         }
18 35
       ]
19 36
     }

+ 10
- 6
index.html View File

@@ -11,12 +11,15 @@
11 11
     <!-- Templates -->
12 12
 
13 13
     <script id="launcher-view-tpl" type="text/x-template">
14
-      {{#unless isRoot}}
15
-        <div class="category-header">
16
-          <h2><a href="#" class="goback" data-item-path="{{currentItemPath}}">&#8678;</a> {{currentItem.label}}</h2>
17
-        </div>
18
-      {{/unless}}
19
-      {{> itemListTpl}}
14
+      <div class="launcher">
15
+        {{#unless isRoot}}
16
+          <div class="category-header">
17
+            <a href="#" class="goback" data-item-path="{{currentItemPath}}">&#9668;</a>
18
+            <span class="category-label">{{currentItem.label}}</span>
19
+          </div>
20
+        {{/unless}}
21
+        {{> itemListTpl}}
22
+      </div>
20 23
     </script>
21 24
 
22 25
     <script id="items-list-tpl" type="text/x-template">
@@ -37,6 +40,7 @@
37 40
 
38 41
     <!-- Scripts -->
39 42
     <script type="text/javascript" src="js/dom.js"></script>
43
+    <script type="text/javascript" src="js/anim.js"></script>
40 44
     <script type="text/javascript" src="js/app.js"></script>
41 45
 
42 46
     <!-- Application bootstrapping -->

+ 24
- 0
js/anim.js View File

@@ -0,0 +1,24 @@
1
+(function(Pitaya, window) {
2
+
3
+  "use strict";
4
+
5
+  var Anim = Pitaya.Anim = {};
6
+  var Events = Anim.Events = {
7
+    ANIMATION_END: 'webkitAnimationEnd'
8
+  };
9
+
10
+  Anim.play = function(el, animation) {
11
+    return new Promise(function(resolve, reject) {
12
+      
13
+      el.addEventListener(Events.ANIMATION_END, onAnimEnd, false);
14
+      el.style.webkitAnimation = animation;
15
+
16
+      function onAnimEnd(evt) {
17
+        el.removeEventListener(Events.ANIMATION_END, onAnimEnd);
18
+        return resolve(el);
19
+      }
20
+
21
+    });
22
+  };
23
+
24
+}(window.Pitaya = window.Pitaya || {}, window));

+ 21
- 16
js/app.js View File

@@ -66,8 +66,6 @@
66 66
    */
67 67
   Pitaya.renderLauncherView = function(currentItemPath) {
68 68
 
69
-    console.log('render', currentItemPath);
70
-
71 69
     currentItemPath = Pitaya._normalizeItemPath(currentItemPath);
72 70
     var rootEl = Pitaya._rootEl;
73 71
     var currentItem = Pitaya._getItemByPath(currentItemPath);
@@ -78,8 +76,6 @@
78 76
       isRoot: currentItemPath.length === 0
79 77
     };
80 78
 
81
-    console.log('render data', data);
82
-
83 79
     rootEl.innerHTML = launcherViewTpl(data);
84 80
 
85 81
   };
@@ -110,27 +106,30 @@
110 106
     var itemPath = appItemEl.dataset.itemPath;
111 107
     var item = Pitaya._getItemByPath(itemPath);
112 108
 
113
-    console.log('item click',itemPath, item);
114
-
115 109
     if(!item) return;
116 110
 
117 111
     if('items' in item) {
118
-      return Pitaya.renderLauncherView(itemPath);
112
+      var rootEl = Pitaya._rootEl;
113
+      Pitaya.Anim.play(rootEl, 'slide-out-left 250ms ease-in-out')
114
+        .then(function() {
115
+          Pitaya.renderLauncherView(itemPath);
116
+          return Pitaya.Anim.play(rootEl, 'slide-in-right 250ms ease-in-out');
117
+        })
118
+      ;
119 119
     }
120 120
 
121 121
     if(item.exec) {
122 122
 
123 123
       console.info('Launching application "'+item.exec+'"...');
124
-      appItemEl.classList.add('loading');
124
+      appItemEl.classList.add('pulse');
125 125
 
126 126
       Pitaya._runApp(item.exec)
127 127
         .then(function() {
128
-          appItemEl.classList.remove('loading');
129
-          console.info('Application closed "'+item.exec+'".');
128
+          appItemEl.classList.remove('pulse');
130 129
         })
131 130
         .catch(function(err) {
132 131
           Pitaya._onError(err);
133
-          appItemEl.classList.remove('loading');
132
+          appItemEl.classList.remove('pulse');
134 133
         })
135 134
       ;
136 135
 
@@ -155,7 +154,13 @@
155 154
 
156 155
     parentItemPath.pop();
157 156
 
158
-    return Pitaya.renderLauncherView(parentItemPath);
157
+    var rootEl = Pitaya._rootEl;
158
+    Pitaya.Anim.play(rootEl, 'slide-out-right 250ms ease-in-out')
159
+      .then(function() {
160
+        Pitaya.renderLauncherView(parentItemPath);
161
+        return Pitaya.Anim.play(rootEl, 'slide-in-left 250ms ease-in-out');
162
+      })
163
+    ;
159 164
 
160 165
   };
161 166
 
@@ -179,9 +184,9 @@
179 184
     rootItem = rootItem || Pitaya._profile;
180 185
     itemPath = Pitaya._normalizeItemPath(itemPath);
181 186
 
182
-    var index = itemPath.slice(0,1)[0];
187
+    var itemIndex = itemPath[0];
183 188
 
184
-    if(index === undefined) {
189
+    if(itemIndex === undefined) {
185 190
       return rootItem;
186 191
     }
187 192
 
@@ -189,13 +194,13 @@
189 194
       return undefined;
190 195
     }
191 196
 
192
-    var subItem = rootItem.items[index];
197
+    var subItem = rootItem.items[itemIndex];
193 198
 
194 199
     if(itemPath.length === 0) {
195 200
       return subItem;
196 201
     }
197 202
 
198
-    return Pitaya._getItemByPath(itemPath, subItem);
203
+    return Pitaya._getItemByPath(itemPath.slice(1), subItem);
199 204
 
200 205
   };
201 206
 

Loading…
Cancel
Save