├── .editorconfig ├── .gitattributes ├── .github └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── LICENSE ├── SECURITY.md ├── demo ├── demo.html ├── demo.js ├── github.png ├── npmjs.png ├── paypal.png ├── preload.svg └── svg │ ├── amazon-ws.svg │ ├── asus.svg │ ├── avast.svg │ ├── bluetooth.svg │ ├── burger-king.svg │ ├── continental.svg │ ├── hilti.svg │ └── sennheiser.svg ├── dist ├── angular-super-gallery.min.css ├── angular-super-gallery.min.css.gz ├── angular-super-gallery.min.js └── angular-super-gallery.min.js.gz ├── index.js ├── mix-manifest.json ├── package-lock.json ├── package.json ├── readme.md ├── screenshot1.jpg ├── screenshot2.jpg ├── src ├── asg-control.ts ├── asg-debug.ts ├── asg-image.ts ├── asg-info.ts ├── asg-modal.ts ├── asg-panel.ts ├── asg-service.ts ├── asg-templates.js ├── asg-thumbnail.ts ├── asg.scss ├── asg.ts ├── scss │ ├── asg-control.scss │ ├── asg-image.scss │ ├── asg-info.scss │ ├── asg-modal.scss │ ├── asg-panel.scss │ ├── asg-thumbnail.scss │ ├── asg-transitions.scss │ ├── theme-darkblue.scss │ ├── theme-darkred.scss │ ├── theme-default.scss │ ├── theme-whitegold.scss │ └── transitions │ │ ├── fadeInOut.scss │ │ ├── flipX.scss │ │ ├── flipY.scss │ │ ├── rotateLR.scss │ │ ├── rotateTB.scss │ │ ├── rotateZY.scss │ │ ├── slideLR.scss │ │ ├── slideTB.scss │ │ ├── zlideLR.scss │ │ ├── zlideTB.scss │ │ ├── zoomIn.scss │ │ ├── zoomInOut.scss │ │ └── zoomOut.scss └── views │ ├── asg-control.html │ ├── asg-debug.html │ ├── asg-help.html │ ├── asg-image.html │ ├── asg-info.html │ ├── asg-modal.html │ ├── asg-panel.html │ ├── asg-thumbnail.html │ └── button │ ├── asg-close.html │ ├── asg-fullscreen.html │ ├── asg-help.html │ ├── asg-index-xs.html │ ├── asg-index.html │ ├── asg-next.html │ ├── asg-pin.html │ ├── asg-playstop.html │ ├── asg-prev.html │ ├── asg-size.html │ ├── asg-thumbnails.html │ └── asg-transition.html ├── test ├── index.html ├── package.json ├── src │ ├── index.css │ └── index.js └── webpack.config.js ├── tsconfig.json ├── tslint.json └── webpack.mix.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | charset = utf-8 11 | indent_style = tab 12 | indent_size = 4 13 | trim_trailing_whitespace = true 14 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * linguist-vendored 2 | *.js linguist-vendored=false -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '17 9 * * 4' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'javascript', 'typescript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 37 | # Learn more: 38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 39 | 40 | steps: 41 | - name: Checkout repository 42 | uses: actions/checkout@v2 43 | 44 | # Initializes the CodeQL tools for scanning. 45 | - name: Initialize CodeQL 46 | uses: github/codeql-action/init@v1 47 | with: 48 | languages: ${{ matrix.language }} 49 | # If you wish to specify custom queries, you can do so here or in a config file. 50 | # By default, queries listed here will override any specified in a config file. 51 | # Prefix the list here with "+" to use these queries and those in the config file. 52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | - name: Autobuild 57 | uses: github/codeql-action/autobuild@v1 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | #- run: | 67 | # make bootstrap 68 | # make release 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v1 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | .history 4 | temp 5 | typings 6 | *.log 7 | node_modules 8 | test/node_modules 9 | test/fonts 10 | test/bundle.js 11 | test/yarn* 12 | /demo/index.html 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-2018 Tamas Schalk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | 2.2.x | :white_check_mark: | 8 | | < 2.1 | :x: | 9 | 10 | ## Reporting a Vulnerability 11 | 12 | Github Issues 13 | -------------------------------------------------------------------------------- /demo/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AngularJS Super Gallery 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 100 | 101 | 102 | 103 | 104 | 105 | 176 | 177 |
178 | 179 |
180 | 181 |
182 | 183 | 184 |
185 |
186 | multiple images | thumbnails | modal + controls 187 | 190 |
191 | 192 |
193 | 194 |
{{ ctrl.options1|json}}
195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 |
204 |
205 | 206 |
207 | 209 | 211 | 213 | 215 |
216 |
217 | 218 |
219 |
220 |
221 | File index (editable) 222 |
223 | 224 |
225 |
226 | 227 |
228 |
229 |
230 | Theme 231 |
232 | 238 |
239 |
240 | 241 |
242 |
243 |
244 | Transition 245 |
246 | 262 |
263 |
264 | 265 |
266 |
267 |
268 | custom panel | auto select the image when mouseover 269 | 270 | 271 |
272 | only modal | without theme 273 |
274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 |
283 | 284 | 288 | 289 |
290 | 291 | 292 |
293 | 294 |
295 | 296 | 297 |
298 | 299 |
300 | multiple images | autoplay | modal + hidden controls 301 | 304 |
305 |
306 | 307 |
{{ ctrl.options2|json}}
308 | 309 | 310 | 311 | 316 | 317 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 |
352 | 353 | 357 | 358 |
359 | 360 | 361 | 362 |
363 | 364 |
365 | svg logos | autoplay | no modal | no control | auto height by first image 366 |
367 | 368 |
369 | 370 | 371 | 379 | 380 | 381 | 382 |
383 | 384 | 390 | 391 |
392 | 393 | 394 | 395 |
396 | 397 |
398 | single image | fixed height | modal + hidden controls and caption 399 |
400 | 401 |
402 | 403 |
404 |
405 | 406 | 413 | 414 | 415 |
416 |
417 | 418 | 425 | 426 | 427 |
428 |
429 | 430 | 431 |
432 | 433 | 437 | 438 |
439 | 440 | 441 | 442 |
443 |
444 |
445 | 446 | 447 | 448 | 449 | -------------------------------------------------------------------------------- /demo/demo.js: -------------------------------------------------------------------------------- 1 | const demo = angular.module('demo', ['angularSuperGallery']); 2 | 3 | demo.controller('DemoController', ['$rootScope', function($rootScope) { 4 | 5 | this.gallery = { 6 | nature: true, 7 | abstracts: true, 8 | portraits: true, 9 | logos: true, 10 | }; 11 | 12 | this.options1 = { 13 | debug: true, 14 | hashUrl: false, 15 | baseUrl: "https://images.unsplash.com/", 16 | selected: 0, 17 | fields: { 18 | source: { 19 | modal: "link", 20 | image: "medium", 21 | panel: "thumbnail" 22 | } 23 | }, 24 | loadingImage: 'preload.svg', 25 | preloadNext: true, 26 | preloadDelay: 420, 27 | autoplay: { 28 | enabled: false, 29 | delay: 3200 30 | }, 31 | theme: 'darkblue', 32 | thumbnail: { 33 | height: 64, 34 | index: true, 35 | }, 36 | modal: { 37 | caption: { 38 | visible: true, 39 | position: 'bottom' 40 | }, 41 | header: { 42 | enabled: true, 43 | dynamic: false 44 | }, 45 | transition: 'rotateLR', 46 | title: "Angular Super Gallery Demo", 47 | subtitle: "Nature Wallpapers Full HD", 48 | thumbnail: { 49 | height: 77, 50 | index: true, 51 | }, 52 | }, 53 | panel: { 54 | click: { 55 | select: false, 56 | modal: true 57 | }, 58 | hover: { 59 | select: true 60 | }, 61 | items: { 62 | class: "", 63 | }, 64 | item: { 65 | class: "custom", 66 | title: false 67 | } 68 | }, 69 | image: { 70 | height: 580, 71 | click: { 72 | modal: true 73 | }, 74 | transition: 'zlideLR', 75 | placeholder: 'panel' 76 | }, 77 | }; 78 | 79 | const imagesBackGroundColor = 'black'; 80 | 81 | this.files1 = [{ 82 | "source": { 83 | "modal": "photo-1462480803487-a2edfd796460?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 84 | "image": "photo-1462480803487-a2edfd796460?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 85 | "panel": "photo-1462480803487-a2edfd796460?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 86 | }, 87 | "title": "Marmolada, Italy", 88 | "description": "Marco Bonomo", 89 | 'color': imagesBackGroundColor, 90 | 'video': { 91 | 'vimeoId' : '173523597' 92 | } 93 | }, { 94 | "source": { 95 | "modal": "photo-1577951930508-9b26cce01b4c?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 96 | "image": "photo-1577951930508-9b26cce01b4c?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 97 | "panel": "photo-1577951930508-9b26cce01b4c?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 98 | }, 99 | "title": "ALEKSEY KUPRIKOV", 100 | "description": "", 101 | 'color': imagesBackGroundColor, 102 | 'video': { 103 | 'vimeoId' : '137468479' 104 | } 105 | }, { 106 | "source": { 107 | "modal": "photo-1577578306649-09e937512e28?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 108 | "image": "photo-1577578306649-09e937512e28?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 109 | "panel": "photo-1577578306649-09e937512e28?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 110 | }, 111 | "title": "Tindfjöll, Iceland", 112 | "description": "Gissur Steinarsson", 113 | 'color': imagesBackGroundColor 114 | }, { 115 | "source": { 116 | "modal": "photo-1577688723008-7c501eae6f26?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 117 | "image": "photo-1577688723008-7c501eae6f26?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 118 | "panel": "photo-1577688723008-7c501eae6f26?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 119 | }, 120 | "title": "Ky Quan San (Bạch Mộc Lương Tử), Bát Xát, Lào Cai, Việt Nam", 121 | "description": "Dương Trần Quốc", 122 | 'color': imagesBackGroundColor 123 | }, { 124 | "source": { 125 | "modal": "photo-1577833780113-9ce85d64d49d?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 126 | "image": "photo-1577833780113-9ce85d64d49d?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 127 | "panel": "photo-1577833780113-9ce85d64d49d?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 128 | }, 129 | "title": "Arhavi, Artvin, Turkey", 130 | "description": "Emre Öztürk", 131 | 'color': imagesBackGroundColor 132 | }, 133 | 134 | { 135 | "source": { 136 | "modal": "photo-1555985202-12975b0235dc?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 137 | "image": "photo-1555985202-12975b0235dc?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 138 | "panel": "photo-1555985202-12975b0235dc?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 139 | }, 140 | "title": "Grand Canyon North Rim", 141 | "description": "Stephen Walker", 142 | 'color': imagesBackGroundColor 143 | }, 144 | { 145 | "source": { 146 | "modal": "photo-1483977399921-6cf94f6fdc3a?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 147 | "image": "photo-1483977399921-6cf94f6fdc3a?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 148 | "panel": "photo-1483977399921-6cf94f6fdc3a?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 149 | }, 150 | "title": "Paris, France", 151 | "description": "Nicolas Prieto", 152 | 'color': imagesBackGroundColor 153 | }, 154 | 155 | { 156 | "source": { 157 | "modal": "photo-1434394354979-a235cd36269d?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 158 | "image": "photo-1434394354979-a235cd36269d?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 159 | "panel": "photo-1434394354979-a235cd36269d?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 160 | }, 161 | "title": "Ales Krivec", 162 | "description": "", 163 | 'color': imagesBackGroundColor 164 | }, 165 | 166 | 167 | { 168 | "source": { 169 | "modal": "photo-1464822759023-fed622ff2c3b?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 170 | "image": "photo-1464822759023-fed622ff2c3b?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 171 | "panel": "photo-1464822759023-fed622ff2c3b?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 172 | }, 173 | "title": "Kluane National Park and Reserve of Canada, Canada", 174 | "description": "Kalen Emsley", 175 | 'color': imagesBackGroundColor 176 | }, 177 | 178 | { 179 | "source": { 180 | "modal": "photo-1466927593098-4d4aa7a2b2d8?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 181 | "image": "photo-1466927593098-4d4aa7a2b2d8?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 182 | "panel": "photo-1466927593098-4d4aa7a2b2d8?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 183 | }, 184 | "title": "Playa de la Misericordia, Spain", 185 | "description": "Quino Al", 186 | 'color': imagesBackGroundColor 187 | }, 188 | { 189 | "source": { 190 | "modal": "photo-1542810104-c5f07c7357ff?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 191 | "image": "photo-1542810104-c5f07c7357ff?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 192 | "panel": "photo-1542810104-c5f07c7357ff?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 193 | }, 194 | "title": "Francesco Ungaro", 195 | "description": "", 196 | 'color': imagesBackGroundColor 197 | }, 198 | { 199 | "source": { 200 | "modal": "photo-1572152269271-c652a70dd517?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 201 | "image": "photo-1572152269271-c652a70dd517?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 202 | "panel": "photo-1572152269271-c652a70dd517?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 203 | }, 204 | "title": "Heping Island Park, Keelung City, Taiwan", 205 | "description": "Andy Wang", 206 | 'color': imagesBackGroundColor 207 | }, 208 | 209 | 210 | 211 | { 212 | "source": { 213 | "modal": "photo-1512089425728-b012186ab3cc?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 214 | "image": "photo-1512089425728-b012186ab3cc?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 215 | "panel": "photo-1512089425728-b012186ab3cc?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 216 | }, 217 | "title": "Sun rays a game only on 3-6 minutes…", 218 | "description": "Valeriy Andrushko", 219 | 'color': imagesBackGroundColor 220 | }, 221 | 222 | ]; 223 | 224 | this.add1 = function() { 225 | $rootScope.$broadcast('ASG-gallery-edit', { 226 | id: 'nature', 227 | selected: -1, 228 | add: [{ 229 | "source": { 230 | "modal": "photo-1527437934671-61474b530017?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 231 | "image": "photo-1527437934671-61474b530017?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 232 | "panel": "photo-1527437934671-61474b530017?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 233 | }, 234 | "title": "Seychelles", 235 | "description": "Nenad Radojčić", 236 | 'color': imagesBackGroundColor 237 | }] 238 | }); 239 | }; 240 | 241 | this.update1options = function() { 242 | $rootScope.$broadcast('ASG-gallery-edit', { 243 | id: 'nature', 244 | options: this.options1 245 | }); 246 | }; 247 | 248 | this.update1selected = function() { 249 | $rootScope.$broadcast('ASG-gallery-edit', { 250 | id: 'nature', 251 | selected: this.options1.selected 252 | }); 253 | }; 254 | 255 | this.update1 = function() { 256 | 257 | const newGalleryImages = [{ 258 | "source": { 259 | "modal": "photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 260 | "image": "photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 261 | "panel": "photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 262 | }, 263 | "title": "North Shore, Waialua, United States", 264 | "description": "Sean O.", 265 | 'color': imagesBackGroundColor 266 | }, { 267 | "source": { 268 | "modal": "photo-1560294572-28b9874e5ada?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 269 | "image": "photo-1560294572-28b9874e5ada?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 270 | "panel": "photo-1560294572-28b9874e5ada?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&q=75", 271 | }, 272 | "title": "Beach, Fuerteventura, Spain", 273 | "description": "Uwe Jelting", 274 | 'color': imagesBackGroundColor 275 | }]; 276 | 277 | this.options1.selected = 1; 278 | 279 | $rootScope.$broadcast('ASG-gallery-edit', { 280 | id: 'nature', 281 | update: newGalleryImages 282 | }); 283 | 284 | }; 285 | 286 | this.delete1 = function() { 287 | $rootScope.$broadcast('ASG-gallery-edit', { 288 | id: 'nature', 289 | delete: null // index number or null for delete selected image 290 | }); 291 | }; 292 | 293 | this.reset1 = function() { 294 | 295 | this.options1 = angular.copy(this.options1Backup); 296 | this.files1 = angular.copy(this.files1Backup); 297 | 298 | $rootScope.$broadcast('ASG-gallery-edit', { 299 | id: 'nature', 300 | selected: 0, 301 | update: this.files1, 302 | options: this.options1 303 | }); 304 | }; 305 | 306 | this.options1Backup = angular.copy(this.options1); 307 | this.files1Backup = angular.copy(this.files1); 308 | 309 | //----------------------------- 310 | 311 | this.options2 = { 312 | debug: false, 313 | loadingImage: 'preload.svg', 314 | preloadNext: true, 315 | preloadDelay: 1200, 316 | baseUrl: "https://images.unsplash.com/", 317 | hashUrl: false, 318 | autoplay: { 319 | enabled: true, 320 | delay: 4200 321 | }, 322 | theme: 'darkred', 323 | modal: { 324 | title: '', 325 | transition: 'fadeInOut', 326 | transitionSpeed: 1, 327 | titleFromImage: true, 328 | subtitleFromImage: true, 329 | caption: { 330 | visible: false, 331 | position: 'bottom' 332 | }, 333 | thumbnail: { 334 | height: 90, 335 | index: false, 336 | dynamic: true 337 | }, 338 | }, 339 | panel: { 340 | visible: false, 341 | item: { 342 | class: "col-md-4 float-left", 343 | caption: true, 344 | index: true 345 | }, 346 | click: { 347 | select: true, 348 | modal: false 349 | }, 350 | }, 351 | image: { 352 | heightAuto: { 353 | initial: true, 354 | onresize: true, 355 | }, 356 | transition: 'zoomInOut', 357 | transitionSpeed: 0.9, 358 | placeholder: 'panel' 359 | }, 360 | }; 361 | 362 | 363 | this.files2 = [{ 364 | "source": { 365 | "modal": "photo-1541701494587-cb58502866ab?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 366 | "image": "photo-1541701494587-cb58502866ab?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 367 | "panel": "photo-1541701494587-cb58502866ab?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&h=200&q=70", 368 | }, 369 | "title": "Lucas Benjamin", 370 | "description": "" 371 | }, { 372 | "source": { 373 | "modal": "photo-1516670428252-df97bba108d1?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 374 | "image": "photo-1516670428252-df97bba108d1?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 375 | "panel": "photo-1516670428252-df97bba108d1?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&h=200&q=70", 376 | }, 377 | "title": "Fairhaven, Bellingham, United States", 378 | "description": "Adrien Converse" 379 | }, { 380 | "source": { 381 | "modal": "photo-1519017524945-ed31bb7a3786?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 382 | "image": "photo-1519017524945-ed31bb7a3786?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 383 | "panel": "photo-1519017524945-ed31bb7a3786?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&h=200&q=70", 384 | }, 385 | "title": "Red Vein", 386 | "description": "Lucas Benjamin" 387 | 388 | }, { 389 | "source": { 390 | "modal": "photo-1565638459249-c85cbb2faaa8?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 391 | "image": "photo-1565638459249-c85cbb2faaa8?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 392 | "panel": "photo-1565638459249-c85cbb2faaa8?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&h=200&q=70", 393 | }, 394 | "title": "Paweł Czerwiński", 395 | "description": "" 396 | 397 | }, { 398 | "source": { 399 | "modal": "photo-1470485661945-c52d58c91f51?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 400 | "image": "photo-1470485661945-c52d58c91f51?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 401 | "panel": "photo-1470485661945-c52d58c91f51?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&h=200&q=70", 402 | }, 403 | "title": "The Titanic Memorial Garden, Belfast, United Kingdom", 404 | "description": "Yaniv Knobel" 405 | 406 | }, { 407 | "source": { 408 | "modal": "photo-1552084162-ec07b3f162dc?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 409 | "image": "photo-1552084162-ec07b3f162dc?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 410 | "panel": "photo-1552084162-ec07b3f162dc?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&h=200&q=70", 411 | }, 412 | "title": "Paweł Czerwiński", 413 | "description": "" 414 | 415 | }, { 416 | "source": { 417 | "modal": "photo-1484626753559-5fa3ea273ae8?ixlib=rb-1.2.1&auto=format&fit=crop&w=1920&q=90", 418 | "image": "photo-1484626753559-5fa3ea273ae8?ixlib=rb-1.2.1&auto=format&fit=crop&w=960&q=85", 419 | "panel": "photo-1484626753559-5fa3ea273ae8?ixlib=rb-1.2.1&auto=format&fit=crop&w=300&h=200&q=70", 420 | }, 421 | "title": "Petersen Automotive Museum, Los Angeles, United States", 422 | "description": "Denys Nevozhai" 423 | 424 | } 425 | 426 | ]; 427 | 428 | }]); 429 | -------------------------------------------------------------------------------- /demo/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schalkt/angular-super-gallery/43bdf1bfbf0b9c264613356164374f77943c25dd/demo/github.png -------------------------------------------------------------------------------- /demo/npmjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schalkt/angular-super-gallery/43bdf1bfbf0b9c264613356164374f77943c25dd/demo/npmjs.png -------------------------------------------------------------------------------- /demo/paypal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schalkt/angular-super-gallery/43bdf1bfbf0b9c264613356164374f77943c25dd/demo/paypal.png -------------------------------------------------------------------------------- /demo/preload.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /demo/svg/amazon-ws.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 29 | 64 | 66 | 68 | 70 | 72 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /demo/svg/asus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 26 | 27 | -------------------------------------------------------------------------------- /demo/svg/avast.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/svg/bluetooth.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 44 | -------------------------------------------------------------------------------- /demo/svg/burger-king.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 13 | 17 | 21 | 24 | 26 | 29 | 32 | 36 | 39 | 42 | 46 | 49 | 53 | 55 | 57 | 59 | 63 | 64 | -------------------------------------------------------------------------------- /demo/svg/continental.svg: -------------------------------------------------------------------------------- 1 | icon-i-logo -------------------------------------------------------------------------------- /demo/svg/hilti.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /demo/svg/sennheiser.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | Sennheiser Logo RGB 11 | 12 | 13 | -------------------------------------------------------------------------------- /dist/angular-super-gallery.min.css.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schalkt/angular-super-gallery/43bdf1bfbf0b9c264613356164374f77943c25dd/dist/angular-super-gallery.min.css.gz -------------------------------------------------------------------------------- /dist/angular-super-gallery.min.js.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schalkt/angular-super-gallery/43bdf1bfbf0b9c264613356164374f77943c25dd/dist/angular-super-gallery.min.js.gz -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require('./dist/angular-super-gallery.js'); 2 | module.exports = 'angularSuperGallery'; 3 | -------------------------------------------------------------------------------- /mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/dist/angular-super-gallery.min.js": "/dist/angular-super-gallery.min.js", 3 | "/dist/angular-super-gallery.min.css": "/dist/angular-super-gallery.min.css" 4 | } 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-super-gallery", 3 | "version": "2.2.29", 4 | "description": "AngularJS Super Gallery", 5 | "homepage": "https://projects.schalk.hu/angular-super-gallery/demo/", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/schalkt/angular-super-gallery.git" 9 | }, 10 | "keywords": [ 11 | "angular", 12 | "image", 13 | "gallery", 14 | "thumbnails", 15 | "component", 16 | "modal", 17 | "bootstrap" 18 | ], 19 | "scripts": { 20 | "dev": "npm run development", 21 | "development": "mix", 22 | "watch": "mix watch", 23 | "watch-poll": "mix watch -- --watch-options-poll=1000", 24 | "hot": "mix watch --hot", 25 | "prod": "npm run production", 26 | "production": "mix --production", 27 | "init": "npm prune && npm update && npm audit fix && npm run development", 28 | "release": "npm --no-git-tag-version version patch && npm run production" 29 | }, 30 | "author": "Tamas Schalk (https://github.com/schalkt)", 31 | "license": "MIT", 32 | "main": "index.js", 33 | "devDependencies": { 34 | "@types/angular": "1.8.9", 35 | "@types/angular-animate": "1.5.14", 36 | "@types/bootstrap": "4.*", 37 | "@types/jquery": "3.5.32", 38 | "compression-webpack-plugin": "^11.1.0", 39 | "cross-env": "^7.0.3", 40 | "i": "^0.3.7", 41 | "laravel-mix": "^6.0.49", 42 | "laravel-mix-angular-templatecache": "^1.0.1", 43 | "lodash": "^4.17.21", 44 | "postcss": "^8.5.3", 45 | "resolve-url-loader": "^5.0.0", 46 | "sass": "^1.88.0", 47 | "sass-loader": "^16.0.5", 48 | "ts-loader": "^9.5.2", 49 | "typescript": "5.8.3" 50 | }, 51 | "dependencies": { 52 | "angular": "1.8.3", 53 | "angular-animate": "1.8.3", 54 | "angular-touch": "1.8.3", 55 | "bootstrap": "4.*", 56 | "font-awesome": "4.7.0", 57 | "jquery": "3.7.1", 58 | "popper.js": "1.16.1", 59 | "screenfull": "6.0.2" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # AngularJS Super Gallery 2 | 3 | Image gallery based on **AngularJS** and **Bootstrap 4**. (for Bootstrap 3 switch to the bootstrap3 branch) 4 | 5 | [![npm](https://img.shields.io/npm/dt/angular-super-gallery.svg?style=flat-square)](https://www.npmjs.com/package/angular-super-gallery) 6 | [![GitHub issues](https://img.shields.io/github/issues/schalkt/angular-super-gallery.svg?style=flat-square)](https://github.com/schalkt/angular-super-gallery/issues) 7 | [![CodeQL](https://github.com/schalkt/angular-super-gallery/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/schalkt/angular-super-gallery/actions/workflows/codeql-analysis.yml) 8 | [![npm](https://img.shields.io/npm/v/angular-super-gallery.svg?style=flat-square)](https://www.npmjs.com/package/angular-super-gallery) 9 | 10 | [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=schalkt_angular-super-gallery&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=schalkt_angular-super-gallery) 11 | [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=schalkt_angular-super-gallery&metric=security_rating)](https://sonarcloud.io/dashboard?id=schalkt_angular-super-gallery) 12 | [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=schalkt_angular-super-gallery&metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=schalkt_angular-super-gallery) 13 | [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=schalkt_angular-super-gallery&metric=bugs)](https://sonarcloud.io/dashboard?id=schalkt_angular-super-gallery) 14 | 15 | ## Preview 16 | 17 | [![preview](https://img.shields.io/badge/preview-click_here-green.svg?style=flat-square)](https://projects.schalk.hu/angular-super-gallery/demo/) or check /demo/index.html 18 | 19 | ![angular-super-gallery-screenshot-1](https://projects.schalk.hu/angular-super-gallery/screenshot1.jpg) 20 | ![angular-super-gallery-screenshot-2](https://projects.schalk.hu/angular-super-gallery/screenshot2.jpg) 21 | 22 | ## Dependencies 23 | 24 | ```json 25 | { 26 | "angular": "1.8.0", 27 | "angular-animate": "1.8.0", 28 | "angular-touch": "1.8.0", 29 | "bootstrap": "4.5.0", 30 | "font-awesome": "4.7.0", 31 | "jquery": "3.5.1", 32 | "screenfull": "5.0.2" 33 | } 34 | ``` 35 | 36 | ## Features 37 | 38 | - separated Angular components (image, modal, thumbnail, panel, info and control) 39 | - highly configurable 40 | - image display modes (cover, contain, auto, stretch) 41 | - multiple image sizes : thumbnail (for panel) , medium (for image), original (for modal) 42 | - responsive and 4 built-in themes 43 | - 13 image transitions (CSS3 3D) 44 | - configurable keyboard shortcuts in modal window 45 | - events (config load, image load, modal open/close, autoplay, update, etc.) 46 | - placeholder image and loading animation 47 | - touch support (swipe) 48 | 49 | ## Install 50 | 51 | - `npm install --save angular-super-gallery` or `yarn add angular-super-gallery` 52 | 53 | ## Setup 54 | 55 | ```javascript 56 | import 'bootstrap/dist/css/bootstrap.min.css'; 57 | import 'angular-super-gallery/dist/angular-super-gallery.css'; 58 | import 'jquery'; 59 | import 'angular'; 60 | import 'bootstrap'; 61 | import 'angular-animate'; 62 | import 'angular-touch'; 63 | import 'screenfull'; 64 | import angularSuperGallery from 'angular-super-gallery'; 65 | 66 | angular.module("app", [angularSuperGallery]); 67 | ``` 68 | 69 | ## Quick usage in HTML 70 | 71 | ```html 72 | 78 | 79 | 80 | 81 | 82 | ``` 83 | 84 | ## Advanced usage 85 | 86 | setup in controller 87 | 88 | ```javascript 89 | this.showModal = false; 90 | this.nature1Options = { 91 | baseUrl: "https://", 92 | fields: { 93 | source: { 94 | modal: "link", 95 | image: "medium", 96 | panel: "thumbnail" 97 | } 98 | }, 99 | modal: { 100 | transition: 'zoomInOut' 101 | }, 102 | panel: { 103 | thumbnail: { 104 | class: "col-md-4" 105 | }, 106 | }, 107 | image: { 108 | transition: 'fadeInOut' 109 | } 110 | }; 111 | this.nature1 = [ 112 | { 113 | "link": "wallpaperscraft.com/image/nature_waterfall_summer_lake_trees_90400_1920x1080.jpg", 114 | "thumbnail": "i1.wallpaperscraft.com/image/nature_waterfall_summer_lake_trees_90400_300x188.jpg", 115 | "medium": "i1.wallpaperscraft.com/image/nature_waterfall_summer_lake_trees_90400_602x339.jpg", 116 | }, { 117 | "link": "wallpaperscraft.com/image/summer_mountains_nature_lake_river_grass_93164_1920x1080.jpg", 118 | "thumbnail": "i1.wallpaperscraft.com/image/summer_mountains_nature_lake_river_grass_93164_300x188.jpg", 119 | "medium": "i1.wallpaperscraft.com/image/summer_mountains_nature_lake_river_grass_93164_602x339.jpg", 120 | } 121 | ]; 122 | ``` 123 | 124 | in HTML 125 | 126 | ```html 127 | 128 | 129 | 130 | 131 | 132 | ``` 133 | 134 | or (without thumbnails) 135 | 136 | ```html 137 | 138 | 139 | 140 | 141 | ``` 142 | 143 | ## Available options 144 | 145 | ```javascript 146 | debug: false, // image load, autoplay, etc. info in console.log 147 | hashUrl: true, // enable/disable hash usage in url (#asg-nature-4) 148 | baseUrl: '', // url prefix 149 | duplicates: false, // enable or disable same images (url) in gallery 150 | selected: 0, // selected image on init 151 | fields: { 152 | source: { 153 | modal: 'url', // required, image url for modal component (large size) 154 | panel: 'url', // image url for panel component (thumbnail size) 155 | image: 'url', // image url for image (medium or custom size) 156 | placeholder: null // image url for preload lowres image 157 | }, 158 | title: 'title', // title field name 159 | description: 'description', // description field name 160 | }, 161 | autoplay: { 162 | enabled: false, // slideshow play enabled/disabled 163 | delay: 4100 // autoplay delay in millisecond 164 | }, 165 | theme: 'default', // css style [default, darkblue, darkred, whitegold] 166 | preloadNext: false, // preload next image (forward/backward) 167 | preloadDelay: 770, // preload delay for preloadNext 168 | loadingImage: 'preload.svg', // loader image 169 | preload: [], // preload images by index number 170 | modal: { 171 | title: '', // modal window title 172 | subtitle: '', // modal window subtitle 173 | titleFromImage: false, // force update the gallery title by image title 174 | subtitleFromImage: false, // force update the gallery subtitle by image description 175 | placeholder: 'panel', // set image placeholder source type (thumbnail) or full url (http...) 176 | caption: { 177 | disabled: false, // disable image caption 178 | visible: true, // show/hide image caption 179 | position: 'top', // caption position [top, bottom] 180 | download: false // show/hide download link 181 | }, 182 | header: { 183 | enabled: true, // enable/disable modal menu 184 | dynamic: false, // show/hide modal menu on mouseover 185 | buttons: ['playstop', 'index', 'prev', 'next', 'pin', 'size', 'transition', 'thumbnails', 'fullscreen', 'help', 'close'], 186 | }, 187 | help: false, // show/hide help 188 | arrows: { 189 | enabled: true, // show/hide arrows 190 | preload: true, // preload image on mouseover 191 | }, 192 | click: { 193 | close: true // when click on the image close the modal 194 | }, 195 | thumbnail: { 196 | height: 50, // thumbnail image height in pixel 197 | index: false, // show index number on thumbnail 198 | enabled: true, // enable/disable thumbnails 199 | dynamic: false, // if true thumbnails visible only when mouseover 200 | autohide: true, // hide thumbnail component when single image 201 | click: { 202 | select: true, // set selected image when true 203 | modal: false // open modal when true 204 | }, 205 | hover: { 206 | preload: true, // preload image on mouseover 207 | select: false // set selected image on mouseover when true 208 | }, 209 | }, 210 | transition: 'slideLR', // transition effect 211 | transitionSpeed: 0.7, // transition speed 0.7s 212 | size: 'cover', // contain, cover, auto, stretch 213 | keycodes: { 214 | exit: [27], // esc 215 | playpause: [80], // p 216 | forward: [32, 39], // space, right arrow 217 | backward: [37], // left arrow 218 | first: [38, 36], // up arrow, home 219 | last: [40, 35], // down arrow, end 220 | fullscreen: [13], // enter 221 | menu: [77], // m 222 | caption: [67], // c 223 | help: [72], // h 224 | size: [83], // s 225 | transition: [84] // t 226 | } 227 | }, 228 | thumbnail: { 229 | height: 50, // thumbnail image height in pixel 230 | index: false, // show index number on thumbnail 231 | dynamic: false, // if true thumbnails visible only when mouseover 232 | autohide: false, // hide thumbnail component when single image 233 | click: { 234 | select: true, // set selected image when true 235 | modal: false // open modal when true 236 | }, 237 | hover: { 238 | preload: true, // preload image on mouseover 239 | select: false // set selected image on mouseover when true 240 | }, 241 | }, 242 | panel: { 243 | visible: true, 244 | item: { 245 | class: 'col-md-3', // item class 246 | caption: false, // show/hide image caption 247 | index: false, // show/hide image index 248 | }, 249 | hover: { 250 | preload: true, // preload image on mouseover 251 | select: false // set selected image on mouseover when true 252 | }, 253 | click: { 254 | select: false, // set selected image when true 255 | modal: true // open modal when true 256 | }, 257 | }, 258 | image: { 259 | transition: 'slideLR', // transition effect 260 | transitionSpeed: 0.7, // transition speed 0.7s 261 | size: 'cover', // contain, cover, auto, stretch 262 | arrows: { 263 | enabled: true, // show/hide arrows 264 | preload: true, // preload image on mouseover 265 | }, 266 | click: { 267 | modal: true // when click on the image open the modal window 268 | }, 269 | height: null, // height in pixel 270 | heightMin: null, // min height in pixel 271 | heightAuto: { 272 | initial: true, // calculate div height by first image 273 | onresize: false // calculate div height on window resize 274 | }, 275 | placeholder: 'panel' // set image placeholder source type (thumbnail) or full url (http...) 276 | } 277 | ``` 278 | 279 | ## Edit 280 | 281 | ### Add new image or images to the gallery by id 282 | 283 | ```javascript 284 | $rootScope.$broadcast('ASG-gallery-edit', { 285 | id: 'nature', 286 | add: [{ 287 | "link": "wallpaperscraft.com/image/tree_fog_nature_beautiful_84257_1920x1080.jpg", 288 | "thumbnail": "images.wallpaperscraft.com/image/tree_fog_nature_beautiful_84257_300x168.jpg", 289 | "medium": "images.wallpaperscraft.com/image/tree_fog_nature_beautiful_84257_960x544.jpg", 290 | }] 291 | }); 292 | ``` 293 | 294 | ### Update gallery options and set selected image 295 | 296 | ```javascript 297 | $rootScope.$broadcast('ASG-gallery-edit', { 298 | id: 'nature', 299 | selected: 0, 300 | options: this.options1 301 | }); 302 | ``` 303 | 304 | ### Reload gallery images 305 | 306 | ```javascript 307 | $rootScope.$broadcast('ASG-gallery-edit', { 308 | id: 'nature', 309 | refresh: true 310 | }); 311 | ``` 312 | 313 | ### Delete image 314 | 315 | ```javascript 316 | $rootScope.$broadcast('ASG-gallery-edit', { 317 | id: 'nature', 318 | delete: null // index number or null for delete selected image 319 | }); 320 | ``` 321 | 322 | ### Update gallery images 323 | 324 | ```javascript 325 | $rootScope.$broadcast('ASG-gallery-edit', { 326 | id: 'nature', 327 | update: ['image1url', 'image2url', {source: {image: 'image3url', title: 'image3title'}}]; // use image url or object 328 | }); 329 | ``` 330 | 331 | ## Transitions 332 | 333 | - no 334 | - fadeInOut 335 | - zoomIn 336 | - zoomOut 337 | - zoomInOut 338 | - rotateLR 339 | - rotateTB 340 | - rotateZY 341 | - slideLR 342 | - slideTB 343 | - zlideLR 344 | - zlideTB 345 | - flipX 346 | - flipY 347 | 348 | ## Default keyboard shortcuts in modal window 349 | 350 | - RIGHT / SPACE : forward 351 | - LEFT : backward 352 | - UP / HOME : first 353 | - DOWN / END : last 354 | - ESC : exit 355 | - ENTER : toggle fullscreen 356 | - p : play/pause 357 | - t : change transition effect 358 | - m : toggle menu 359 | - s : toggle image size 360 | - c : toggle caption 361 | - h : toggle help 362 | 363 | ## Events 364 | 365 | - CONFIG_LOAD: `ASG-config-load-[gallery id]`, 366 | - AUTOPLAY_START: `ASG-autoplay-start-[gallery id]`, 367 | - AUTOPLAY_STOP: `ASG-autoplay-stop-[gallery id]`, 368 | - PARSE_IMAGES: `ASG-parse-images-[gallery id]`, 369 | - FIRST_IMAGE: `ASG-first-image-[gallery id]`, 370 | - LOAD_IMAGE: `ASG-load-image-[gallery id]`, 371 | - CHANGE_IMAGE: `ASG-change-image-[gallery id]`, 372 | - MODAL_OPEN: `ASG-modal-open-[gallery id]`, 373 | - MODAL_CLOSE: `ASG-modal-close-[gallery id]`, 374 | - THUMBNAIL_MOVE: `ASG-thumbnail-move-[gallery id]`, 375 | 376 | ## Build 377 | 378 | - Node.js 12 recommended 379 | - `npm install` 380 | - `npm run dev` 381 | - `npm run prod` (minified javascript and css file) 382 | - `npm run watch` (automatic build under development) 383 | 384 | ## Todo 385 | 386 | - Vimeo video player [WIP] 387 | - slideshow mode (fullscreen, hide menu and arrows, start autoplay) 388 | - indicator component 389 | - theme color setup 390 | - remove caption from modal and add asg-info 391 | - control component custom buttons 392 | - header component with controls = modal header? 393 | - fix info component image width and height data 394 | - exit button must be visible on modal when menubar hidden 395 | - load images and config from API endpoint 396 | - add edit mode (upload, delete, rename, etc.) for admin page 397 | - options and info menu in modal 398 | - image zoom / drag / rotate 399 | - image info (original width and height / bytes) 400 | - preloader svg fix in Microsoft Edge (or fix Edge :) 401 | - remember website hash and set back when modal closed? 402 | 403 | ## Photos 404 | 405 | [unsplash.com](https://unsplash.com/) 406 | 407 | ## License 408 | 409 | MIT 410 | -------------------------------------------------------------------------------- /screenshot1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schalkt/angular-super-gallery/43bdf1bfbf0b9c264613356164374f77943c25dd/screenshot1.jpg -------------------------------------------------------------------------------- /screenshot2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schalkt/angular-super-gallery/43bdf1bfbf0b9c264613356164374f77943c25dd/screenshot2.jpg -------------------------------------------------------------------------------- /src/asg-control.ts: -------------------------------------------------------------------------------- 1 | namespace angularSuperGallery { 2 | 3 | export class ControlController { 4 | 5 | public id: string; 6 | private type = 'control'; 7 | private asg: IServiceController; 8 | private template; 9 | 10 | constructor( 11 | private service: IServiceController, 12 | private $scope: IScope) { 13 | 14 | this.template = '/views/asg-control.html'; 15 | 16 | } 17 | 18 | public $onInit() { 19 | 20 | // get service instance 21 | this.asg = this.service.getInstance(this); 22 | 23 | this.$scope.forward = () => { 24 | this.asg.toForward(true); 25 | }; 26 | 27 | this.$scope.backward = () => { 28 | this.asg.toBackward(true); 29 | }; 30 | 31 | } 32 | 33 | 34 | // get image config 35 | public get config(): IOptionsImage { 36 | 37 | return this.asg ? this.asg.options[this.type] : null; 38 | 39 | } 40 | 41 | // set image config 42 | public set config(value: IOptionsImage) { 43 | 44 | this.asg.options[this.type] = value; 45 | 46 | } 47 | 48 | // set selected image 49 | public set selected(v: number) { 50 | 51 | if (this.asg) { 52 | this.asg.selected = v; 53 | } 54 | 55 | } 56 | 57 | // get selected image 58 | public get selected() { 59 | 60 | return this.asg ? this.asg.selected : null; 61 | 62 | } 63 | 64 | } 65 | 66 | let app: ng.IModule = angular.module('angularSuperGallery'); 67 | 68 | app.component('asgControl', { 69 | controller: ['asgService', '$scope', angularSuperGallery.ControlController], 70 | template: '
', 71 | bindings: { 72 | id: '@?', 73 | selected: '=?', 74 | template: '@?' 75 | } 76 | }); 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/asg-debug.ts: -------------------------------------------------------------------------------- 1 | namespace angularSuperGallery { 2 | 3 | export class DebugController { 4 | 5 | public id: string; 6 | private asg: IServiceController; 7 | private type; 8 | private template; 9 | 10 | constructor( 11 | private service: IServiceController, 12 | private $scope: ng.IScope) { 13 | 14 | this.type = 'info'; 15 | this.template = '/views/asg-debug.html'; 16 | 17 | } 18 | 19 | public $onInit() { 20 | 21 | // get service instance 22 | this.asg = this.service.getInstance(this); 23 | 24 | } 25 | 26 | public get file() { 27 | return this.asg ? this.asg.file : null; 28 | } 29 | 30 | } 31 | 32 | let app: ng.IModule = angular.module('angularSuperGallery'); 33 | 34 | app.component('asgDebug', { 35 | controller: ['asgService', '$scope', angularSuperGallery.DebugController], 36 | template: '
', 37 | transclude: true, 38 | bindings: { 39 | id: '@?', 40 | template: '@?' 41 | } 42 | }); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/asg-image.ts: -------------------------------------------------------------------------------- 1 | 2 | namespace angularSuperGallery { 3 | 4 | export class ImageController { 5 | 6 | public id: string; 7 | public options: IOptions; 8 | public items: Array; 9 | public baseUrl: string; 10 | 11 | private type = 'image'; 12 | private asg: IServiceController; 13 | 14 | constructor(private service: IServiceController, 15 | private $rootScope: ng.IRootScopeService, 16 | private $element: ng.IRootElementService, 17 | private $timeout: ng.ITimeoutService, 18 | private $window: ng.IWindowService, 19 | private $scope: ng.IScope) { 20 | 21 | angular.element($window).bind('resize', (event) => { 22 | this.onResize(); 23 | }); 24 | 25 | } 26 | 27 | private onResize() { 28 | 29 | if (this.config.heightAuto.onresize) { 30 | this.setHeight(this.asg.file); 31 | } 32 | 33 | } 34 | 35 | public $onInit() { 36 | 37 | // get service instance 38 | this.asg = this.service.getInstance(this); 39 | 40 | const self = this; 41 | 42 | // set image component height 43 | this.$rootScope.$on(this.asg.events.FIRST_IMAGE + this.id, (event, data) => { 44 | 45 | if (!this.config.height && this.config.heightAuto.initial === true) { 46 | this.$timeout(() => { 47 | self.setHeight(data.img); 48 | }, 10); 49 | } 50 | 51 | }); 52 | 53 | // scope apply when image loaded 54 | this.$rootScope.$on(this.asg.events.LOAD_IMAGE + this.id, (event, data) => { 55 | 56 | this.$scope.$apply(); 57 | 58 | }); 59 | 60 | } 61 | 62 | // set image component height 63 | private setHeight(img) { 64 | 65 | let width = this.$element.children('div')[0].clientWidth; 66 | let ratio = img.width / img.height; 67 | this.config.height = width / ratio; 68 | 69 | } 70 | 71 | // height 72 | public get height() { 73 | 74 | return this.config.height; 75 | 76 | } 77 | 78 | 79 | // get image config 80 | public get config(): IOptionsImage { 81 | 82 | return this.asg ? this.asg.options[this.type] : null; 83 | 84 | } 85 | 86 | // set image config 87 | public set config(value: IOptionsImage) { 88 | 89 | this.asg.options[this.type] = value; 90 | 91 | } 92 | 93 | public toBackward(stop?: boolean, $event?: UIEvent) { 94 | 95 | if ($event) { 96 | $event.stopPropagation(); 97 | } 98 | 99 | this.asg.toBackward(stop); 100 | 101 | } 102 | 103 | public toForward(stop?: boolean, $event?: UIEvent) { 104 | 105 | if ($event) { 106 | $event.stopPropagation(); 107 | } 108 | 109 | this.asg.toForward(stop); 110 | 111 | } 112 | 113 | public hover(index: number, $event?: MouseEvent) { 114 | 115 | if (this.config.arrows.preload === true) { 116 | this.asg.hoverPreload(index); 117 | } 118 | 119 | } 120 | 121 | // set selected image 122 | public set selected(v: number) { 123 | 124 | if (this.asg) { 125 | this.asg.selected = v; 126 | } 127 | 128 | } 129 | 130 | // get selected image 131 | public get selected() { 132 | 133 | return this.asg ? this.asg.selected : null; 134 | 135 | } 136 | 137 | // modal available 138 | public get modalAvailable() { 139 | 140 | return this.asg.modalAvailable && this.config.click.modal; 141 | 142 | } 143 | 144 | // open the modal 145 | public modalOpen($event: UIEvent) { 146 | 147 | if ($event) { 148 | $event.stopPropagation(); 149 | } 150 | 151 | if (this.config.click.modal) { 152 | this.asg.modalOpen(this.asg.selected); 153 | } 154 | 155 | } 156 | 157 | public playVideo($event: UIEvent) { 158 | 159 | if ($event) { 160 | $event.stopPropagation(); 161 | } 162 | 163 | const self = this; 164 | 165 | this.asg.file.video.visible = true; 166 | this.asg.file.video.htmlId = 'vimeo_video_' + this.asg.file.video.vimeoId; 167 | 168 | let player; 169 | 170 | const options = { 171 | id: this.asg.file.video.vimeoId, 172 | responsive: true, 173 | loop: false 174 | }; 175 | 176 | if (this.asg.file.video.player) { 177 | player = this.asg.file.video.player; 178 | } else { 179 | player = new Vimeo.Player(this.asg.file.video.htmlId, options); 180 | } 181 | 182 | // player.loadVideo(this.asg.file.video.vimeoId).then(function(id) { 183 | 184 | // }) 185 | 186 | player.setVolume(0.5); 187 | 188 | player.play().catch(function (error) { 189 | console.error('error playing the video:', error); 190 | }) 191 | 192 | player.on('play', function() { 193 | self.asg.file.video.playing = true; 194 | }); 195 | 196 | player.on('pause', function() { 197 | self.asg.file.video.playing = false 198 | }); 199 | 200 | this.asg.file.video.player = player; 201 | this.asg.file.video.playing = true; 202 | 203 | } 204 | 205 | } 206 | 207 | let app: ng.IModule = angular.module('angularSuperGallery'); 208 | 209 | app.component('asgImage', { 210 | controller: ['asgService', '$rootScope', '$element', '$timeout', '$window', '$scope', angularSuperGallery.ImageController], 211 | templateUrl: '/views/asg-image.html', 212 | transclude: true, 213 | bindings: { 214 | id: '@?', 215 | items: '=?', 216 | options: '=?', 217 | selected: '=?', 218 | baseUrl: '@?' 219 | } 220 | }); 221 | 222 | 223 | } 224 | -------------------------------------------------------------------------------- /src/asg-info.ts: -------------------------------------------------------------------------------- 1 | namespace angularSuperGallery { 2 | 3 | export class InfoController { 4 | 5 | public id: string; 6 | private asg: IServiceController; 7 | private type; 8 | private template; 9 | 10 | constructor( 11 | private service: IServiceController, 12 | private $scope: ng.IScope) { 13 | 14 | this.type = 'info'; 15 | this.template = '/views/asg-info.html'; 16 | 17 | } 18 | 19 | public $onInit() { 20 | 21 | // get service instance 22 | this.asg = this.service.getInstance(this); 23 | 24 | } 25 | 26 | public get file() { 27 | return this.asg.file; 28 | } 29 | 30 | } 31 | 32 | let app: ng.IModule = angular.module('angularSuperGallery'); 33 | 34 | app.component('asgInfo', { 35 | controller: ['asgService', '$scope', angularSuperGallery.InfoController], 36 | template: '
', 37 | transclude: true, 38 | bindings: { 39 | id: '@?', 40 | template: '@?' 41 | } 42 | }); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/asg-modal.ts: -------------------------------------------------------------------------------- 1 | namespace angularSuperGallery { 2 | 3 | export class ModalController { 4 | 5 | public id : string; 6 | public options : IOptions; 7 | public items : Array; 8 | public baseUrl : string; 9 | 10 | private type = 'modal'; 11 | private asg : IServiceController; 12 | private arrowsVisible = false; 13 | 14 | constructor(private service : IServiceController, 15 | private $window : ng.IWindowService, 16 | private $rootScope : ng.IRootScopeService, 17 | private $scope : ng.IScope) { 18 | 19 | } 20 | 21 | 22 | public $onInit() { 23 | 24 | // get service instance 25 | this.asg = this.service.getInstance(this); 26 | this.asg.modalAvailable = true; 27 | 28 | // scope apply when image loaded 29 | this.$rootScope.$on(this.asg.events.LOAD_IMAGE + this.id, (event, data) => { 30 | this.$scope.$apply(); 31 | }); 32 | 33 | } 34 | 35 | 36 | private getClass() { 37 | 38 | if (!this.config) { 39 | return; 40 | } 41 | 42 | let ngClass = []; 43 | 44 | if (this.config.header.dynamic) { 45 | ngClass.push('dynamic'); 46 | } 47 | 48 | ngClass.push(this.asg.options.theme); 49 | 50 | return ngClass.join(' '); 51 | 52 | } 53 | 54 | // get action from keycodes 55 | private getActionByKeyCode(keyCode : number) { 56 | 57 | let keys = Object.keys(this.config.keycodes); 58 | let action; 59 | 60 | for (let key in keys) { 61 | 62 | let codes = this.config.keycodes[keys[key]]; 63 | 64 | if (!codes) { 65 | continue; 66 | } 67 | 68 | let index = codes.indexOf(keyCode); 69 | 70 | if (index > -1) { 71 | action = keys[key]; 72 | break; 73 | } 74 | 75 | } 76 | 77 | return action; 78 | 79 | } 80 | 81 | 82 | public close($event? : UIEvent) { 83 | 84 | this.asg.modalClick($event); 85 | this.asg.modalClose(); 86 | this.exitFullScreen(); 87 | 88 | } 89 | 90 | public imageClick($event? : UIEvent) { 91 | 92 | this.asg.modalClick($event); 93 | 94 | if (this.config.click.close) { 95 | this.asg.modalClose(); 96 | this.exitFullScreen(); 97 | } 98 | 99 | } 100 | 101 | public hover(index : number, $event? : MouseEvent) { 102 | 103 | if (this.config.arrows.preload === true) { 104 | this.asg.hoverPreload(index); 105 | } 106 | 107 | } 108 | 109 | public setFocus($event? : UIEvent) { 110 | 111 | this.asg.modalClick($event); 112 | 113 | } 114 | 115 | public autoPlayToggle($event? : UIEvent) { 116 | 117 | this.asg.modalClick($event); 118 | this.asg.autoPlayToggle(); 119 | 120 | } 121 | 122 | public toFirst(stop? : boolean, $event? : UIEvent) { 123 | 124 | this.asg.modalClick($event); 125 | this.asg.toFirst(); 126 | 127 | } 128 | 129 | public toBackward(stop? : boolean, $event? : UIEvent) { 130 | 131 | this.asg.modalClick($event); 132 | this.asg.toBackward(stop); 133 | 134 | } 135 | 136 | public toForward(stop? : boolean, $event? : UIEvent) { 137 | 138 | this.asg.modalClick($event); 139 | this.asg.toForward(stop); 140 | 141 | } 142 | 143 | public toLast(stop? : boolean, $event? : UIEvent) { 144 | 145 | this.asg.modalClick($event); 146 | this.asg.toLast(stop); 147 | 148 | } 149 | 150 | // do keyboard action 151 | public keyUp(e : KeyboardEvent) { 152 | 153 | let action : string = this.getActionByKeyCode(e.keyCode); 154 | 155 | switch (action) { 156 | 157 | case 'exit': 158 | this.close(); 159 | break; 160 | 161 | case 'playpause': 162 | this.asg.autoPlayToggle(); 163 | break; 164 | 165 | case 'forward': 166 | this.asg.toForward(true); 167 | break; 168 | 169 | case 'backward': 170 | this.asg.toBackward(true); 171 | break; 172 | 173 | case 'first': 174 | this.asg.toFirst(true); 175 | break; 176 | 177 | case 'last': 178 | this.asg.toLast(true); 179 | break; 180 | 181 | case 'fullscreen': 182 | this.toggleFullScreen(); 183 | break; 184 | 185 | case 'menu': 186 | this.toggleMenu(); 187 | break; 188 | 189 | case 'caption': 190 | this.toggleCaption(); 191 | break; 192 | 193 | case 'help': 194 | this.toggleHelp(); 195 | break; 196 | 197 | case 'size': 198 | this.toggleSize(); 199 | break; 200 | 201 | case 'transition': 202 | this.nextTransition(); 203 | break; 204 | 205 | default: 206 | this.asg.log('unknown keyboard action: ' + e.keyCode); 207 | break; 208 | 209 | } 210 | 211 | } 212 | 213 | 214 | // switch to next transition effect 215 | private nextTransition($event? : UIEvent) { 216 | 217 | this.asg.modalClick($event); 218 | let idx = this.asg.transitions.indexOf(this.config.transition) + 1; 219 | let next = idx >= this.asg.transitions.length ? 0 : idx; 220 | this.config.transition = this.asg.transitions[next]; 221 | 222 | } 223 | 224 | // toggle fullscreen 225 | private toggleFullScreen($event? : UIEvent) { 226 | 227 | this.asg.modalClick($event); 228 | 229 | if (!this.$window.screenfull) { 230 | return; 231 | } 232 | 233 | this.$window.screenfull.toggle(); 234 | 235 | } 236 | 237 | // exit fullscreen 238 | private exitFullScreen() { 239 | 240 | if (!this.$window.screenfull) { 241 | return; 242 | } 243 | 244 | if (!this.$window.screenfull.isFullscreen) { 245 | return; 246 | } 247 | 248 | this.$window.screenfull.exit(); 249 | 250 | } 251 | 252 | // toggle thumbnails 253 | private toggleThumbnails($event? : UIEvent) { 254 | 255 | this.asg.modalClick($event); 256 | this.config.thumbnail.dynamic = !this.config.thumbnail.dynamic; 257 | 258 | } 259 | 260 | // set transition effect 261 | public setTransition(transition, $event? : UIEvent) { 262 | 263 | this.asg.modalClick($event); 264 | this.config.transition = transition; 265 | 266 | } 267 | 268 | // set theme 269 | public setTheme(theme : string, $event? : UIEvent) { 270 | 271 | this.asg.modalClick($event); 272 | this.asg.options.theme = theme; 273 | 274 | } 275 | 276 | // toggle help 277 | private toggleHelp($event? : UIEvent) { 278 | 279 | this.asg.modalClick($event); 280 | this.config.help = !this.config.help; 281 | 282 | } 283 | 284 | // toggle size 285 | private toggleSize($event? : UIEvent) { 286 | 287 | this.asg.modalClick($event); 288 | let index = this.asg.sizes.indexOf(this.config.size); 289 | index = (index + 1) >= this.asg.sizes.length ? 0 : ++index; 290 | this.config.size = this.asg.sizes[index]; 291 | this.asg.log('toggle image size:', [this.config.size, index]); 292 | 293 | } 294 | 295 | // toggle menu 296 | private toggleMenu($event? : UIEvent) { 297 | 298 | this.asg.modalClick($event); 299 | this.config.header.dynamic = !this.config.header.dynamic; 300 | 301 | } 302 | 303 | // toggle caption 304 | private toggleCaption() { 305 | 306 | this.config.caption.visible = !this.config.caption.visible; 307 | 308 | } 309 | 310 | // get margint top 311 | public get marginTop() { 312 | 313 | return this.config.marginTop; 314 | 315 | } 316 | 317 | // get margin bottom 318 | public get marginBottom() { 319 | 320 | return this.config.marginBottom; 321 | 322 | } 323 | 324 | // get modal visible 325 | public get visible() { 326 | 327 | return this.asg ? this.asg.modalVisible : null; 328 | 329 | } 330 | 331 | // set modal visible 332 | public set visible(value : boolean) { 333 | 334 | if (!this.asg) { 335 | return; 336 | } 337 | 338 | this.asg.modalVisible = value; 339 | this.asg.setHash(); 340 | 341 | } 342 | 343 | // set selected image 344 | public set selected(v : number) { 345 | 346 | if (!this.asg) { 347 | return; 348 | } 349 | 350 | this.asg.selected = v; 351 | 352 | } 353 | 354 | // get selected image 355 | public get selected() { 356 | 357 | return this.asg ? this.asg.selected : null; 358 | 359 | } 360 | 361 | // get modal config 362 | public get config() : IOptionsModal { 363 | 364 | return this.asg.options[this.type]; 365 | 366 | } 367 | 368 | // set modal config 369 | public set config(value : IOptionsModal) { 370 | 371 | this.asg.options[this.type] = value; 372 | 373 | } 374 | 375 | } 376 | 377 | 378 | let app : ng.IModule = angular.module('angularSuperGallery'); 379 | 380 | app.component('asgModal', { 381 | controller: ['asgService', '$window', '$rootScope', '$scope', angularSuperGallery.ModalController], 382 | templateUrl: '/views/asg-modal.html', 383 | transclude: true, 384 | bindings: { 385 | id: '@?', 386 | items: '=?', 387 | options: '=?', 388 | selected: '=?', 389 | visible: '=?', 390 | baseUrl: '@?' 391 | } 392 | }); 393 | 394 | } 395 | -------------------------------------------------------------------------------- /src/asg-panel.ts: -------------------------------------------------------------------------------- 1 | namespace angularSuperGallery { 2 | 3 | export class PanelController { 4 | 5 | public id: string; 6 | public options: IOptions; 7 | public items: Array; 8 | public baseUrl: string; 9 | 10 | private type = 'panel'; 11 | private template; 12 | private asg: IServiceController; 13 | 14 | constructor( 15 | private service: IServiceController, 16 | private $scope: ng.IScope) { 17 | 18 | this.template = '/views/asg-panel.html'; 19 | 20 | } 21 | 22 | public $onInit() { 23 | 24 | // get service instance 25 | this.asg = this.service.getInstance(this); 26 | 27 | } 28 | 29 | // set selected image 30 | public setSelected(index: number, $event?: MouseEvent) { 31 | 32 | this.asg.modalClick($event); 33 | 34 | if (this.config.click.modal) { 35 | this.asg.modalOpen(index); 36 | return; 37 | } 38 | 39 | if (this.config.click.select) { 40 | this.asg.setSelected(index); 41 | } 42 | 43 | } 44 | 45 | public hover(index: number, $event?: MouseEvent) { 46 | 47 | if (this.config.hover.preload === true) { 48 | this.asg.hoverPreload(index); 49 | } 50 | 51 | if (this.config.hover.select === true) { 52 | this.asg.setSelected(index); 53 | } 54 | 55 | } 56 | 57 | // get panel config 58 | public get config(): IOptionsPanel { 59 | 60 | return this.asg.options[this.type]; 61 | 62 | } 63 | 64 | // set panel config 65 | public set config(value: IOptionsPanel) { 66 | 67 | this.asg.options[this.type] = value; 68 | 69 | } 70 | 71 | // set selected image 72 | public set selected(v: number) { 73 | 74 | if (!this.asg) { 75 | return; 76 | } 77 | 78 | this.asg.selected = v; 79 | 80 | } 81 | 82 | // get selected image 83 | public get selected() { 84 | 85 | return this.asg ? this.asg.selected : null; 86 | 87 | } 88 | 89 | } 90 | 91 | let app: ng.IModule = angular.module('angularSuperGallery'); 92 | 93 | app.component('asgPanel', { 94 | controller: ['asgService', '$scope', angularSuperGallery.PanelController], 95 | template: '
', 96 | transclude: true, 97 | bindings: { 98 | id: '@', 99 | items: '=?', 100 | options: '=?', 101 | selected: '=?', 102 | visible: '=?', 103 | template: '@?', 104 | baseUrl: '@?' 105 | } 106 | }); 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/asg-templates.js: -------------------------------------------------------------------------------- 1 | angular.module('angularSuperGallery').run(['$templateCache', function($templateCache) { 2 | $templateCache.put('/views/asg-control.html','\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n'); 3 | $templateCache.put('/views/asg-debug.html','
    \r\n    {{ $ctrl.file | json }}    \r\n
\r\n
\r\n
        \r\n    {{ $ctrl.service.instances.abstracts.options | json }}\r\n
'); 4 | $templateCache.put('/views/asg-help.html','
    \r\n\t
  • SPACE : forward
  • \r\n\t
  • RIGHT : forward
  • \r\n\t
  • LEFT : backward
  • \r\n\t
  • UP / HOME : first
  • \r\n\t
  • DOWN / END : last
  • \r\n\t
  • ENTER : toggle fullscreen
  • \r\n\t
  • ESC : exit
  • \r\n\t
  • p : play/pause
  • \r\n\t
  • t : change transition effect
  • \r\n\t
  • m : toggle menu
  • \r\n\t
  • s : toggle image size
  • \r\n\t
  • c : toggle caption
  • \r\n\t
  • h : toggle help
  • \r\n
'); 5 | $templateCache.put('/views/asg-image.html','\r\n
\r\n\r\n\t
\r\n\r\n\t\t
\r\n\r\n\t\t\t
\r\n\t\t\t
\r\n\r\n\t\t\t
\r\n\r\n\t\t\t
\r\n\t\t\t\t
\r\n\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\r\n\t\t\t\t
\r\n\t\t\t
\r\n\t\t
\r\n\t
\r\n\r\n\t
\r\n\t\t\r\n\t
\r\n\r\n\t
\r\n\t\t\r\n\t
\r\n\r\n\t\r\n\r\n
\r\n'); 6 | $templateCache.put('/views/asg-info.html','
\r\n\r\n\t
\r\n\t\t

{{ $ctrl.file.title }}

\r\n\t
\r\n\r\n\t
\r\n\t\t{{ $ctrl.file.description }}\r\n\t\t\r\n\t
\r\n\r\n
\r\n\r\n\r\n'); 7 | $templateCache.put('/views/asg-modal.html','
\r\n\r\n
\r\n\r\n
\r\n\r\n
\r\n\r\n \r\n\t\t\t\t\r\n \r\n\r\n \r\n\t\t\t\t\r\n \r\n\r\n \r\n\t\t\t\t{{ $ctrl.config.title }}\r\n {{ $ctrl.config.subtitle }}\r\n \r\n\r\n
\r\n\r\n
\r\n\r\n
\r\n\r\n\t\t\t
\r\n\t\t\t\t\r\n\t\t\t
\r\n\r\n\t\t\t
\r\n\t\t\t\t\r\n\t\t\t
\r\n\r\n
\r\n\r\n
\r\n
\r\n
\r\n\r\n
\r\n\r\n
\r\n
\r\n {{ $ctrl.asg.file.title }}\r\n - \r\n {{ $ctrl.asg.file.description }}\r\n \r\n Download\r\n \r\n
\r\n
\r\n\r\n
\r\n\r\n \r\n\r\n
\r\n\r\n
\r\n'); 8 | $templateCache.put('/views/asg-panel.html','
\r\n\r\n
\r\n\r\n {{ file.title }}\r\n\r\n
\r\n {{ key + 1 }}\r\n {{ file.title }}\r\n
\r\n
\r\n\r\n
'); 9 | $templateCache.put('/views/asg-thumbnail.html','
\r\n
\r\n\r\n {{ file.title }}\r\n\r\n {{ key + 1 }}\r\n\r\n
\r\n
'); 10 | $templateCache.put('/views/button/asg-close.html','\n'); 11 | $templateCache.put('/views/button/asg-fullscreen.html','\r\n'); 12 | $templateCache.put('/views/button/asg-help.html','\n'); 13 | $templateCache.put('/views/button/asg-index-xs.html','\n'); 14 | $templateCache.put('/views/button/asg-index.html',''); 15 | $templateCache.put('/views/button/asg-next.html','\r\n'); 16 | $templateCache.put('/views/button/asg-pin.html','\n'); 17 | $templateCache.put('/views/button/asg-playstop.html','\r\n'); 18 | $templateCache.put('/views/button/asg-prev.html','\r\n'); 19 | $templateCache.put('/views/button/asg-size.html',''); 20 | $templateCache.put('/views/button/asg-thumbnails.html','\r\n'); 21 | $templateCache.put('/views/button/asg-transition.html','\r\n'); 22 | }]); 23 | -------------------------------------------------------------------------------- /src/asg-thumbnail.ts: -------------------------------------------------------------------------------- 1 | namespace angularSuperGallery { 2 | 3 | export class ThumbnailController { 4 | 5 | public id: string; 6 | public options: IOptions; 7 | public items: Array; 8 | public baseUrl: string; 9 | 10 | private type = 'thumbnail'; 11 | private template; 12 | private asg: IServiceController; 13 | private modal = false; 14 | private loaded = 0; 15 | 16 | constructor( 17 | private service: IServiceController, 18 | private $scope: IScope, 19 | private $rootScope: ng.IRootScopeService, 20 | private $element: ng.IRootElementService, 21 | private $timeout: ng.ITimeoutService) { 22 | 23 | this.template = '/views/asg-thumbnail.html'; 24 | 25 | } 26 | 27 | public $onInit() { 28 | 29 | // get service instance 30 | this.asg = this.service.getInstance(this); 31 | 32 | const self = this; 33 | 34 | // get parent asg component (modal) 35 | if (this.$scope && this.$scope.$parent && this.$scope.$parent.$parent && this.$scope.$parent.$parent['$ctrl']) { 36 | this.modal = this.$scope.$parent.$parent['$ctrl'].type === 'modal' ? true : false; 37 | } 38 | 39 | this.$rootScope.$on(this.asg.events.LAST_THUMBNAIL + this.id, (event, data) => { 40 | 41 | self.asg.thumbnailsMove(10); 42 | self.$timeout(() => { 43 | self.config.initialized = true; 44 | }, 120); 45 | 46 | }); 47 | } 48 | 49 | public onLoad(file?: IFile) { 50 | 51 | file.loaded.panel = true; 52 | this.loaded++; 53 | 54 | if (this.loaded === this.asg.files.length) { 55 | this.asg.event(this.asg.events.LAST_THUMBNAIL, file); 56 | this.config.loaded = true; 57 | } 58 | 59 | } 60 | 61 | // set selected image 62 | public setSelected(index: number, $event?: MouseEvent) { 63 | 64 | this.asg.modalClick($event); 65 | 66 | if (this.config.click.modal) { 67 | this.asg.modalOpen(index); 68 | return; 69 | } 70 | 71 | if (this.config.click.select) { 72 | this.asg.setSelected(index); 73 | } 74 | 75 | } 76 | 77 | // prelod when mouseover and set selected if enabled 78 | public hover(index: number, $event?: MouseEvent) { 79 | 80 | if (this.config.hover.preload === true) { 81 | this.asg.hoverPreload(index); 82 | } 83 | 84 | if (this.config.hover.select === true) { 85 | this.asg.setSelected(index); 86 | } 87 | 88 | } 89 | 90 | // get thumbnail config 91 | public get config(): IOptionsThumbnail { 92 | 93 | return this.modal ? this.asg.options.modal[this.type] : this.asg.options[this.type]; 94 | 95 | } 96 | 97 | // set thumbnail config 98 | public set config(value: IOptionsThumbnail) { 99 | 100 | if (this.modal) { 101 | this.asg.options[this.type] = value; 102 | } else { 103 | this.asg.options.modal[this.type] = value; 104 | } 105 | 106 | } 107 | 108 | // set selected image 109 | public set selected(v: number) { 110 | 111 | if (this.asg) { 112 | this.asg.selected = v; 113 | } 114 | 115 | } 116 | 117 | // get selected image 118 | public get selected() { 119 | 120 | return this.asg ? this.asg.selected : null; 121 | 122 | } 123 | 124 | // get above from config 125 | public get dynamic() { 126 | 127 | return this.config.dynamic ? 'dynamic' : ''; 128 | 129 | } 130 | 131 | // autohide and isSingle == true ? 132 | public get autohide() { 133 | 134 | return this.config.autohide && this.asg.isSingle ? true : false; 135 | 136 | } 137 | 138 | // get classes 139 | public get classes(): string { 140 | 141 | return this.asg.classes + ' ' + this.dynamic + ' ' + (this.config.initialized ? 'initialized' : 'initializing'); 142 | 143 | } 144 | 145 | } 146 | 147 | let app: ng.IModule = angular.module('angularSuperGallery'); 148 | 149 | app.component('asgThumbnail', { 150 | controller: ['asgService', '$scope', '$rootScope', '$element', '$timeout', angularSuperGallery.ThumbnailController], 151 | template: '
', 152 | bindings: { 153 | id: '@', 154 | items: '=?', 155 | options: '=?', 156 | selected: '=?', 157 | visible: '=?', 158 | template: '@?', 159 | baseUrl: '@?' 160 | } 161 | }); 162 | 163 | } 164 | -------------------------------------------------------------------------------- /src/asg.scss: -------------------------------------------------------------------------------- 1 | @use 'sass:math'; 2 | 3 | $perspective: 1280px; 4 | $animspeed: 0.64s; 5 | $animsize: 14%; 6 | $rotate: 32deg; 7 | $scaleIn: 1.14; 8 | $scaleOut: 0.86; 9 | 10 | body.asg-yhidden { 11 | overflow-y: hidden; 12 | } 13 | 14 | @import "scss/asg-image"; 15 | @import "scss/asg-modal"; 16 | @import "scss/asg-panel"; 17 | @import "scss/asg-thumbnail"; 18 | @import "scss/asg-info"; 19 | @import "scss/asg-control"; 20 | @import "scss/theme-default"; 21 | @import "scss/theme-darkblue"; 22 | @import "scss/theme-darkred"; 23 | @import "scss/theme-whitegold"; 24 | -------------------------------------------------------------------------------- /src/asg.ts: -------------------------------------------------------------------------------- 1 | let Vimeo; 2 | 3 | namespace angularSuperGallery { 4 | 5 | let app : ng.IModule = angular.module('angularSuperGallery', ['ngAnimate', 'ngTouch']); 6 | 7 | app.filter('asgBytes', () => { 8 | return function (bytes : any, precision : number) : string { 9 | 10 | if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) { 11 | return ''; 12 | } 13 | 14 | if (bytes === 0) { 15 | return '0'; 16 | } 17 | 18 | if (typeof precision === 'undefined') { 19 | precision = 1; 20 | } 21 | 22 | let units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'], 23 | number = Math.floor(Math.log(bytes) / Math.log(1024)); 24 | 25 | return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + ' ' + units[number]; 26 | 27 | }; 28 | }); 29 | 30 | } 31 | 32 | require('./asg-templates'); 33 | require('./asg-service'); 34 | require('./asg-control'); 35 | require('./asg-debug'); 36 | require('./asg-info'); 37 | require('./asg-modal'); 38 | require('./asg-panel'); 39 | require('./asg-image'); 40 | require('./asg-thumbnail'); 41 | -------------------------------------------------------------------------------- /src/scss/asg-control.scss: -------------------------------------------------------------------------------- 1 | .asg-control { 2 | position: relative; 3 | padding: 10px; 4 | z-index: 200; 5 | } -------------------------------------------------------------------------------- /src/scss/asg-image.scss: -------------------------------------------------------------------------------- 1 | .asg-image { 2 | position: relative; 3 | overflow: hidden; 4 | 5 | > .images { 6 | position: absolute; 7 | top: 0px; 8 | right: 0px; 9 | bottom: 0px; 10 | left: 0px; 11 | z-index: auto; 12 | overflow: hidden; 13 | perspective: $perspective; 14 | 15 | > .img { 16 | background-size: auto; 17 | background-position: 50% 50%; 18 | background-repeat: no-repeat; 19 | 20 | > .placeholder { 21 | position: absolute; 22 | top: 0px; 23 | right: 0px; 24 | bottom: 0px; 25 | left: 0px; 26 | z-index: auto; 27 | overflow: hidden; 28 | background-size: auto; 29 | background-position: 50% 50%; 30 | background-repeat: no-repeat; 31 | filter: blur(10px); 32 | 33 | &.cover { 34 | background-size: cover; 35 | } 36 | 37 | &.contain { 38 | background-size: contain; 39 | } 40 | 41 | &.stretch { 42 | background-size: 100% 100%; 43 | } 44 | } 45 | 46 | > .source { 47 | cursor: pointer; 48 | background-size: auto; 49 | background-position: 50% 50%; 50 | background-repeat: no-repeat; 51 | transition: all ease 0.5s; 52 | opacity: 0; 53 | 54 | &.cover { 55 | background-size: cover; 56 | } 57 | 58 | &.contain { 59 | background-size: contain; 60 | } 61 | 62 | &.stretch { 63 | background-size: 100% 100%; 64 | } 65 | } 66 | 67 | &.loaded { 68 | background-image: none; 69 | 70 | .source { 71 | opacity: 1; 72 | } 73 | } 74 | } 75 | 76 | @import "asg-transitions"; 77 | } 78 | 79 | &.modalon .source { 80 | cursor: pointer; 81 | } 82 | 83 | .asg-info { 84 | position: absolute; 85 | bottom: 0; 86 | left: 0; 87 | right: 0; 88 | } 89 | 90 | .asg-control { 91 | position: absolute; 92 | bottom: 0; 93 | right: 0; 94 | } 95 | 96 | .arrow { 97 | position: absolute; 98 | top: calc(50% - 35px); 99 | opacity: 0; 100 | z-index: 720; 101 | min-height: 70px; 102 | transition: all ease 0.2s; 103 | transform: scale(1.2); 104 | 105 | display: flex; 106 | align-items: center; 107 | justify-content: center; 108 | 109 | &.left { 110 | text-align: left; 111 | left: -20px; 112 | } 113 | 114 | &.right { 115 | text-align: right; 116 | right: -20px; 117 | } 118 | 119 | .btn { 120 | padding: 10px 16px; 121 | opacity: 0.7; 122 | 123 | &:hover { 124 | opacity: 1; 125 | } 126 | } 127 | } 128 | 129 | .video { 130 | position: absolute; 131 | top: 0; 132 | bottom: 0; 133 | left: 0; 134 | right: 0; 135 | z-index: 710; 136 | background-color: black; 137 | 138 | > div { 139 | position: unset !important; 140 | } 141 | } 142 | 143 | .play { 144 | position: absolute; 145 | top: calc(50% - 80px); 146 | left: calc(50% - 80px); 147 | width: 160px; 148 | height: 160px; 149 | z-index: 800; 150 | text-align: center; 151 | 152 | .button { 153 | fill: white; 154 | opacity: 0.42; 155 | cursor: pointer; 156 | transition: all $animspeed; 157 | border-radius: 50%; 158 | 159 | &:hover { 160 | opacity: 0.77; 161 | box-shadow: 0px 0px 7px #212121; 162 | } 163 | 164 | svg { 165 | stroke-width: 2; 166 | } 167 | } 168 | } 169 | 170 | &:hover { 171 | .arrow { 172 | opacity: 1; 173 | transform: scale(1); 174 | 175 | &.left { 176 | left: 0; 177 | } 178 | 179 | &.right { 180 | right: 0; 181 | } 182 | } 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /src/scss/asg-info.scss: -------------------------------------------------------------------------------- 1 | .asg-info { 2 | position: relative; 3 | padding: 10px; 4 | z-index: auto; 5 | } -------------------------------------------------------------------------------- /src/scss/asg-modal.scss: -------------------------------------------------------------------------------- 1 | .asg-modal { 2 | z-index: 99999; 3 | line-height: inherit; 4 | position: fixed; 5 | top: 0; 6 | right: 0; 7 | bottom: 0; 8 | left: 0; 9 | padding: 0; 10 | outline: none; 11 | opacity: 1; 12 | &.dynamic { 13 | .header { 14 | position: absolute; 15 | opacity: 0; 16 | top: 0; 17 | left: 0; 18 | right: 0; 19 | &:hover { 20 | opacity: 0.75; 21 | } 22 | } 23 | } 24 | .frame { 25 | z-index: 7400; 26 | position: absolute; 27 | overflow: hidden; 28 | top: 0; 29 | right: 0; 30 | bottom: 0; 31 | left: 0; 32 | padding: 0; 33 | display: flex; 34 | flex-direction: column; 35 | } 36 | .btn { 37 | text-transform: lowercase; 38 | } 39 | .btn-size { 40 | width: 64px; 41 | } 42 | .btn-transitions { 43 | width: 96px; 44 | } 45 | &.ng-hide-add, 46 | &.ng-hide-remove { 47 | transition: all ease 0.42s; 48 | } 49 | &.ng-hide { 50 | opacity: 0; 51 | } 52 | .keyInput { 53 | position: absolute; 54 | width: 0px; 55 | height: 0px; 56 | opacity: 0; 57 | } 58 | .header { 59 | position: relative; 60 | display: block; 61 | width: 100%; 62 | height: auto; 63 | z-index: 7700; 64 | .title { 65 | display: inline-block; 66 | margin: 6px 10px 4px 12px; 67 | float: left; 68 | font-size: 1.2em; 69 | } 70 | .subtitle { 71 | display: inline-block; 72 | margin: 4px 10px 4px 2px; 73 | text-transform: uppercase; 74 | float: left; 75 | font-size: 0.8em; 76 | padding: 6px 16px 6px 16px; 77 | } 78 | .file { 79 | font-size: 0.9em; 80 | padding: 10px 12px; 81 | display: inline-block; 82 | } 83 | .buttons { 84 | margin: 4px 4px 4px 14px; 85 | .btn { 86 | margin: 0px 1px; 87 | } 88 | } 89 | } 90 | perspective: $perspective; 91 | .help { 92 | ul, 93 | li { 94 | margin: 0; 95 | padding: 0; 96 | display: block; 97 | } 98 | position: absolute; 99 | right: 0; 100 | padding: 10px; 101 | z-index: 7500; 102 | font-size: 12px; 103 | transition: all ease 0.42s; 104 | transform: translateY(0) rotateX(0deg); 105 | &.ng-hide { 106 | opacity: 0; 107 | transform-origin: right center; 108 | transform: translateX(77px) rotateY(0deg); 109 | } 110 | } 111 | .images { 112 | perspective: $perspective; 113 | position: relative; 114 | z-index: auto; 115 | overflow: hidden; 116 | height: 100%; 117 | @import "asg-transitions"; 118 | } 119 | 120 | .arrow { 121 | position: absolute; 122 | top: 0; 123 | bottom: 0; 124 | opacity: 0; 125 | z-index: 700; 126 | min-height: 100px; 127 | transition: all ease 0.2s; 128 | transform: scale(1.2); 129 | 130 | display: flex; 131 | align-items: center; 132 | justify-content: center; 133 | 134 | cursor: pointer; 135 | 136 | &.left { 137 | left: -20px; 138 | } 139 | 140 | &.right { 141 | right: -20px; 142 | } 143 | 144 | .btn { 145 | padding: 10px 16px; 146 | opacity: 0.7; 147 | 148 | &:hover { 149 | opacity: 1; 150 | } 151 | } 152 | } 153 | 154 | &:hover { 155 | .arrow { 156 | opacity: 1; 157 | transform: scale(1); 158 | 159 | &.left { 160 | left: 0; 161 | } 162 | 163 | &.right { 164 | right: 0; 165 | } 166 | 167 | } 168 | 169 | } 170 | 171 | .caption { 172 | position: absolute; 173 | left: 0; 174 | right: 0; 175 | opacity: 0; 176 | z-index: 900; 177 | &.top { 178 | top: 0; 179 | } 180 | &.bottom { 181 | bottom: 0; 182 | } 183 | &.visible { 184 | opacity: 1; 185 | } 186 | &:not(.visible):hover { 187 | opacity: 1; 188 | } 189 | .content { 190 | padding: 7px 10px; 191 | text-align: center; 192 | margin: auto; 193 | } 194 | } 195 | .dropdown-submenu { 196 | position: relative; 197 | } 198 | .dropdown-submenu>.dropdown-menu { 199 | position: relative; 200 | } 201 | .dropdown-submenu.open>.dropdown-menu { 202 | display: block; 203 | } 204 | @media (orientation: portrait) { 205 | .help { 206 | left: 0; 207 | right: 0; 208 | top: 0; 209 | font-size: 1.1em; 210 | text-align: right; 211 | li { 212 | margin: 0; 213 | padding: 2px; 214 | display: block; 215 | } 216 | } 217 | .header { 218 | text-align: center; 219 | font-size: 18px; 220 | .title, 221 | .subtitle { 222 | margin-top: 1%; 223 | float: none; 224 | clear: both; 225 | } 226 | .buttons { 227 | float: none !important; 228 | clear: both !important; 229 | .btn { 230 | font-size: 0.7em; 231 | margin: 1% 0; 232 | } 233 | } 234 | } 235 | .caption { 236 | .content { 237 | font-size: 1.1em; 238 | } 239 | } 240 | } 241 | } 242 | -------------------------------------------------------------------------------- /src/scss/asg-panel.scss: -------------------------------------------------------------------------------- 1 | .asg-panel { 2 | .item { 3 | overflow: hidden; 4 | position: relative; 5 | border: none; 6 | border-radius: unset; 7 | img { 8 | cursor: pointer; 9 | display: block; 10 | max-width: 100%; 11 | height: auto; 12 | margin-right: auto; 13 | margin-left: auto; 14 | } 15 | .index { 16 | position: absolute; 17 | top: 7px; 18 | z-index: 9999; 19 | right: 7px; 20 | padding: 2px 4px; 21 | font-size: 9px; 22 | } 23 | .caption { 24 | width: 100%; 25 | font-size: 11px; 26 | overflow: hidden; 27 | text-overflow: ellipsis; 28 | white-space: nowrap; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/scss/asg-thumbnail.scss: -------------------------------------------------------------------------------- 1 | .asg-thumbnail { 2 | position: relative; 3 | overflow: hidden; 4 | transition: all ease math.div($animspeed, 2); 5 | padding: 0; 6 | opacity: 0; 7 | &.initialized { 8 | opacity: 1; 9 | } 10 | &.dynamic { 11 | position: absolute; 12 | left: 0; 13 | right: 0; 14 | bottom: 0; 15 | bottom: -20px; 16 | opacity: 0; 17 | &:hover { 18 | bottom: 0px; 19 | opacity: 1; 20 | } 21 | } 22 | .items { 23 | position: relative; 24 | white-space: nowrap; 25 | transition: all ease math.div($animspeed, 2); 26 | .item { 27 | overflow: hidden; 28 | position: relative; 29 | display: inline-block; 30 | margin: 0px 0px 0px 0px; 31 | transition: all ease math.div($animspeed, 2); 32 | vertical-align: top; 33 | &:last-child { 34 | margin-right: 0px; 35 | } 36 | img { 37 | cursor: pointer; 38 | display: block; 39 | width: auto; 40 | margin: 0px; 41 | } 42 | .index { 43 | transition: all ease math.div($animspeed, 2); 44 | position: absolute; 45 | z-index: 9999; 46 | top: 5px; 47 | right: 5px; 48 | padding: 1px 2px 0px 4px; 49 | font-size: 9px; 50 | cursor: pointer; 51 | } 52 | } 53 | } 54 | } 55 | 56 | .asg-modal { 57 | .asg-thumbnail { 58 | .items { 59 | img { 60 | height: 85px; 61 | } 62 | .index { 63 | font-size: 12px; 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/scss/asg-transitions.scss: -------------------------------------------------------------------------------- 1 | .img { 2 | max-width: 100%; 3 | max-height: 100%; 4 | margin: auto; 5 | position: absolute; 6 | top: 0; 7 | right: 0px; 8 | left: 0; 9 | z-index: 0; 10 | width: auto; 11 | height: auto; 12 | bottom: 0px; 13 | opacity: 1; 14 | 15 | background-size: auto; 16 | background-position: 50% 50%; 17 | background-repeat: no-repeat; 18 | 19 | >.placeholder { 20 | position: absolute; 21 | top: 0px; 22 | right: 0px; 23 | bottom: 0px; 24 | left: 0px; 25 | z-index: auto; 26 | overflow: hidden; 27 | background-size: auto; 28 | background-position: 50% 50%; 29 | background-repeat: no-repeat; 30 | opacity: 0.42; 31 | 32 | -ms-filter: 'progid:DXImageTransform.Microsoft.MotionBlur(strength=10)'; 33 | -webkit-filter: blur(10px); 34 | -moz-filter: blur(10px); 35 | -o-filter: blur(10px); 36 | filter: blur(10px); 37 | 38 | &.cover { 39 | background-size: cover; 40 | } 41 | 42 | &.contain { 43 | background-size: contain; 44 | } 45 | 46 | &.stretch { 47 | background-size: 100% 100%; 48 | } 49 | 50 | } 51 | 52 | >.source { 53 | max-width: 100%; 54 | max-height: 100%; 55 | margin: auto; 56 | display: block; 57 | position: absolute; 58 | top: 0; 59 | bottom: 0; 60 | left: 0; 61 | right: 0; 62 | background-size: auto; 63 | background-position: 50% 50%; 64 | background-repeat: no-repeat; 65 | transition: all ease .5s; 66 | opacity: 0; 67 | 68 | &.cover { 69 | background-size: cover; 70 | } 71 | 72 | &.contain { 73 | background-size: contain; 74 | } 75 | 76 | &.stretch { 77 | background-size: 100% 100%; 78 | } 79 | 80 | } 81 | 82 | &.loaded { 83 | 84 | background-image: none; 85 | 86 | .source { 87 | opacity: 1; 88 | } 89 | 90 | } 91 | 92 | } 93 | 94 | @import 'transitions/rotateLR'; 95 | @import 'transitions/rotateTB'; 96 | @import 'transitions/rotateZY'; 97 | @import 'transitions/slideLR'; 98 | @import 'transitions/slideTB'; 99 | @import 'transitions/zlideLR'; 100 | @import 'transitions/zlideTB'; 101 | @import 'transitions/fadeInOut'; 102 | @import 'transitions/zoomIn'; 103 | @import 'transitions/zoomOut'; 104 | @import 'transitions/zoomInOut'; 105 | @import 'transitions/flipX'; 106 | @import 'transitions/flipY'; 107 | 108 | -------------------------------------------------------------------------------- /src/scss/theme-darkblue.scss: -------------------------------------------------------------------------------- 1 | $black: #050505; 2 | $white: #fefefe; 3 | $white_darken: darken($white, 14%); 4 | $primary: #30c6d4; 5 | $primary_darken: darken($primary, 40%); 6 | .asg-thumbnail.darkblue { 7 | background-color: $black; 8 | padding: 4px 0px 0px 0px; 9 | .item { 10 | margin: 0px 4px 0px 0px; 11 | img { 12 | height: 42px; 13 | opacity: 0.64; 14 | } 15 | .index { 16 | background-color: rgba($black, 0.64); 17 | padding: 1px 3px 0px 4px; 18 | color: $primary; 19 | top: 0px; 20 | right: -10px; 21 | bottom: 0px; 22 | opacity: 0; 23 | } 24 | background-color: $black; 25 | &.selected { 26 | img { 27 | opacity: 1; 28 | } 29 | .index { 30 | opacity: 1; 31 | right: 0px; 32 | } 33 | } 34 | &:hover { 35 | .index { 36 | opacity: 0.77; 37 | right: 0px; 38 | } 39 | } 40 | } 41 | } 42 | 43 | .asg-image.darkblue { 44 | background-color: $black; 45 | color: $primary; 46 | .asg-info { 47 | top: -100px; 48 | bottom: auto; 49 | font-size: 12px; 50 | background-color: rgba($black, 0); 51 | transition: all 0.25s; 52 | a { 53 | color: $primary; 54 | border-bottom: 1px dashed $primary; 55 | text-decoration: none; 56 | &:hover { 57 | text-decoration: none; 58 | border-bottom: 1px solid $primary; 59 | } 60 | } 61 | } 62 | &:hover .asg-info { 63 | background-color: rgba($black, 0.77); 64 | top: 0; 65 | } 66 | .btn { 67 | -webkit-transition: all .3s ease-in-out; 68 | transition: all .3s ease-in-out; 69 | border-radius: 0; 70 | background-image: none; 71 | text-shadow: none; 72 | } 73 | .btn-default { 74 | border: 1px solid $primary_darken; 75 | color: $primary; 76 | background-color: transparent; 77 | } 78 | .btn-default:focus, 79 | .btn-default:hover { 80 | border: 1px solid $primary; 81 | outline: none; 82 | color: $black; 83 | background-color: $primary; 84 | } 85 | .arrow { 86 | &.left .btn { 87 | margin-left: -1px; 88 | } 89 | &.right .btn { 90 | margin-right: -1px; 91 | } 92 | } 93 | .play { 94 | 95 | .button { 96 | 97 | fill: white; 98 | box-shadow: 0px 0px 4px $primary; 99 | 100 | &:hover { 101 | box-shadow: 0px 0px 17px $primary; 102 | } 103 | 104 | svg { 105 | .circle { 106 | stroke: $primary; 107 | fill: $black; 108 | } 109 | .icon { 110 | fill: $primary; 111 | } 112 | } 113 | } 114 | } 115 | } 116 | 117 | .asg-modal.darkblue { 118 | .frame { 119 | margin: 0; 120 | } 121 | .btn { 122 | -webkit-transition: all .3s ease-in-out; 123 | transition: all .3s ease-in-out; 124 | border-radius: 0; 125 | background-image: none; 126 | text-shadow: none; 127 | } 128 | .btn-default { 129 | border: 1px solid $primary_darken; 130 | color: $primary; 131 | background-color: transparent; 132 | } 133 | .btn-default:focus, 134 | .btn-default:hover { 135 | border: 1px solid $primary; 136 | outline: none; 137 | color: $black; 138 | background-color: $primary; 139 | } 140 | background-color: $black; 141 | .header { 142 | background-color: $black; 143 | color: $primary; 144 | .title { 145 | text-transform: uppercase; 146 | } 147 | .subtitle { 148 | background: $primary; 149 | color: $black; 150 | } 151 | } 152 | .help { 153 | background-color: rgba($black, 0.77); 154 | color: $primary; 155 | } 156 | .caption { 157 | .content { 158 | background-color: rgba($black, 0.64); 159 | color: $primary; 160 | padding: 0px; 161 | line-height: 32px; 162 | } 163 | } 164 | .asg-thumbnail { 165 | background-color: rgba($black, 0.77); 166 | .item { 167 | img { 168 | height: 77px; 169 | } 170 | } 171 | } 172 | 173 | } 174 | 175 | .asg-control.darkblue { 176 | .btn { 177 | -webkit-transition: all .3s ease-in-out; 178 | transition: all .3s ease-in-out; 179 | border-radius: 0; 180 | background-image: none; 181 | text-shadow: none; 182 | } 183 | .btn-default { 184 | border: 1px solid $primary; 185 | color: $primary; 186 | background-color: transparent; 187 | } 188 | .btn-default:focus, 189 | .btn-default:hover { 190 | border: 1px solid $primary; 191 | outline: none; 192 | color: $black; 193 | background-color: $primary; 194 | } 195 | background-color: $black; 196 | } 197 | 198 | .asg-info.darkblue { 199 | background-color: $black; 200 | color: $primary; 201 | } 202 | 203 | .asg-panel.darkblue { 204 | background-color: $black; 205 | .item { 206 | background-color: $black; 207 | &.selected { 208 | border-color: $black; 209 | } 210 | .index { 211 | background-color: rgba($black, 0.56); 212 | color: $primary; 213 | } 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /src/scss/theme-darkred.scss: -------------------------------------------------------------------------------- 1 | $black: #141414; 2 | $dark: #252c31; 3 | $primary: #ff4343; 4 | $button: #445059; 5 | $icon: #8fa9cc; 6 | $white: #fefefe; 7 | .asg-thumbnail.darkred { 8 | background-color: $dark; 9 | padding: 6px 0px 7px 0px; 10 | .item { 11 | margin: 0px 7px 0px 0px; 12 | opacity: 0.64; 13 | &.selected { 14 | opacity: 1; 15 | } 16 | img { 17 | height: 42px; 18 | } 19 | &:hover, 20 | &.selected { 21 | .index { 22 | opacity: 1; 23 | left: 0px; 24 | } 25 | } 26 | .index { 27 | background-color: rgba($dark, 0.9); 28 | color: $primary; 29 | top: unset; 30 | left: -20px; 31 | bottom: 8%; 32 | right: unset; 33 | opacity: 0; 34 | padding: 1px 12px; 35 | } 36 | background-color: $dark; 37 | } 38 | } 39 | 40 | .asg-image.darkred { 41 | background-color: $dark; 42 | color: $primary; 43 | .asg-info { 44 | top: -100px; 45 | bottom: auto; 46 | font-size: 12px; 47 | background-color: rgba($dark, 0); 48 | transition: all 0.25s; 49 | a { 50 | color: $primary; 51 | border-bottom: 1px dashed $primary; 52 | text-decoration: none; 53 | &:hover { 54 | text-decoration: none; 55 | border-bottom: 1px solid $primary; 56 | } 57 | } 58 | } 59 | &:hover .asg-info { 60 | background-color: rgba($dark, 0.77); 61 | top: 0; 62 | } 63 | .btn { 64 | -webkit-transition: all .2s ease-in-out; 65 | transition: all .2s ease-in-out; 66 | border-radius: 3px; 67 | background-image: none; 68 | text-shadow: none; 69 | } 70 | .btn-default { 71 | border: none; 72 | color: $icon; 73 | background-color: $button; 74 | } 75 | .btn-default:focus, 76 | .btn-default:hover { 77 | border: none; 78 | outline: none; 79 | color: $dark; 80 | background-color: $primary; 81 | } 82 | .arrow { 83 | &.left .btn { 84 | margin-left: 7px; 85 | } 86 | &.right .btn { 87 | margin-right: 7px; 88 | } 89 | } 90 | } 91 | 92 | .asg-modal.darkred { 93 | .frame { 94 | margin: 0; 95 | } 96 | .btn { 97 | -webkit-transition: all .2s ease-in-out; 98 | transition: all .2s ease-in-out; 99 | border-radius: 3px; 100 | background-image: none; 101 | text-shadow: none; 102 | } 103 | .btn-default { 104 | border: none; 105 | color: $icon; 106 | background-color: $button; 107 | } 108 | .btn-default:focus, 109 | .btn-default:hover { 110 | border: none; 111 | outline: none; 112 | color: $dark; 113 | background-color: $primary; 114 | } 115 | background-color: $dark; 116 | .header { 117 | .buttons { 118 | margin: 4px 4px 5px 14px; 119 | } 120 | background-color: $dark; 121 | color: $icon; 122 | .title { 123 | margin: 3px 10px 4px 12px; 124 | color: $primary; 125 | text-transform: uppercase; 126 | } 127 | .subtitle { 128 | margin: 6px 10px 4px 10px; 129 | padding: 2px 10px 2px 10px; 130 | background: $primary; 131 | color: $dark; 132 | } 133 | } 134 | .help { 135 | background-color: rgba($dark, 0.77); 136 | color: $icon; 137 | } 138 | .caption { 139 | .content { 140 | background-color: rgba($dark, 0.77); 141 | color: $icon; 142 | padding: 0px; 143 | line-height: 32px; 144 | } 145 | } 146 | .asg-thumbnail { 147 | background-color: rgba($dark, 0.77); 148 | .item { 149 | img { 150 | height: 77px; 151 | } 152 | } 153 | } 154 | } 155 | 156 | .asg-control.darkred { 157 | .btn { 158 | -webkit-transition: all .2s ease-in-out; 159 | transition: all .2s ease-in-out; 160 | border-radius: 3px; 161 | background-image: none; 162 | text-shadow: none; 163 | } 164 | .btn-default { 165 | border: none; 166 | color: $primary; 167 | background-color: transparent; 168 | } 169 | .btn-default:focus, 170 | .btn-default:hover { 171 | border: none; 172 | outline: none; 173 | color: $dark; 174 | background-color: $primary; 175 | } 176 | background-color: $dark; 177 | } 178 | 179 | .asg-info.darkred { 180 | background-color: $dark; 181 | color: $primary; 182 | } 183 | 184 | .asg-panel.darkred { 185 | background-color: $dark; 186 | .item { 187 | background-color: $dark; 188 | &:hover { 189 | .caption { 190 | color: $white; 191 | } 192 | } 193 | &.selected { 194 | .index { 195 | background-color: $black; 196 | } 197 | } 198 | .index { 199 | float: left; 200 | background-color: $dark; 201 | color: $primary; 202 | position: relative; 203 | padding: 1px 7px; 204 | margin-right: 7px; 205 | font-size: 10px; 206 | top: unset; 207 | right: unset; 208 | } 209 | .caption { 210 | transition: color 0.4s; 211 | max-height: 21px; 212 | display: inline-block; 213 | padding: 3px 0px; 214 | margin-bottom: 15px; 215 | } 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /src/scss/theme-default.scss: -------------------------------------------------------------------------------- 1 | $black: #050505; 2 | $white: #fefefe; 3 | $white_darken: darken($white, 14%); 4 | .asg-thumbnail { 5 | .item { 6 | .index { 7 | background-color: $white_darken; 8 | color: $black; 9 | } 10 | } 11 | } 12 | 13 | .asg-modal.default { 14 | background-color: $white_darken; 15 | .highlight { 16 | background-color: $white; 17 | } 18 | .header { 19 | background-color: $white; 20 | .subtitle { 21 | background: $white_darken; 22 | color: $white; 23 | } 24 | } 25 | .help { 26 | background-color: rgba($black, 0.56); 27 | color: $white_darken; 28 | } 29 | .caption { 30 | .content { 31 | background-color: rgba($black, 0.56); 32 | color: $white_darken; 33 | } 34 | } 35 | } 36 | 37 | .asg-panel.default { 38 | .item { 39 | &.selected { 40 | border-color: $black; 41 | } 42 | .index { 43 | background-color: $white_darken; 44 | color: $black; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /src/scss/theme-whitegold.scss: -------------------------------------------------------------------------------- 1 | $black: #212121; 2 | $white: #f1f1f1; 3 | $white_darken: darken($white, 14%); 4 | $primary: #d4c386; 5 | .asg-thumbnail.whitegold { 6 | background-color: #d4c386; 7 | padding: 4px; 8 | .item { 9 | margin: 0px 4px 0px 0px; 10 | opacity: 0.64; 11 | &.selected { 12 | opacity: 1; 13 | } 14 | &:hover, 15 | &.selected { 16 | .index { 17 | opacity: 1; 18 | right: 0px; 19 | } 20 | } 21 | .index { 22 | background-color: rgba($black, 0.64); 23 | color: $primary; 24 | top: 0px; 25 | right: -10px; 26 | bottom: 0px; 27 | opacity: 0; 28 | } 29 | background-color: $black; 30 | } 31 | } 32 | 33 | .asg-image.whitegold { 34 | background-color: $primary; 35 | color: $white; 36 | .asg-info { 37 | background-color: rgba($black, 0.5); 38 | color: darken($white, 5%); 39 | a { 40 | color: darken($white, 5%); 41 | } 42 | } 43 | .btn { 44 | -webkit-transition: all .3s ease-in-out; 45 | transition: all .3s ease-in-out; 46 | border-radius: 0; 47 | background-image: none; 48 | text-shadow: none; 49 | } 50 | .btn-default { 51 | border: 1px solid $white; 52 | color: $white; 53 | background-color: transparent; 54 | } 55 | .btn-default:focus, 56 | .btn-default:hover { 57 | border: 1px solid $primary; 58 | outline: none; 59 | color: $primary; 60 | background-color: $white; 61 | } 62 | } 63 | 64 | .asg-modal.whitegold { 65 | .btn { 66 | -webkit-transition: all .3s ease-in-out; 67 | transition: all .3s ease-in-out; 68 | border-radius: 0; 69 | background-image: none; 70 | text-shadow: none; 71 | } 72 | .btn-default { 73 | border: 1px solid $white; 74 | color: $white; 75 | background-color: transparent; 76 | } 77 | .btn-default:focus, 78 | .btn-default:hover { 79 | border: 1px solid $primary; 80 | outline: none; 81 | color: $primary; 82 | background-color: $white; 83 | } 84 | background-color: $primary; 85 | .header { 86 | background-color: $primary; 87 | color: $primary; 88 | .title { 89 | color: $white; 90 | } 91 | .subtitle { 92 | background: $primary; 93 | color: $white; 94 | } 95 | } 96 | .help { 97 | background-color: rgba($primary, 0.77); 98 | color: $white; 99 | } 100 | .caption { 101 | .content { 102 | background-color: rgba($primary, 0.56); 103 | color: $white; 104 | } 105 | } 106 | } 107 | 108 | .asg-control.whitegold { 109 | .btn { 110 | -webkit-transition: all .3s ease-in-out; 111 | transition: all .3s ease-in-out; 112 | border-radius: 0; 113 | background-image: none; 114 | text-shadow: none; 115 | } 116 | .btn-default { 117 | border: 1px solid $white; 118 | color: $white; 119 | background-color: transparent; 120 | } 121 | .btn-default:focus, 122 | .btn-default:hover { 123 | border: 1px solid $primary; 124 | outline: none; 125 | color: $primary; 126 | background-color: $white; 127 | } 128 | background-color: $primary; 129 | } 130 | 131 | .asg-info.whitegold { 132 | background-color: $primary; 133 | color: $white; 134 | a { 135 | color: $white; 136 | border-bottom: 1px dashed $primary; 137 | text-decoration: none; 138 | &:hover { 139 | text-decoration: none; 140 | border-bottom: 1px solid $primary; 141 | } 142 | } 143 | } 144 | 145 | .asg-panel.whitegold { 146 | .item { 147 | &.selected { 148 | border-color: $primary; 149 | .index { 150 | background-color: $primary; 151 | color: $white; 152 | } 153 | } 154 | .index { 155 | color: $primary; 156 | top: inherit; 157 | bottom: 5px; 158 | font-size: 12px; 159 | padding: 0px 4px; 160 | line-height: 17px; 161 | right: 15px; 162 | border-radius: 2px; 163 | } 164 | } 165 | } -------------------------------------------------------------------------------- /src/scss/transitions/fadeInOut.scss: -------------------------------------------------------------------------------- 1 | &.fadeInOut { 2 | 3 | &.forward .img { 4 | 5 | &.ng-hide-remove, &.ng-hide-add { 6 | transition: all ease $animspeed; 7 | } 8 | 9 | &.ng-hide-add.ng-hide-add-active { 10 | opacity: 0; 11 | } 12 | 13 | &.ng-hide-add { 14 | opacity: 1; 15 | } 16 | 17 | &.ng-hide-remove.ng-hide-remove-active { 18 | opacity: 1; 19 | } 20 | 21 | &.ng-hide-remove { 22 | opacity: 0; 23 | } 24 | 25 | } 26 | 27 | &.backward .img { 28 | 29 | &.ng-hide-remove, &.ng-hide-add { 30 | transition: all ease $animspeed; 31 | } 32 | 33 | &.ng-hide-add.ng-hide-add-active { 34 | opacity: 0; 35 | } 36 | 37 | &.ng-hide-add { 38 | opacity: 1; 39 | } 40 | 41 | &.ng-hide-remove.ng-hide-remove-active { 42 | opacity: 1; 43 | } 44 | 45 | &.ng-hide-remove { 46 | opacity: 0; 47 | } 48 | 49 | } 50 | } -------------------------------------------------------------------------------- /src/scss/transitions/flipX.scss: -------------------------------------------------------------------------------- 1 | &.flipX { 2 | 3 | &.forward .img { 4 | 5 | &.ng-hide-remove, &.ng-hide-add { 6 | transition: all ease $animspeed; 7 | } 8 | 9 | &.ng-hide-add.ng-hide-add-active { 10 | opacity: 0; 11 | transform: rotateX(-180deg); 12 | } 13 | 14 | &.ng-hide-add { 15 | opacity: 1; 16 | transform: rotateX(0deg); 17 | } 18 | 19 | &.ng-hide-remove.ng-hide-remove-active { 20 | opacity: 1; 21 | transform: rotateX(0deg); 22 | } 23 | 24 | &.ng-hide-remove { 25 | opacity: 0; 26 | transform: rotateX(180deg); 27 | } 28 | 29 | } 30 | 31 | &.backward .img { 32 | 33 | &.ng-hide-remove, &.ng-hide-add { 34 | transition: all ease $animspeed; 35 | } 36 | 37 | &.ng-hide-add.ng-hide-add-active { 38 | opacity: 0; 39 | transform: rotateX(180deg); 40 | } 41 | 42 | &.ng-hide-add { 43 | opacity: 1; 44 | transform: rotateX(0deg); 45 | } 46 | 47 | &.ng-hide-remove.ng-hide-remove-active { 48 | opacity: 1; 49 | transform: rotateX(0deg); 50 | } 51 | 52 | &.ng-hide-remove { 53 | opacity: 0; 54 | transform: rotateX(-180deg); 55 | } 56 | 57 | } 58 | } -------------------------------------------------------------------------------- /src/scss/transitions/flipY.scss: -------------------------------------------------------------------------------- 1 | &.flipY { 2 | 3 | &.forward .img { 4 | 5 | &.ng-hide-remove, &.ng-hide-add { 6 | transition: all ease $animspeed; 7 | } 8 | 9 | &.ng-hide-add.ng-hide-add-active { 10 | opacity: 0; 11 | transform: rotateY(-180deg); 12 | } 13 | 14 | &.ng-hide-add { 15 | opacity: 1; 16 | transform: rotateY(0deg); 17 | } 18 | 19 | &.ng-hide-remove.ng-hide-remove-active { 20 | opacity: 1; 21 | transform: rotateY(0deg); 22 | } 23 | 24 | &.ng-hide-remove { 25 | opacity: 0; 26 | transform: rotateY(180deg); 27 | } 28 | 29 | } 30 | 31 | &.backward .img { 32 | 33 | &.ng-hide-remove, &.ng-hide-add { 34 | transition: all ease $animspeed; 35 | } 36 | 37 | &.ng-hide-add.ng-hide-add-active { 38 | opacity: 0; 39 | transform: rotateY(180deg); 40 | } 41 | 42 | &.ng-hide-add { 43 | opacity: 1; 44 | transform: rotateY(0deg); 45 | } 46 | 47 | &.ng-hide-remove.ng-hide-remove-active { 48 | opacity: 1; 49 | transform: rotateY(0deg); 50 | } 51 | 52 | &.ng-hide-remove { 53 | opacity: 0; 54 | transform: rotateY(-180deg); 55 | } 56 | 57 | } 58 | } -------------------------------------------------------------------------------- /src/scss/transitions/rotateLR.scss: -------------------------------------------------------------------------------- 1 | 2 | &.rotateLR { 3 | 4 | &.forward .img { 5 | 6 | &.ng-hide-remove, &.ng-hide-add { 7 | transition: all ease $animspeed; 8 | } 9 | 10 | &.ng-hide-add.ng-hide-add-active { 11 | opacity: 0; 12 | transform: rotateY(-$rotate) translateX(-$animsize); 13 | } 14 | 15 | &.ng-hide-add { 16 | opacity: 1; 17 | transform: rotateY(0deg) translateX(0); 18 | } 19 | 20 | &.ng-hide-remove.ng-hide-remove-active { 21 | opacity: 1; 22 | transform: rotateY(0deg) translateX(0); 23 | } 24 | 25 | &.ng-hide-remove { 26 | opacity: 0; 27 | transform: rotateY($rotate) translateX($animsize); 28 | } 29 | 30 | } 31 | 32 | &.backward .img { 33 | 34 | &.ng-hide-remove, &.ng-hide-add { 35 | transition: all ease $animspeed; 36 | } 37 | 38 | &.ng-hide-add.ng-hide-add-active { 39 | opacity: 0; 40 | transform: rotateY($rotate) translateX($animsize); 41 | } 42 | 43 | &.ng-hide-add { 44 | opacity: 1; 45 | transform: rotateY(0deg) translateX(0); 46 | } 47 | 48 | &.ng-hide-remove.ng-hide-remove-active { 49 | opacity: 1; 50 | transform: rotateY(0deg) translateX(0); 51 | } 52 | 53 | &.ng-hide-remove { 54 | opacity: 0; 55 | transform: rotateY(-$rotate) translateX(-$animsize); 56 | } 57 | 58 | } 59 | } -------------------------------------------------------------------------------- /src/scss/transitions/rotateTB.scss: -------------------------------------------------------------------------------- 1 | &.rotateTB { 2 | 3 | &.forward .img { 4 | 5 | &.ng-hide-remove, &.ng-hide-add { 6 | transition: all ease $animspeed; 7 | } 8 | 9 | &.ng-hide-add.ng-hide-add-active { 10 | opacity: 0; 11 | transform: translateY($animsize) rotateX(-$rotate); 12 | } 13 | 14 | &.ng-hide-add { 15 | opacity: 1; 16 | transform: translateY(0) rotateX(0deg); 17 | } 18 | 19 | &.ng-hide-remove.ng-hide-remove-active { 20 | opacity: 1; 21 | transform: translateY(0) rotateX(0deg); 22 | } 23 | 24 | &.ng-hide-remove { 25 | opacity: 0; 26 | transform: translateY(-$animsize) rotateX($rotate); 27 | } 28 | 29 | } 30 | 31 | &.backward .img { 32 | 33 | &.ng-hide-remove, &.ng-hide-add { 34 | transition: all ease $animspeed; 35 | } 36 | 37 | &.ng-hide-add.ng-hide-add-active { 38 | opacity: 0; 39 | transform: translateY(-$animsize) rotateX($rotate); 40 | } 41 | 42 | &.ng-hide-add { 43 | opacity: 1; 44 | transform: translateY(0) rotateX(0deg); 45 | } 46 | 47 | &.ng-hide-remove.ng-hide-remove-active { 48 | opacity: 1; 49 | transform: translateY(0) rotateX(0deg); 50 | } 51 | 52 | &.ng-hide-remove { 53 | opacity: 0; 54 | transform: translateY($animsize) rotateX(-$rotate); 55 | } 56 | 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /src/scss/transitions/rotateZY.scss: -------------------------------------------------------------------------------- 1 | &.rotateZY { 2 | 3 | &.forward .img { 4 | 5 | &.ng-hide-remove, &.ng-hide-add { 6 | transition: all ease $animspeed; 7 | } 8 | 9 | &.ng-hide-add.ng-hide-add-active { 10 | opacity: 0; 11 | transform: rotateZ(-$rotate) rotateY($rotate); 12 | } 13 | 14 | &.ng-hide-add { 15 | opacity: 1; 16 | transform: rotateZ(0) rotateY(0deg); 17 | } 18 | 19 | &.ng-hide-remove.ng-hide-remove-active { 20 | opacity: 1; 21 | transform: rotateZ(0) rotateY(0deg); 22 | } 23 | 24 | &.ng-hide-remove { 25 | opacity: 0; 26 | transform: rotateZ($rotate) rotateY(-$rotate); 27 | } 28 | 29 | } 30 | 31 | &.backward .img { 32 | 33 | &.ng-hide-remove, &.ng-hide-add { 34 | transition: all ease $animspeed; 35 | } 36 | 37 | &.ng-hide-add.ng-hide-add-active { 38 | opacity: 0; 39 | transform: rotateZ($rotate) rotateY(-$rotate); 40 | } 41 | 42 | &.ng-hide-add { 43 | opacity: 1; 44 | transform: rotateZ(0) rotateY(0deg); 45 | } 46 | 47 | &.ng-hide-remove.ng-hide-remove-active { 48 | opacity: 1; 49 | transform: rotateZ(0) rotateY(0deg); 50 | } 51 | 52 | &.ng-hide-remove { 53 | opacity: 0; 54 | transform: rotateZ(-$rotate) rotateY($rotate); 55 | } 56 | 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /src/scss/transitions/slideLR.scss: -------------------------------------------------------------------------------- 1 | &.slideLR { 2 | 3 | &.forward .img { 4 | 5 | &.ng-hide-remove, &.ng-hide-add { 6 | transition: all ease $animspeed; 7 | } 8 | 9 | &.ng-hide-add.ng-hide-add-active { 10 | opacity: 0; 11 | transform: translateX(-$animsize); 12 | } 13 | 14 | &.ng-hide-add { 15 | opacity: 1; 16 | transform: translateX(0); 17 | } 18 | 19 | &.ng-hide-remove.ng-hide-remove-active { 20 | opacity: 1; 21 | transform: translateX(0); 22 | } 23 | 24 | &.ng-hide-remove { 25 | opacity: 0; 26 | transform: translateX($animsize); 27 | } 28 | 29 | } 30 | 31 | &.backward .img { 32 | 33 | &.ng-hide-remove, &.ng-hide-add { 34 | transition: all ease $animspeed; 35 | } 36 | 37 | &.ng-hide-add.ng-hide-add-active { 38 | opacity: 0; 39 | transform: translateX($animsize); 40 | } 41 | 42 | &.ng-hide-add { 43 | opacity: 1; 44 | transform: translateX(0); 45 | } 46 | 47 | &.ng-hide-remove.ng-hide-remove-active { 48 | opacity: 1; 49 | transform: translateX(0); 50 | } 51 | 52 | &.ng-hide-remove { 53 | opacity: 0; 54 | transform: translateX(-$animsize); 55 | } 56 | 57 | } 58 | } -------------------------------------------------------------------------------- /src/scss/transitions/slideTB.scss: -------------------------------------------------------------------------------- 1 | &.slideTB { 2 | 3 | &.forward .img { 4 | 5 | &.ng-hide-remove, &.ng-hide-add { 6 | transition: all ease $animspeed; 7 | } 8 | 9 | &.ng-hide-add.ng-hide-add-active { 10 | opacity: 0; 11 | transform: translateY($animsize); 12 | } 13 | 14 | &.ng-hide-add { 15 | opacity: 1; 16 | transform: translateY(0); 17 | } 18 | 19 | &.ng-hide-remove.ng-hide-remove-active { 20 | opacity: 1; 21 | transform: translateY(0); 22 | } 23 | 24 | &.ng-hide-remove { 25 | opacity: 0; 26 | transform: translateY(-$animsize); 27 | } 28 | 29 | } 30 | 31 | &.backward .img { 32 | 33 | &.ng-hide-remove, &.ng-hide-add { 34 | transition: all ease $animspeed; 35 | } 36 | 37 | &.ng-hide-add.ng-hide-add-active { 38 | opacity: 0; 39 | transform: translateY(-$animsize); 40 | } 41 | 42 | &.ng-hide-add { 43 | opacity: 1; 44 | transform: translateY(0); 45 | } 46 | 47 | &.ng-hide-remove.ng-hide-remove-active { 48 | opacity: 1; 49 | transform: translateY(0); 50 | } 51 | 52 | &.ng-hide-remove { 53 | opacity: 0; 54 | transform: translateY($animsize); 55 | } 56 | 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /src/scss/transitions/zlideLR.scss: -------------------------------------------------------------------------------- 1 | &.zlideLR { 2 | 3 | &.forward .img { 4 | 5 | &.ng-hide-remove, &.ng-hide-add { 6 | transition: all ease $animspeed; 7 | } 8 | 9 | &.ng-hide-add.ng-hide-add-active { 10 | opacity: 0; 11 | transform: translateX(-$animsize) scale($scaleOut); 12 | } 13 | 14 | &.ng-hide-add { 15 | opacity: 1; 16 | transform: translateX(0) scale(1); 17 | } 18 | 19 | &.ng-hide-remove.ng-hide-remove-active { 20 | opacity: 1; 21 | transform: translateX(0) scale(1); 22 | } 23 | 24 | &.ng-hide-remove { 25 | opacity: 0; 26 | transform: translateX($animsize) scale($scaleOut); 27 | } 28 | 29 | } 30 | 31 | &.backward .img { 32 | 33 | &.ng-hide-remove, &.ng-hide-add { 34 | transition: all ease $animspeed; 35 | } 36 | 37 | &.ng-hide-add.ng-hide-add-active { 38 | opacity: 0; 39 | transform: translateX($animsize) scale($scaleOut); 40 | } 41 | 42 | &.ng-hide-add { 43 | opacity: 1; 44 | transform: translateX(0) scale(1); 45 | } 46 | 47 | &.ng-hide-remove.ng-hide-remove-active { 48 | opacity: 1; 49 | transform: translateX(0) scale(1); 50 | } 51 | 52 | &.ng-hide-remove { 53 | opacity: 0; 54 | transform: translateX(-$animsize) scale($scaleOut); 55 | } 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/scss/transitions/zlideTB.scss: -------------------------------------------------------------------------------- 1 | &.zlideTB { 2 | 3 | &.forward .img { 4 | 5 | &.ng-hide-remove, &.ng-hide-add { 6 | transition: all ease $animspeed; 7 | } 8 | 9 | &.ng-hide-add.ng-hide-add-active { 10 | opacity: 0; 11 | transform: translateY($animsize) scale($scaleOut); 12 | } 13 | 14 | &.ng-hide-add { 15 | opacity: 1; 16 | transform: translateY(0) scale(1); 17 | } 18 | 19 | &.ng-hide-remove.ng-hide-remove-active { 20 | opacity: 1; 21 | transform: translateY(0) scale(1); 22 | } 23 | 24 | &.ng-hide-remove { 25 | opacity: 0; 26 | transform: translateY(-$animsize) scale($scaleOut); 27 | } 28 | 29 | } 30 | 31 | &.backward .img { 32 | 33 | &.ng-hide-remove, &.ng-hide-add { 34 | transition: all ease $animspeed; 35 | } 36 | 37 | &.ng-hide-add.ng-hide-add-active { 38 | opacity: 0; 39 | transform: translateY(-$animsize) scale($scaleOut); 40 | } 41 | 42 | &.ng-hide-add { 43 | opacity: 1; 44 | transform: translateY(0) scale(1); 45 | } 46 | 47 | &.ng-hide-remove.ng-hide-remove-active { 48 | opacity: 1; 49 | transform: translateY(0) scale(1); 50 | } 51 | 52 | &.ng-hide-remove { 53 | opacity: 0; 54 | transform: translateY($animsize) scale($scaleOut); 55 | } 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/scss/transitions/zoomIn.scss: -------------------------------------------------------------------------------- 1 | &.zoomIn { 2 | 3 | &.forward .img { 4 | 5 | &.ng-hide-remove, &.ng-hide-add { 6 | transition: all ease $animspeed; 7 | } 8 | 9 | &.ng-hide-add.ng-hide-add-active { 10 | opacity: 0; 11 | transform: scale($scaleIn); 12 | } 13 | 14 | &.ng-hide-add { 15 | opacity: 1; 16 | transform: scale(1); 17 | } 18 | 19 | &.ng-hide-remove.ng-hide-remove-active { 20 | opacity: 1; 21 | transform: scale(1); 22 | } 23 | 24 | &.ng-hide-remove { 25 | opacity: 0; 26 | transform: scale($scaleOut); 27 | } 28 | 29 | } 30 | 31 | &.backward .img { 32 | 33 | &.ng-hide-remove, &.ng-hide-add { 34 | transition: all ease $animspeed; 35 | } 36 | 37 | &.ng-hide-add.ng-hide-add-active { 38 | opacity: 0; 39 | transform: scale($scaleOut); 40 | } 41 | 42 | &.ng-hide-add { 43 | opacity: 1; 44 | transform: scale(1); 45 | } 46 | 47 | &.ng-hide-remove.ng-hide-remove-active { 48 | opacity: 1; 49 | transform: scale(1); 50 | } 51 | 52 | &.ng-hide-remove { 53 | opacity: 0; 54 | transform: scale($scaleIn); 55 | } 56 | 57 | } 58 | } -------------------------------------------------------------------------------- /src/scss/transitions/zoomInOut.scss: -------------------------------------------------------------------------------- 1 | &.zoomInOut { 2 | 3 | &.forward .img { 4 | 5 | &.ng-hide-remove, &.ng-hide-add { 6 | transition: all ease $animspeed; 7 | } 8 | 9 | &.ng-hide-add.ng-hide-add-active { 10 | opacity: 0; 11 | transform: scale($scaleIn); 12 | } 13 | 14 | &.ng-hide-add { 15 | opacity: 1; 16 | transform: scale(1); 17 | } 18 | 19 | &.ng-hide-remove.ng-hide-remove-active { 20 | opacity: 1; 21 | transform: scale(1); 22 | } 23 | 24 | &.ng-hide-remove { 25 | opacity: 0; 26 | transform: scale($scaleIn); 27 | } 28 | 29 | } 30 | 31 | &.backward .img { 32 | 33 | &.ng-hide-remove, &.ng-hide-add { 34 | transition: all ease $animspeed; 35 | } 36 | 37 | &.ng-hide-add.ng-hide-add-active { 38 | opacity: 0; 39 | transform: scale($scaleIn); 40 | } 41 | 42 | &.ng-hide-add { 43 | opacity: 1; 44 | transform: scale(1); 45 | } 46 | 47 | &.ng-hide-remove.ng-hide-remove-active { 48 | opacity: 1; 49 | transform: scale(1); 50 | } 51 | 52 | &.ng-hide-remove { 53 | opacity: 0; 54 | transform: scale($scaleIn); 55 | } 56 | 57 | } 58 | } -------------------------------------------------------------------------------- /src/scss/transitions/zoomOut.scss: -------------------------------------------------------------------------------- 1 | &.zoomOut { 2 | 3 | &.forward .img { 4 | 5 | &.ng-hide-remove, &.ng-hide-add { 6 | transition: all ease $animspeed; 7 | } 8 | 9 | &.ng-hide-add.ng-hide-add-active { 10 | opacity: 0; 11 | transform: scale($scaleOut); 12 | } 13 | 14 | &.ng-hide-add { 15 | opacity: 1; 16 | transform: scale(1); 17 | } 18 | 19 | &.ng-hide-remove.ng-hide-remove-active { 20 | opacity: 1; 21 | transform: scale(1); 22 | } 23 | 24 | &.ng-hide-remove { 25 | opacity: 0; 26 | transform: scale($scaleIn); 27 | } 28 | 29 | } 30 | 31 | &.backward .img { 32 | 33 | &.ng-hide-remove, &.ng-hide-add { 34 | transition: all ease $animspeed; 35 | } 36 | 37 | &.ng-hide-add.ng-hide-add-active { 38 | opacity: 0; 39 | transform: scale($scaleIn); 40 | } 41 | 42 | &.ng-hide-add { 43 | opacity: 1; 44 | transform: scale(1); 45 | } 46 | 47 | &.ng-hide-remove.ng-hide-remove-active { 48 | opacity: 1; 49 | transform: scale(1); 50 | } 51 | 52 | &.ng-hide-remove { 53 | opacity: 0; 54 | transform: scale($scaleOut); 55 | } 56 | 57 | } 58 | } -------------------------------------------------------------------------------- /src/views/asg-control.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | 9 | 10 | 13 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /src/views/asg-debug.html: -------------------------------------------------------------------------------- 1 |
    
2 |     {{ $ctrl.file | json }}    
3 | 
4 |
5 |
        
6 |     {{ $ctrl.service.instances.abstracts.options | json }}
7 | 
-------------------------------------------------------------------------------- /src/views/asg-help.html: -------------------------------------------------------------------------------- 1 |
    2 |
  • SPACE : forward
  • 3 |
  • RIGHT : forward
  • 4 |
  • LEFT : backward
  • 5 |
  • UP / HOME : first
  • 6 |
  • DOWN / END : last
  • 7 |
  • ENTER : toggle fullscreen
  • 8 |
  • ESC : exit
  • 9 |
  • p : play/pause
  • 10 |
  • t : change transition effect
  • 11 |
  • m : toggle menu
  • 12 |
  • s : toggle image size
  • 13 |
  • c : toggle caption
  • 14 |
  • h : toggle help
  • 15 |
-------------------------------------------------------------------------------- /src/views/asg-image.html: -------------------------------------------------------------------------------- 1 | 2 |
4 | 5 |
7 | 8 |
12 | 13 |
14 |
17 | 18 |
19 | 20 |
21 |
22 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
33 |
34 |
35 |
36 | 37 |
38 | 42 |
43 | 44 |
45 | 49 |
50 | 51 | 52 | 53 |
54 | -------------------------------------------------------------------------------- /src/views/asg-info.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |

{{ $ctrl.file.title }}

5 |
6 | 7 |
8 | {{ $ctrl.file.description }} 9 | 10 |
11 | 12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /src/views/asg-modal.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | {{ $ctrl.config.title }} 19 | {{ $ctrl.config.subtitle }} 20 | 21 | 22 |
23 | 24 |
25 | 26 |
27 | 28 |
29 | 32 |
33 | 34 |
35 | 38 |
39 | 40 |
41 | 42 |
43 |
44 |
45 | 46 |
47 | 48 |
49 |
50 | {{ $ctrl.asg.file.title }} 51 | - 52 | {{ $ctrl.asg.file.description }} 53 | 54 | Download 55 | 56 |
57 |
58 | 59 |
60 | 61 | 62 | 63 |
64 | 65 |
66 | -------------------------------------------------------------------------------- /src/views/asg-panel.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | {{ file.title }} 6 | 7 |
8 | {{ key + 1 }} 9 | {{ file.title }} 10 |
11 |
12 | 13 |
-------------------------------------------------------------------------------- /src/views/asg-thumbnail.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | {{ file.title }} 5 | 6 | {{ key + 1 }} 7 | 8 |
9 |
-------------------------------------------------------------------------------- /src/views/button/asg-close.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/views/button/asg-fullscreen.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/views/button/asg-help.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/views/button/asg-index-xs.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/views/button/asg-index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/button/asg-next.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/views/button/asg-pin.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /src/views/button/asg-playstop.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /src/views/button/asg-prev.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/views/button/asg-size.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/button/asg-thumbnails.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/views/button/asg-transition.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example Angular Super Gallery 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 | 14 | 15 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 |
43 |
44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "dependencies": { 7 | "angular-super-gallery": "https://github.com/schalkt/angular-super-gallery#develop" 8 | }, 9 | "devDependencies": { 10 | "i": "^0.3.6", 11 | "npm": "^6.13.7", 12 | "webpack": "^3.12.0", 13 | "webpack-css-loaders": "^1.0.0" 14 | }, 15 | "scripts": { 16 | "build": "webpack -p", 17 | "watch": "webpack --watch" 18 | } 19 | } -------------------------------------------------------------------------------- /test/src/index.css: -------------------------------------------------------------------------------- 1 | html { 2 | height: 100%; 3 | } 4 | 5 | body { 6 | background-color: #101010; 7 | padding: 5%; 8 | height: 100%; 9 | color: #c2c2c2; 10 | } 11 | 12 | .asg-modal { 13 | background-color: #101010; 14 | } -------------------------------------------------------------------------------- /test/src/index.js: -------------------------------------------------------------------------------- 1 | import 'bootstrap/dist/css/bootstrap.min.css'; 2 | import 'angular-super-gallery/dist/angular-super-gallery.css'; 3 | import './index.css'; 4 | import 'jquery'; 5 | import 'angular'; 6 | import 'bootstrap'; 7 | import 'angular-animate'; 8 | import 'angular-touch'; 9 | import 'screenfull'; 10 | import angularSuperGallery from 'angular-super-gallery'; 11 | 12 | angular.module("app", [angularSuperGallery]); -------------------------------------------------------------------------------- /test/webpack.config.js: -------------------------------------------------------------------------------- 1 | // This library allows us to combine paths easily 2 | 3 | const path = require('path'); 4 | const webpack = require('webpack'); 5 | 6 | module.exports = { 7 | entry: path.resolve(__dirname, 'src', 'index.js'), 8 | output: { 9 | path: path.resolve(__dirname, ''), 10 | filename: 'bundle.js' 11 | }, 12 | resolve: { 13 | extensions: ['.js'] 14 | }, 15 | plugins: [ 16 | new webpack.ProvidePlugin({ 17 | jQuery: "jquery", 18 | $: "jquery", 19 | jquery: "jquery" 20 | }) 21 | ], 22 | module: { 23 | rules: [ 24 | { 25 | test: /\.(jpe?g|png|gif)$/i, 26 | loader: "file-loader", 27 | query: { 28 | name: '[name].[ext]', 29 | outputPath: 'images/' 30 | } 31 | }, 32 | { 33 | test: /\.(woff(2)?|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, 34 | loader: "url-loader", 35 | query: { 36 | limit: '10000', 37 | name: '[name].[ext]', 38 | outputPath: './fonts/' 39 | } 40 | }, 41 | { 42 | test: /\.css$/, 43 | loaders: ["style-loader", "css-loader"] 44 | } 45 | ] 46 | } 47 | }; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES5", 4 | "module": "commonjs", 5 | "skipLibCheck": false, 6 | "noImplicitAny": false, 7 | "removeComments": true, 8 | "preserveConstEnums": true, 9 | "moduleResolution": "node", 10 | "sourceMap": true, 11 | "typeRoots": [ 12 | "node_modules/@types" 13 | ], 14 | "lib": [ 15 | "es6", 16 | "dom" 17 | ] 18 | }, 19 | "include": [ 20 | "src/*.ts" 21 | ], 22 | "compileOnSave": false, 23 | "buildOnSave": false 24 | } 25 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "import-no-alias": true, 4 | "naming-scheme": true, 5 | "align": [ 6 | false, 7 | "parameters", 8 | "arguments", 9 | "statements" 10 | ], 11 | "ban": true, 12 | "class-name": true, 13 | "comment-format": [ 14 | true, 15 | "check-space", 16 | "check-lowercase" 17 | ], 18 | "curly": true, 19 | "eofline": true, 20 | "indent": [ 21 | true, 22 | "tabs" 23 | ], 24 | "interface-name": true, 25 | "jsdoc-format": true, 26 | "label-position": true, 27 | "label-undefined": true, 28 | "member-access": true, 29 | "member-ordering": [ 30 | true, 31 | "variables-before-functions" 32 | ], 33 | "no-any": false, 34 | "no-arg": true, 35 | "no-conditional-assignment": true, 36 | "no-console": [ 37 | true, 38 | "debug", 39 | "info", 40 | "time", 41 | "timeEnd", 42 | "trace" 43 | ], 44 | "no-construct": true, 45 | "no-constructor-vars": true, 46 | "no-debugger": true, 47 | "no-duplicate-key": true, 48 | "no-shadowed-variable": true, 49 | "no-duplicate-variable": true, 50 | "no-empty": true, 51 | "no-eval": true, 52 | "no-inferrable-types": true, 53 | "no-internal-module": true, 54 | "no-string-literal": true, 55 | "no-switch-case-fall-through": true, 56 | "no-trailing-comma": true, 57 | "no-unreachable": true, 58 | "no-unused-expression": true, 59 | "no-unused-variable": true, 60 | "no-use-before-declare": true, 61 | "no-var-keyword": true, 62 | "no-var-requires": true, 63 | "quotemark": [ 64 | true, 65 | "single", 66 | "avoid-escape" 67 | ], 68 | "radix": true, 69 | "semicolon": true, 70 | "sort-object-literal-keys": true, 71 | "switch-default": true, 72 | "triple-equals": [ 73 | true, 74 | "allow-null-check" 75 | ] 76 | } 77 | } -------------------------------------------------------------------------------- /webpack.mix.js: -------------------------------------------------------------------------------- 1 | const mix = require('laravel-mix'); 2 | const CompressionPlugin = require('compression-webpack-plugin'); 3 | const PROD = (process.env.NODE_ENV && process.env.NODE_ENV === 'production'); 4 | const fs = require('fs'); 5 | const packagejson = JSON.parse(fs.readFileSync('./package.json')); 6 | 7 | require('laravel-mix-angular-templatecache'); 8 | 9 | mix.disableNotifications(); 10 | 11 | mix.extend('replace', function (webpackConfig, ...args) { 12 | 13 | let content = fs.readFileSync(args[0]).toString(); 14 | 15 | args[1].forEach(function (item) { 16 | content = content.replace(item[0], item[1]); 17 | }); 18 | 19 | fs.writeFileSync(args[0], content); 20 | 21 | return webpackConfig; 22 | 23 | }); 24 | 25 | mix.webpackConfig({ 26 | plugins: [ 27 | PROD ? new CompressionPlugin({ 28 | //asset: "[path].gz[query]", 29 | algorithm: "gzip", 30 | test: /\.js$|\.ts$|\.css$|\.html$|\.svg$/, 31 | threshold: 10240, 32 | minRatio: 0.8 33 | 34 | }) : () => { } 35 | ], 36 | }); 37 | 38 | 39 | mix.before(() => { 40 | 41 | // angular template cache 42 | mix.cacheTemplates('./src/views/**/*.html', { 43 | root: '/views', 44 | module: 'angularSuperGallery', 45 | outputFilename: './src/asg-templates.js', 46 | }).replace('./src/asg-templates.js', [ 47 | [/button\\/g, 'button/'], 48 | [/\\views\\/g, '/views/'], 49 | ]); 50 | 51 | }); 52 | 53 | 54 | // compile typesript and scss 55 | mix.ts('./src/asg.ts', './dist/angular-super-gallery.min.js') 56 | .sass('./src/asg.scss', './dist/angular-super-gallery.min.css'); 57 | 58 | 59 | // update version 60 | mix.replace('./src/asg-service.ts', [ 61 | [/version.*"\d+\.\d+\.\d+"/, 'version = "' + packagejson.version + '"'] 62 | ]); 63 | 64 | --------------------------------------------------------------------------------