update retro shooters, use simple lightbox

This commit is contained in:
wgroeneveld 2020-06-07 10:18:09 +02:00
parent 93ca0f62e9
commit 3358769c84
16 changed files with 83 additions and 459 deletions

View File

@ -1,6 +1,4 @@
---
showonlyimage: false
draft: false
image: "/img/games/doom2.jpeg"
date: "2006-11-02"
title: "Early Shooter Clones"

View File

@ -17,15 +17,7 @@ game_developer: 'Voidpoint'
### In search of 90's shooters
Do you remember the nineties? You know, big CRT screens, laptops of 10 kg and lots of floppy drives? Magnetic things that regularly fail to read data? How about a bit later, Windows 95? That era produced so many good (and _extremely gory_) PC shooters that I don't even know where to start if I wanted to list them:
- **1998**: Unreal<br/>_The start of OpenGL wars between Quake and Unreal_
- **1997**: Redneck Rampage<br/>_Using the Build engine to shoot at chickens?_
- **1996**: Quake, Duke Nukem 3D<br/>_Complex level design, "real" 3D_
- **1995**: Rise of the Triad<br/>_Huge levels, flying bodyparts_
- **1994**: Heretic<br/>_Doom engine mixed with medieval magic_
- **1993**: Doom<br/>_Great atmosphere and music, a sense of verticality_
- **1992**: Wolfenstein 3D<br/>_Hugging walls and pressing spacebar!_
Do you remember the nineties? You know, big CRT screens, laptops of 10 kg and lots of floppy drives? Magnetic things that regularly fail to read data? How about a bit later, Windows 95? That era produced so many good (and _extremely gory_) PC shooters that I don't even know where to start if I wanted to list them. I did try to list them in this [quick look at retro shooters](/articles/retro-shootesr/) and their engines.
Every single game was a big step forward and had me completely hooked during my childhood. Since Jefklak's Codex is a retro codex, and since retro gaming is becoming more and more popular, I thought, "_hey, why not cover the resurgence of nineties shooters?_"

View File

@ -5,18 +5,20 @@ title: "A Quick Look At Retro Shooters and Their Engines"
tags:
- 'retro shooters'
- 'doom'
description: "I'm feeling nostalgic. Why don't you join me and we can marvel at magnificent achievements of the FPS past..."
description: "I'm feeling nostalgic. Why don't you join me so we can marvel at magnificent achievements of the FPS past?"
---
I'm feeling nostalgic. Why don't you join me so we can marvel at magnificent achievements of the FPS past? Apparently, I wrote an article on [early shooter clones](/articles/early-shooter-clones) in 2006 - that's 14 years ago! [Ion Fury](/articles/ion-fury) and the excellent retro shooter videos of [GmanLives](https://www.youtube.com/user/Gggmanlives/) respiked my interest in the genre. According to GmanLives, I must have missed a lot of classic shooters back in the day. Since it's never too late to relive those moments, let's create a list based on Wikipedia's [List of first-person shooter engines](https://en.wikipedia.org/wiki/List_of_first-person_shooter_engines) - who knows I might have missed something good.
Most games listed below are available on [Good Old Games](https://gog.com) and I highly recommend you to check them out.
This is just a selection of shooters I highlighted. Most games listed below are available on [Good Old Games](https://gog.com) and I highly recommend you to check them out.
**TLDR**; Scroll through the screenshots (use the &larr; &rarr; keys) to get an idea of the evolution of shooters.
### 1. Early 1990s: wireframes to 2.5D worlds and textures
1992 - Of course, there's the **[Wolfenstein 3D](/tags/wolfenstein-3d) engine**. I did play [Blake Stone](/articles/apogees-legacy) and [Rise of the Triad](/tags/rise-of-the-triad), but I can't say I even finished one shareware episode. I was about eight years old and the maze-like levels didn't really help there. All I remember was: _hug walls and press spacebar_! It's mind-boggling that ROTT is running on a supercharged version of the Wolf3D engine
![blake stone](/img/games/blakestone.jpg)
![](/img/games/blakestone.jpg "Blake Stone: Aliens of Gold")
> The Wolf3D engine source is released [on Github](https://github.com/id-Software/wolf3d).
@ -24,41 +26,47 @@ Most games listed below are available on [Good Old Games](https://gog.com) and I
> DSDoom (also spelled DS Doom) is a source port for the Nintendo DS, based on PrBoom 2.4.2. It was made by TheChuckster, WinterMute, and Jefklak.
![](/img/games/doom1.jpg "Doom 1")
I'm quite proud of that! If anyone is interested, I found a copy of the source code from 2007-01-04 you can download here: [dsdoom v110r1](/files/dsdoom_v110r1_20070104.zip). Comes without guarantees - it's been 13 years...
Playing Hexen, the medieval shooter running on the Doom engine, boiled down to me constantly saying "_what the fuck should I do?_". Something completely different than the holding-hands-games they release now.
> The Doom engine source is released [on Github](https://github.com/id-Software/DOOM).
![Outlaws](/img/games/outlaws.jpg)
1995 - Lucas Arts' **Jedi Engine**, used for Star Wars: Dark Forces, and later again in the 1997 masterpiece Outlaws. I can still hear the cowboys yelling "_Where are you marshall?_" and I'm glad to see it's purchasable at GOG.
![](/img/games/outlaws.jpg "Outlaws")
1996 - 3D Realms' **Build Engine** hits bullseye with [Duke Nukem 3D](/tags/duke-nukem-3d). I really should also play Blood at some point, the gory crazy and seemingly difficult game from Monolith. Shadow Warrior re-used a lot of assets from Duke but managed to create it's own appeal, and of course the recent [Ion Fury](/articles/ion-fury) runs on a beefed-up version of the same engine. In 1998, my dad bought me Redneck Rampage, a game where you shoot... chickens and pigs? Unlucky for me, I got stuck at some point searching for yet another keycard.
> The Build engine source is released [via Ken Silverman's website](http://advsys.net/ken/buildsrc/default.htm).
![](/img/games/redneckrampage.jpg "Redneck Rampage")
### 2. Mid 1990s: 3D models, beginnings of hardware acceleration
1996 - the **Quake** engine saw the light and introduced us to the _real_ world of 3D environments. Quake could be rightfully called the spiritual successor of Doom. Hexen II runs on the same engine. I added Quake to my toplay list - I was to busy with Duke3D at that time. A lot of Build engine games were released in the shadow of Quake, missing the hype train...
> The Quake engine source is released [on Github](https://github.com/id-Software/Quake).
1997 - It's worth mentioning that **GoldenEye 007** and Perfect Dark set the tone for FPS games on the console, even if I did not play these on the Gamecube. Even split-screen gameplay was running smooth at that time!
![](/img/games/quake1.jpg "Quake I")
![soldier of fortune](/img/games/sof.jpg)
1997 - It's worth mentioning that **GoldenEye 007** and Perfect Dark set the tone for FPS games on the console, even if I did not play these on the Gamecube. Even split-screen gameplay was running smooth at that time!
1997 - **Quake II** was a forgettable game but the technical marvels of it's engine were re-used in Heretic II (meh), Daikatana (a John Romero Failure), and Soldier of Fortune in 2000 - Raven Software's way of convincing us you can dismember arms with a single shotgun shell.
> The Quake II engine source is released [on Github](https://github.com/id-Software/Quake-2).
1998 - Monolith created **LithTech 1.0** to use in Shogo and Blood II. According to retro expert GmanLives, as good as Blood I is, Blood II was a total letdown. The engine will play a prominent role in the later years. Oh and v1.5 was used in [Might and Magic IX](/tags/might-and-magic/) - yeah...
![](/img/games/sof.jpg "Soldier Of Fortune 1")
1998 - Monolith created **LithTech 1.0** to use in Shogo and Blood II. According to retro expert GmanLives, as good as Blood I is, Blood II was a total letdown. The engine will play a prominent role in the later years. Oh and v1.5 was used in [Might and Magic IX](/tags/might-and-magic/) - arguably the worst Might and Magic ever...
### 3. Late 1990s: 32-bit color, GPUs become standard
1998 - And then, there was competition: **Unreal** and Unreal Tournament outmatched the Quake II engine on all aspects. Deus Ex also runs on the Unreal engine. In that same year, Valve posed as the third major FPS player with the release of **Half-life**.
![unreal tournament](/img/games/ut.jpg)
![](/img/games/ut.jpg "Unreal Tournament")
1999 - Quake III Arena, powered by **id Tech revision 3**, revolutionized (team) deathmatches and multiplayer FPS games. It is also one of the most common used game engines of the early 2000s: Return to Castle Wolfenstein, Medal of Honor: Allied Assault, Star Wars Jedi Knight II, Soldier of Fortune II, Call of Duty - you name it, they use it. I played all of these and have to say that they all ran smoothly, even with my then mid-range desktop computer.
@ -68,44 +76,48 @@ Playing Hexen, the medieval shooter running on the Doom engine, boiled down to m
> (Parts of) the LithTech 2 engine source is released [on Github](https://github.com/jsj2008/lithtech).
![no one lives forever 1](/img/games/nolf1.jpg)
![](/img/games/nolf1.jpg "No One Lives Forever")
### 4. Early 2000s: increasing detail, outdoor environments, rag-doll physics
At this point, I'm starting to doubt whether future shooters qualify for the keyword "_retro_" shooter. Pixels are far off and things are starting to look pretty realistic with rag-doll physics.
2000 - Operation Flashpoint claimed to be a super-realistic warfare shooter. It did take all the fun out of playing a shooter game, but the fights in the woods were impressive, I guess.
2001 - The **Serious Engine** was serious stuff (why so serious? got it?): trying to kill the player with hundreds of enemies in giant outdoor environments. Both the First and Second encounter got a HD remake in 2009 and 2010, powered by version 3 of the engine.
2001 - The **Serious Engine** was serious stuff (why so serious? got it?): trying to kill the player with hundreds of enemies in giant outdoor environments. Both the First and Second encounter got a HD remake in 2009 and 2010.
![](/img/games/serioussam1.jpg "Serious Sam: The First Encounter")
> The Serious Engine was released as open source [on Github](https://github.com/Croteam-official/Serious-Engine/).
![raven shield](/img/games/ravenshield.jpg)
2001 - Operation Flashpoint claimed to be a super-realistic warfare shooter. It did take all the fun out of playing a shooter game, but the fights in the woods were impressive, I guess.
2002 - My beloved Rainbow Six 3: Raven Shield was made possible thanks to the **Unreal 2** engine, also powering Unreal Tournament 2003. I can't count the hours my friend and me played Raven Shield's maps co-op. I still know almost every enemy spawn point by heart.
2002 - In the same year, Digital Illusions Creative Entertainment released the first **Battlefield** game (1942), of which the engine will be reused for three more of their games.
![](/img/games/ravenshield.jpg "Rainbow Six 3: Raven Shield")
2002 - In the same year, Digital Illusions Creative Entertainment released the first **Battlefield** game (1942), of which the engine will be reused for three more of their games, before switching to a proprietary engine.
2002 - **Lithtech Jupiter**, or LithTech 3.x, made No One Lives Forever 2: A Spy in H.A.R.M.'s Way possible. Hooray for shader models! It improved in almost all technical aspects of it's predecessor, but to be honest, I prefer the gameplay and humor in the original.
![no one lives forever 2](/img/games/nolf2.jpg)
![](/img/games/nolf2.jpg "No One Lives Forever 2: A Spy in H.A.R.M.'s way")
### 5. Mid 2000s: lighting and pixel shaders, physics
2004 - PC Gameplay magazines were full of tropical screenshots: Far Cry was more a technical showcase for the **CryEngine** than a game. And my graphics card almost blew up trying to run this thing.
2004 - The Unreal engine got another update. **v. 2.5**, good for UT2004, the not-so-great Duke Nukem Forever (2011), S.W.A.T. 4 (2004), and much later, another masterpiece: BioShock (2007). As a Raven Shield super-fan, I was really looking forward to S.W.A.T., and it delivered, but the engine and load times were pretty bad on my rig back then.
2004 - PC Gameplay magazines were full of tropical screenshots: Far Cry was more a technical showcase for the **CryEngine** than it was a good game. And my graphics card almost blew up trying to run this thing.
> The CRYENGINE-1 source is released [on Github](https://github.com/AFCStudio/CRYENGINE-1).
2004 - The Unreal engine got another update. **v. 2.5**, good for UT2004, the not-so-great Duke Nukem Forever (2011), S.W.A.T. 4 (2004), and especially: BioShock (2007). As a Raven Shield super-fan, I was really looking forward to S.W.A.T., and it delivered, but the engine and load times were pretty bad on my rig back then.
![](/img/games/farcry1.jpg "Far Cry")
2004 - The guys at id were also busy, rolling out **id Tech 4** for Doom 3 and Quake 5 a year later. The Wolfenstein reboot in 2009 also used tech v4. I skipped these games completely, being more involved with the Nintendo handhelds at that time.
2004 - The guys at id were also busy, rolling out **id Tech 4** for Doom 3 and Quake 4 a year later. The Wolfenstein reboot in 2009 also used tech v4. I skipped these games completely, being more involved with the Nintendo handhelds at that time.
> Doom 3 was released under the GPL [on Github](https://github.com/id-Software/DOOM-3).
![left 4 dead](/img/games/left4dead.jpg)
2004 - It must have been an amazing year for shooters. Valve's **Source engine** gave birth to Half-Life 2 and a shitload of spin-offs: Counter-Strike Source, Team Fortress II, Left 4 Dead and v2, Portal, ... It looks like all three major engines kept their releases in sync. As a co-op player, I enjoyed Left 4 dead the most.
![](/img/games/left4dead.jpg "Left 4 Dead")
2005 - Littech Jupiter got an update: **version EX** to be used with F.E.A.R. and the Condemned games.
### 6. Late 2000s and beyond: the approach to photorealism

BIN
static/img/games/doom1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
static/img/games/quake1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

@ -74,10 +74,6 @@ a.internal
cursor: pointer
img.full
width: 100% !important
#csslink
position: absolute
right: 0
@ -138,13 +134,23 @@ a.external
article
figure
margin-top: 1.5rem
margin-bottom: 1.5rem
figcaption
padding: 10px
text-align: center
font-style: italic
color: grey
img
cursor: pointer
border: 1px solid black
border-radius: 5px
.video-mask
padding-top: 1rem
padding-bottom: 1rem
padding-top: 1.2rem
padding-bottom: 1.2rem
width: 100%
border-radius: 5px
overflow: hidden
@ -253,3 +259,11 @@ a:hover, .box-masonry h4 a:hover
outline-color: transparent
-webkit-transition: top .1s ease-in
transition: top .1s ease-in
.sl-wrapper
.sl-counter
font-weight: bold
.sl-caption
text-align: center
background: rgba(0,0,0,0.65) !important

View File

@ -25,7 +25,16 @@
<hr/>
</header>
{{ .Content }}
<!-- thanks https://www.godo.dev/tutorials/hugo-image-figure-wrap/ -->
{{ $reAltIn := "<p><img src=\"([^\"]+)\" alt=\"([^\"]*)\" /></p>" }}
{{ $reAltOut := "<figure><a href=\"$1\" class=\"lbox\"><img src=\"$1\" alt=\"$2\"></a></figure>" }}
{{ $altContent := .Content | replaceRE $reAltIn $reAltOut | safeHTML }}
{{ $reAltTitleIn := "<p><img src=\"([^\"]+)\" alt=\"([^\"]*)\" title=\"([^\"]+)\" /></p>" }}
{{ $reAltTitleOut := "<figure><a href=\"$1\" class=\"lbox\"><img src=\"$1\" title=\"$3\"></a><figcaption>$3</figcaption></figure>" }}
{{ $finalContent := $altContent | replaceRE $reAltTitleIn $reAltTitleOut | safeHTML }}
{{ $finalContent }}
{{ if isset $.Params "tags" }}
<div class="categories">

View File

@ -95,6 +95,7 @@ body, article, h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
<link rel="stylesheet" href="{{ "css/bootstrap.min.css" | absURL }}">
<link rel="stylesheet" href="{{ "css/font-awesome.min.css" | absURL }}">
<link rel="stylesheet" href="{{ "css/simple-lightbox.min.css" | absURL }}">
<link href="{{ "css/style.default.css" | absURL }}" rel="stylesheet" id="theme-stylesheet">
{{- $options := (dict "targetPath" "css/styles.css" "outputStyle" "compressed" "enableSourceMap" "true") -}}
{{- $styles := resources.Get "sass/main.sass" | resources.ExecuteAsTemplate "main.sass" . | resources.ToCSS $options | resources.Fingerprint "sha512" }}

View File

@ -1,5 +1,5 @@
<script src="{{ "js/scrollingelement.js" | absURL }}"></script>
<script defer src="{{ "js/scrollingelement.js" | absURL }}"></script>
<script src="{{ "js/jquery.min.js" | absURL }}"></script>
<script src="{{ "js/bootstrap.min.js" | absURL }}"></script>
<script src="{{ "js/ekko-lightbox.js" | absURL }}"></script>
<script defer src="{{ "js/bootstrap.min.js" | absURL }}"></script>
<script defer src='/js/simple-lightbox.min.js'></script>
<script src="{{ "js/codex.js" | absURL }}"></script>

View File

@ -0,0 +1,7 @@
/*!
By André Rinas, www.andrerinas.de
Documentation, www.simplelightbox.de
Available for use under the MIT License
Version 2.1.5
*/
body.hidden-scroll{overflow:hidden}.sl-overlay{position:fixed;left:0;right:0;top:0;bottom:0;background:#fff;opacity:.7;display:none;z-index:1035}.sl-wrapper{z-index:1040}.sl-wrapper *{box-sizing:border-box}.sl-wrapper button{border:0 none;background:transparent;font-size:28px;padding:0;cursor:pointer}.sl-wrapper button:hover{opacity:0.7}.sl-wrapper .sl-close{display:none;position:fixed;right:30px;top:30px;z-index:10060;margin-top:-14px;margin-right:-14px;height:44px;width:44px;line-height:44px;font-family:Arial,Baskerville,monospace;color:#000;font-size:3rem}.sl-wrapper .sl-close:focus{outline:none}.sl-wrapper .sl-counter{display:none;position:fixed;top:30px;left:30px;z-index:1060;color:#000;font-size:1rem}.sl-wrapper .sl-navigation{width:100%;display:none}.sl-wrapper .sl-navigation button{position:fixed;top:50%;margin-top:-22px;height:44px;width:22px;line-height:44px;text-align:center;display:block;z-index:10060;font-family:Arial,Baskerville,monospace;color:#000}.sl-wrapper .sl-navigation button.sl-next{right:5px;font-size:2rem}.sl-wrapper .sl-navigation button.sl-prev{left:5px;font-size:2rem}.sl-wrapper .sl-navigation button:focus{outline:none}@media (min-width: 35.5em){.sl-wrapper .sl-navigation button{width:44px}.sl-wrapper .sl-navigation button.sl-next{right:10px;font-size:3rem}.sl-wrapper .sl-navigation button.sl-prev{left:10px;font-size:3rem}}@media (min-width: 50em){.sl-wrapper .sl-navigation button{width:44px}.sl-wrapper .sl-navigation button.sl-next{right:20px;font-size:3rem}.sl-wrapper .sl-navigation button.sl-prev{left:20px;font-size:3rem}}.sl-wrapper.sl-dir-rtl .sl-navigation{direction:ltr}.sl-wrapper .sl-image{position:fixed;-ms-touch-action:none;touch-action:none;z-index:10000}.sl-wrapper .sl-image img{margin:0;padding:0;display:block;border:0 none;width:100%;height:auto}@media (min-width: 35.5em){.sl-wrapper .sl-image img{border:0 none}}@media (min-width: 50em){.sl-wrapper .sl-image img{border:0 none}}.sl-wrapper .sl-image iframe{background:#000;border:0 none}@media (min-width: 35.5em){.sl-wrapper .sl-image iframe{border:0 none}}@media (min-width: 50em){.sl-wrapper .sl-image iframe{border:0 none}}.sl-wrapper .sl-image .sl-caption{display:none;padding:10px;color:#fff;background:rgba(0,0,0,0.8);font-size:1rem;position:absolute;bottom:0;left:0;right:0}.sl-wrapper .sl-image .sl-caption.pos-top{bottom:auto;top:0}.sl-wrapper .sl-image .sl-caption.pos-outside{bottom:auto}.sl-wrapper .sl-image .sl-download{display:none;position:absolute;bottom:5px;right:5px;color:#000;z-index:1060}.sl-spinner{display:none;border:5px solid #333;border-radius:40px;height:40px;left:50%;margin:-20px 0 0 -20px;opacity:0;position:fixed;top:50%;width:40px;z-index:1007;-webkit-animation:pulsate 1s ease-out infinite;-moz-animation:pulsate 1s ease-out infinite;-ms-animation:pulsate 1s ease-out infinite;-o-animation:pulsate 1s ease-out infinite;animation:pulsate 1s ease-out infinite}.sl-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.sl-transition{transition:-moz-transform ease 200ms;transition:-ms-transform ease 200ms;transition:-o-transform ease 200ms;transition:-webkit-transform ease 200ms;transition:transform ease 200ms}@-webkit-keyframes pulsate{0%{transform:scale(0.1);opacity:0.0}50%{opacity:1}100%{transform:scale(1.2);opacity:0}}@keyframes pulsate{0%{transform:scale(0.1);opacity:0.0}50%{opacity:1}100%{transform:scale(1.2);opacity:0}}@-moz-keyframes pulsate{0%{transform:scale(0.1);opacity:0.0}50%{opacity:1}100%{transform:scale(1.2);opacity:0}}@-o-keyframes pulsate{0%{transform:scale(0.1);opacity:0.0}50%{opacity:1}100%{transform:scale(1.2);opacity:0}}@-ms-keyframes pulsate{0%{transform:scale(0.1);opacity:0.0}50%{opacity:1}100%{transform:scale(1.2);opacity:0}}

View File

@ -12,13 +12,7 @@ $(function() {
addResponsiveTagToContentImages();
disableResponsiveImagesForInlineLis();
function lightbox() {
$(document).delegate('*[data-toggle="lightbox"]', 'click', function (event) {
event.preventDefault();
$(this).ekkoLightbox();
});
};
lightbox();
const box = new SimpleLightbox('.lbox', { /* options */ });
function offCanvas() {
$('[data-toggle="offcanvas"]').click(function () {
@ -52,15 +46,6 @@ $(function() {
};
addTargetBlankToExternalLinks();
var enableLightboxOnClickImgInContent = function() {
$('article img').click(function(e) {
var me = $(this);
e.preventDefault();
me.data('remote', me.attr('src'));
me.ekkoLightbox();
});
};
var enableScrollToTopOnInternalLinks = function() {
$('#totop').click(function() {
$("html, body").animate({ scrollTop: 0 }, "slow");
@ -111,5 +96,4 @@ $(function() {
setSideBarPlatformHeight();
addRandomImageToSideBarMenus();
enableScrollToTopOnInternalLinks();
enableLightboxOnClickImgInContent();
});

View File

@ -1,400 +0,0 @@
/*
Lightbox for Bootstrap 3 by @ashleydw
https://github.com/ashleydw/lightbox
License: https://github.com/ashleydw/lightbox/blob/master/LICENSE
*/
(function() {
"use strict";
var $, EkkoLightbox;
$ = jQuery;
EkkoLightbox = function(element, options) {
var content, footer, header,
_this = this;
this.options = $.extend({
title: null,
footer: null,
remote: null
}, $.fn.ekkoLightbox.defaults, options || {});
this.$element = $(element);
content = '';
this.modal_id = this.options.modal_id ? this.options.modal_id : 'ekkoLightbox-' + Math.floor((Math.random() * 1000) + 1);
header = '<div class="modal-header"' + (this.options.title || this.options.always_show_close ? '' : ' style="display:none"') + '><button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button><h4 class="modal-title">' + (this.options.title || "&nbsp;") + '</h4></div>';
footer = '<div class="modal-footer"' + (this.options.footer ? '' : ' style="display:none"') + '>' + this.options.footer + '</div>';
$(document.body).append('<div id="' + this.modal_id + '" class="ekko-lightbox modal fade" tabindex="-1"><div class="modal-dialog"><div class="modal-content">' + header + '<div class="modal-body"><div class="ekko-lightbox-container"><div></div></div></div>' + footer + '</div></div></div>');
this.modal = $('#' + this.modal_id);
this.modal_dialog = this.modal.find('.modal-dialog').first();
this.modal_content = this.modal.find('.modal-content').first();
this.modal_body = this.modal.find('.modal-body').first();
this.lightbox_container = this.modal_body.find('.ekko-lightbox-container').first();
this.lightbox_body = this.lightbox_container.find('> div:first-child').first();
this.showLoading();
this.modal_arrows = null;
this.border = {
top: parseFloat(this.modal_dialog.css('border-top-width')) + parseFloat(this.modal_content.css('border-top-width')) + parseFloat(this.modal_body.css('border-top-width')),
right: parseFloat(this.modal_dialog.css('border-right-width')) + parseFloat(this.modal_content.css('border-right-width')) + parseFloat(this.modal_body.css('border-right-width')),
bottom: parseFloat(this.modal_dialog.css('border-bottom-width')) + parseFloat(this.modal_content.css('border-bottom-width')) + parseFloat(this.modal_body.css('border-bottom-width')),
left: parseFloat(this.modal_dialog.css('border-left-width')) + parseFloat(this.modal_content.css('border-left-width')) + parseFloat(this.modal_body.css('border-left-width'))
};
this.padding = {
top: parseFloat(this.modal_dialog.css('padding-top')) + parseFloat(this.modal_content.css('padding-top')) + parseFloat(this.modal_body.css('padding-top')),
right: parseFloat(this.modal_dialog.css('padding-right')) + parseFloat(this.modal_content.css('padding-right')) + parseFloat(this.modal_body.css('padding-right')),
bottom: parseFloat(this.modal_dialog.css('padding-bottom')) + parseFloat(this.modal_content.css('padding-bottom')) + parseFloat(this.modal_body.css('padding-bottom')),
left: parseFloat(this.modal_dialog.css('padding-left')) + parseFloat(this.modal_content.css('padding-left')) + parseFloat(this.modal_body.css('padding-left'))
};
this.modal.on('show.bs.modal', this.options.onShow.bind(this)).on('shown.bs.modal', function() {
_this.modal_shown();
return _this.options.onShown.call(_this);
}).on('hide.bs.modal', this.options.onHide.bind(this)).on('hidden.bs.modal', function() {
if (_this.gallery) {
$(document).off('keydown.ekkoLightbox');
}
_this.modal.remove();
return _this.options.onHidden.call(_this);
}).modal('show', options);
return this.modal;
};
EkkoLightbox.prototype = {
modal_shown: function() {
var video_id,
_this = this;
if (!this.options.remote) {
return this.error('No remote target given');
} else {
this.gallery = this.$element.data('gallery');
if (this.gallery) {
if (this.options.gallery_parent_selector === 'document.body' || this.options.gallery_parent_selector === '') {
this.gallery_items = $(document.body).find('*[data-toggle="lightbox"][data-gallery="' + this.gallery + '"]');
} else {
this.gallery_items = this.$element.parents(this.options.gallery_parent_selector).first().find('*[data-toggle="lightbox"][data-gallery="' + this.gallery + '"]');
}
this.gallery_index = this.gallery_items.index(this.$element);
$(document).on('keydown.ekkoLightbox', this.navigate.bind(this));
if (this.options.directional_arrows && this.gallery_items.length > 1) {
this.lightbox_container.append('<div class="ekko-lightbox-nav-overlay"><a href="#" class="' + this.strip_stops(this.options.left_arrow_class) + '"></a><a href="#" class="' + this.strip_stops(this.options.right_arrow_class) + '"></a></div>');
this.modal_arrows = this.lightbox_container.find('div.ekko-lightbox-nav-overlay').first();
this.lightbox_container.find('a' + this.strip_spaces(this.options.left_arrow_class)).on('click', function(event) {
event.preventDefault();
return _this.navigate_left();
});
this.lightbox_container.find('a' + this.strip_spaces(this.options.right_arrow_class)).on('click', function(event) {
event.preventDefault();
return _this.navigate_right();
});
}
}
if (this.options.type) {
if (this.options.type === 'image') {
return this.preloadImage(this.options.remote, true);
} else if (this.options.type === 'youtube' && (video_id = this.getYoutubeId(this.options.remote))) {
return this.showYoutubeVideo(video_id);
} else if (this.options.type === 'vimeo') {
return this.showVimeoVideo(this.options.remote);
} else if (this.options.type === 'instagram') {
return this.showInstagramVideo(this.options.remote);
} else if (this.options.type === 'url') {
return this.loadRemoteContent(this.options.remote);
} else if (this.options.type === 'video') {
return this.showVideoIframe(this.options.remote);
} else {
return this.error("Could not detect remote target type. Force the type using data-type=\"image|youtube|vimeo|instagram|url|video\"");
}
} else {
return this.detectRemoteType(this.options.remote);
}
}
},
strip_stops: function(str) {
return str.replace(/\./g, '');
},
strip_spaces: function(str) {
return str.replace(/\s/g, '');
},
isImage: function(str) {
return str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
},
isSwf: function(str) {
return str.match(/\.(swf)((\?|#).*)?$/i);
},
getYoutubeId: function(str) {
var match;
match = str.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/);
if (match && match[2].length === 11) {
return match[2];
} else {
return false;
}
},
getVimeoId: function(str) {
if (str.indexOf('vimeo') > 0) {
return str;
} else {
return false;
}
},
getInstagramId: function(str) {
if (str.indexOf('instagram') > 0) {
return str;
} else {
return false;
}
},
navigate: function(event) {
event = event || window.event;
if (event.keyCode === 39 || event.keyCode === 37) {
if (event.keyCode === 39) {
return this.navigate_right();
} else if (event.keyCode === 37) {
return this.navigate_left();
}
}
},
navigateTo: function(index) {
var next, src;
if (index < 0 || index > this.gallery_items.length - 1) {
return this;
}
this.showLoading();
this.gallery_index = index;
this.$element = $(this.gallery_items.get(this.gallery_index));
this.updateTitleAndFooter();
src = this.$element.attr('data-remote') || this.$element.attr('href');
this.detectRemoteType(src, this.$element.attr('data-type') || false);
if (this.gallery_index + 1 < this.gallery_items.length) {
next = $(this.gallery_items.get(this.gallery_index + 1), false);
src = next.attr('data-remote') || next.attr('href');
if (next.attr('data-type') === 'image' || this.isImage(src)) {
return this.preloadImage(src, false);
}
}
},
navigate_left: function() {
if (this.gallery_items.length === 1) {
return;
}
if (this.gallery_index === 0) {
this.gallery_index = this.gallery_items.length - 1;
} else {
this.gallery_index--;
}
this.options.onNavigate.call(this, 'left', this.gallery_index);
return this.navigateTo(this.gallery_index);
},
navigate_right: function() {
if (this.gallery_items.length === 1) {
return;
}
if (this.gallery_index === this.gallery_items.length - 1) {
this.gallery_index = 0;
} else {
this.gallery_index++;
}
this.options.onNavigate.call(this, 'right', this.gallery_index);
return this.navigateTo(this.gallery_index);
},
detectRemoteType: function(src, type) {
var video_id;
type = type || false;
if (type === 'image' || this.isImage(src)) {
this.options.type = 'image';
return this.preloadImage(src, true);
} else if (type === 'youtube' || (video_id = this.getYoutubeId(src))) {
this.options.type = 'youtube';
return this.showYoutubeVideo(video_id);
} else if (type === 'vimeo' || (video_id = this.getVimeoId(src))) {
this.options.type = 'vimeo';
return this.showVimeoVideo(video_id);
} else if (type === 'instagram' || (video_id = this.getInstagramId(src))) {
this.options.type = 'instagram';
return this.showInstagramVideo(video_id);
} else if (type === 'video') {
this.options.type = 'video';
return this.showVideoIframe(video_id);
} else {
this.options.type = 'url';
return this.loadRemoteContent(src);
}
},
updateTitleAndFooter: function() {
var caption, footer, header, title;
header = this.modal_content.find('.modal-header');
footer = this.modal_content.find('.modal-footer');
title = this.$element.data('title') || "";
caption = this.$element.data('footer') || "";
if (title || this.options.always_show_close) {
header.css('display', '').find('.modal-title').html(title || "&nbsp;");
} else {
header.css('display', 'none');
}
if (caption) {
footer.css('display', '').html(caption);
} else {
footer.css('display', 'none');
}
return this;
},
showLoading: function() {
this.lightbox_body.html('<div class="modal-loading">' + this.options.loadingMessage + '</div>');
return this;
},
showYoutubeVideo: function(id) {
var height, width;
width = this.checkDimensions(this.$element.data('width') || 560);
height = width / (560 / 315);
return this.showVideoIframe('//www.youtube.com/embed/' + id + '?badge=0&autoplay=1&html5=1', width, height);
},
showVimeoVideo: function(id) {
var height, width;
width = this.checkDimensions(this.$element.data('width') || 560);
height = width / (500 / 281);
return this.showVideoIframe(id + '?autoplay=1', width, height);
},
showInstagramVideo: function(id) {
var height, width;
width = this.checkDimensions(this.$element.data('width') || 612);
this.resize(width);
height = width + 80;
this.lightbox_body.html('<iframe width="' + width + '" height="' + height + '" src="' + this.addTrailingSlash(id) + 'embed/" frameborder="0" allowfullscreen></iframe>');
this.options.onContentLoaded.call(this);
if (this.modal_arrows) {
return this.modal_arrows.css('display', 'none');
}
},
showVideoIframe: function(url, width, height) {
height = height || width;
this.resize(width);
this.lightbox_body.html('<div class="embed-responsive embed-responsive-16by9"><iframe width="' + width + '" height="' + height + '" src="' + url + '" frameborder="0" allowfullscreen class="embed-responsive-item"></iframe></div>');
this.options.onContentLoaded.call(this);
if (this.modal_arrows) {
this.modal_arrows.css('display', 'none');
}
return this;
},
loadRemoteContent: function(url) {
var disableExternalCheck, width,
_this = this;
width = this.$element.data('width') || 560;
this.resize(width);
disableExternalCheck = this.$element.data('disableExternalCheck') || false;
if (!disableExternalCheck && !this.isExternal(url)) {
this.lightbox_body.load(url, $.proxy(function() {
return _this.$element.trigger('loaded.bs.modal');
}));
} else {
this.lightbox_body.html('<iframe width="' + width + '" height="' + width + '" src="' + url + '" frameborder="0" allowfullscreen></iframe>');
this.options.onContentLoaded.call(this);
}
if (this.modal_arrows) {
this.modal_arrows.css('display', 'none');
}
return this;
},
isExternal: function(url) {
var match;
match = url.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);
if (typeof match[1] === "string" && match[1].length > 0 && match[1].toLowerCase() !== location.protocol) {
return true;
}
if (typeof match[2] === "string" && match[2].length > 0 && match[2].replace(new RegExp(":(" + {
"http:": 80,
"https:": 443
}[location.protocol] + ")?$"), "") !== location.host) {
return true;
}
return false;
},
error: function(message) {
this.lightbox_body.html(message);
return this;
},
preloadImage: function(src, onLoadShowImage) {
var img,
_this = this;
img = new Image();
if ((onLoadShowImage == null) || onLoadShowImage === true) {
img.onload = function() {
var image;
image = $('<img />');
image.attr('src', img.src);
image.addClass('img-responsive');
_this.lightbox_body.html(image);
if (_this.modal_arrows) {
_this.modal_arrows.css('display', 'block');
}
return image.load(function() {
_this.resize(img.width);
return _this.options.onContentLoaded.call(_this);
});
};
img.onerror = function() {
return _this.error('Failed to load image: ' + src);
};
}
img.src = src;
return img;
},
resize: function(width) {
var width_total;
width_total = width + this.border.left + this.padding.left + this.padding.right + this.border.right;
this.modal_dialog.css('width', 'auto').css('max-width', width_total);
this.lightbox_container.find('a').css('line-height', function() {
return $(this).parent().height() + 'px';
});
return this;
},
checkDimensions: function(width) {
var body_width, width_total;
width_total = width + this.border.left + this.padding.left + this.padding.right + this.border.right;
body_width = document.body.clientWidth;
if (width_total > body_width) {
width = this.modal_body.width();
}
return width;
},
close: function() {
return this.modal.modal('hide');
},
addTrailingSlash: function(url) {
if (url.substr(-1) !== '/') {
url += '/';
}
return url;
}
};
$.fn.ekkoLightbox = function(options) {
return this.each(function() {
var $this;
$this = $(this);
options = $.extend({
remote: $this.attr('data-remote') || $this.attr('href'),
gallery_parent_selector: $this.attr('data-parent'),
type: $this.attr('data-type')
}, options, $this.data());
new EkkoLightbox(this, options);
return this;
});
};
$.fn.ekkoLightbox.defaults = {
gallery_parent_selector: 'document.body',
left_arrow_class: '.glyphicon .glyphicon-chevron-left',
right_arrow_class: '.glyphicon .glyphicon-chevron-right',
directional_arrows: true,
type: null,
always_show_close: true,
loadingMessage: 'Loading...',
onShow: function() {},
onShown: function() {},
onHide: function() {},
onHidden: function() {},
onNavigate: function() {},
onContentLoaded: function() {}
};
}).call(this);

File diff suppressed because one or more lines are too long