Skip to content

Commit

Permalink
add a lightbox
Browse files Browse the repository at this point in the history
  • Loading branch information
stebunovd committed Jul 7, 2024
1 parent 96e82b7 commit c7d028b
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 8 deletions.
8 changes: 4 additions & 4 deletions content/on-estimates/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ thing happens, just later. As a rule of thumb, you may think of deadlines as
"the earliest dates when something can be delivered." So no matter whether they
over- or underestimated, nothing ships until the deadline.

![Productivity by Estimation Approach](peopleware-estimates.png)
[![Productivity by Estimation Approach](peopleware-estimates.png)](peopleware-estimates.png)

*Source: [Peopleware by Tom DeMarko and Timothy Lister](https://www.amazon.com/Peopleware-Productive-Projects-Tom-DeMarco/dp/0932633439)*

Expand Down Expand Up @@ -76,7 +76,7 @@ out-of-the-box product, or exist as a library or framework. Therefore, in most
cases, developers have to provide estimates for tasks that have a high degree
of uncertainty.

![Figuring out what to do – Getting it done](hill-concept.png)
[![Figuring out what to do – Getting it done](hill-concept.png)](hill-concept.png)

*Source: [Show Progress | Shape Up by BaseCamp](https://basecamp.com/shapeup/3.4-chapter-12)*

Expand Down Expand Up @@ -104,7 +104,7 @@ how many women are assigned." However, when people hear that a project will
take nine man-months, they sometimes assume that it probably can be three
months for three random developers.

![Mythical Man-Month](man-month.png)
[![Mythical Man-Month](man-month.png)](man-month.png)

*Source: [The Mythical Man-Month by Frederick P. Brooks](https://www.amazon.com/Mythical-Man-Month-Anniversary-Software-Engineering-ebook/dp/B00B8USS14/)*

Expand All @@ -117,7 +117,7 @@ deadline, but fail the task altogether.

## Initial development is a minor cost

![Maintenance vs. initial development](dev-maintenance.png)
[![Maintenance vs. initial development](dev-maintenance.png)](dev-maintenance.png)

Arguably the biggest problem with estimates is that people routinely ask for
initial development estimates, but rarely ask for estimates about the
Expand Down
4 changes: 2 additions & 2 deletions content/router-or-moderator/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Each strategy has pros and cons.

## Router

![Manager as a router](manager-router.png)
[![Manager as a router](manager-router.png)](manager-router.png)

In *router* mode, the manager is responsible for all communication between the
engineering team and the stakeholders. Centralizing communication this way
Expand Down Expand Up @@ -68,7 +68,7 @@ Cons:

## Moderator

![Manager as a moderator](manager-moderator.png)
[![Manager as a moderator](manager-moderator.png)](manager-moderator.png)

An alternative approach is *moderator* mode, where the manager supervises while
stakeholders communicate directly with engineering team members. Everyone is
Expand Down
4 changes: 2 additions & 2 deletions content/three-steps/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ designer. For example, you can use a rapid wireframing tool like
quickly without spending time on minor visual details. Or, use a whiteboard or
good old pencil and paper. Any sketch is better than nothing.

![Low-fidelity Balsamiq wireframes](balsamiq.png)
[![Low-fidelity Balsamiq wireframes](balsamiq.png)](balsamiq.png)
*Low-fidelity [Balsamiq](https://balsamiq.com) wireframes*


Expand Down Expand Up @@ -113,7 +113,7 @@ diagram. ER diagrams are arguably the most useful part of the UML
specification. You may skip everything else in UML, but if you're working with
relational databases - don't skip ER diagrams :)

![ER diagram example](dbdiagram.png)
[![ER diagram example](dbdiagram.png)](dbdiagram.png)
*Credit: [dbdiagram.io](https://dbdiagram.io)*

## Summary
Expand Down
2 changes: 2 additions & 0 deletions layouts/partials/footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@
</div>
</footer>
<script src="/prettify.js"></script>
<script type="text/javascript" src="/lightbox.js"></script>
<link rel="stylesheet" href="/lightbox.css">
94 changes: 94 additions & 0 deletions static/lightbox.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#lightbox {width: 100%; height: 100%; position: fixed; top: 0; left: 0; background: rgba(0,0,0,0.85); z-index: 9999999; line-height: 0; cursor: pointer; display: none;}
#lightbox .img {
position: relative;
top: 50%;
left: 50%;
-ms-transform: translateX(-50%) translateY(-50%);
-webkit-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
max-width: 100%;
max-height: 100%;
}
#lightbox .img img {opacity: 0; pointer-events: none; width: auto;}
@media screen and (min-width: 1200px) {
#lightbox .img {
max-width: 1200px;
}
}
@media screen and (min-height: 1200px) {
#lightbox .img {
max-height: 1200px;
}
}
#lightbox span {display: block; position: fixed; bottom: 13px; height: 1.5em; line-height: 1.4em; width: 100%; text-align: center; color: white; text-shadow:
-1px -1px 0 #000,
1px -1px 0 #000,
-1px 1px 0 #000,
1px 1px 0 #000;
}

#lightbox span {display: none;}

#lightbox .videoWrapperContainer {
position: relative;
top: 50%;
left: 50%;
-ms-transform: translateX(-50%) translateY(-50%);
-webkit-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
max-width: 900px;
max-height: 100%;
}
#lightbox .videoWrapperContainer .videoWrapper {
height: 0;
line-height: 0;
margin: 0;
padding: 0;
position: relative;
padding-bottom: 56.333%; /* custom */
background: black;
}
#lightbox .videoWrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 0;
display: block;
}
#lightbox #prev, #lightbox #next {height: 50px; line-height: 36px; display: none; margin-top: -25px; position: fixed; top: 50%; padding: 0 15px; cursor: pointer; text-decoration: none; z-index: 99; color: white; font-size: 60px;}
#lightbox.gallery #prev, #lightbox.gallery #next {display: block;}
#lightbox #prev {left: 0;}
#lightbox #next {right: 0;}
#lightbox #close {height: 50px; width: 50px; position: fixed; cursor: pointer; text-decoration: none; z-index: 99; right: 0; top: 0;}
#lightbox #close:after, #lightbox #close:before {position: absolute; margin-top: 22px; margin-left: 14px; content: ""; height: 3px; background: white; width: 23px;
-webkit-transform-origin: 50% 50%;
-moz-transform-origin: 50% 50%;
-o-transform-origin: 50% 50%;
transform-origin: 50% 50%;
/* Safari */
-webkit-transform: rotate(-45deg);
/* Firefox */
-moz-transform: rotate(-45deg);
/* IE */
-ms-transform: rotate(-45deg);
/* Opera */
-o-transform: rotate(-45deg);
}
#lightbox #close:after {
/* Safari */
-webkit-transform: rotate(45deg);
/* Firefox */
-moz-transform: rotate(45deg);
/* IE */
-ms-transform: rotate(45deg);
/* Opera */
-o-transform: rotate(45deg);
}
#lightbox, #lightbox * {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
141 changes: 141 additions & 0 deletions static/lightbox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
function is_youtubelink(url) {
var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
return (url.match(p)) ? RegExp.$1 : false;
}
function is_imagelink(url) {
var p = /([a-z\-_0-9\/\:\.]*\.(jpg|jpeg|png|gif))/i;
return (url.match(p)) ? true : false;
}
function is_vimeolink(url,el) {
var id = false;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) { // XMLHttpRequest.DONE == 4
if (xmlhttp.status == 200) {
var response = JSON.parse(xmlhttp.responseText);
id = response.video_id;
console.log(id);
el.classList.add('lightbox-vimeo');
el.setAttribute('data-id',id);

el.addEventListener("click", function(event) {
event.preventDefault();
document.getElementById('lightbox').innerHTML = '<a id="close"></a><a id="next">&rsaquo;</a><a id="prev">&lsaquo;</a><div class="videoWrapperContainer"><div class="videoWrapper"><iframe src="https://player.vimeo.com/video/'+el.getAttribute('data-id')+'/?autoplay=1&byline=0&title=0&portrait=0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div></div>';
document.getElementById('lightbox').style.display = 'block';

setGallery(this);
});
}
else if (xmlhttp.status == 400) {
alert('There was an error 400');
}
else {
alert('something else other than 200 was returned');
}
}
};
xmlhttp.open("GET", 'https://vimeo.com/api/oembed.json?url='+url, true);
xmlhttp.send();
}
function setGallery(el) {
var elements = document.body.querySelectorAll(".gallery");
elements.forEach(element => {
element.classList.remove('gallery');
});
if(el.closest('ul, p')) {
var link_elements = el.closest('ul, p').querySelectorAll("a[class*='lightbox-']");
link_elements.forEach(link_element => {
link_element.classList.remove('current');
});
link_elements.forEach(link_element => {
if(el.getAttribute('href') == link_element.getAttribute('href')) {
link_element.classList.add('current');
}
});
if(link_elements.length>1) {
document.getElementById('lightbox').classList.add('gallery');
link_elements.forEach(link_element => {
link_element.classList.add('gallery');
});
}
var currentkey;
var gallery_elements = document.querySelectorAll('a.gallery');
Object.keys(gallery_elements).forEach(function (k) {
if(gallery_elements[k].classList.contains('current')) currentkey = k;
});
if(currentkey==(gallery_elements.length-1)) var nextkey = 0;
else var nextkey = parseInt(currentkey)+1;
if(currentkey==0) var prevkey = parseInt(gallery_elements.length-1);
else var prevkey = parseInt(currentkey)-1;
document.getElementById('next').addEventListener("click", function() {
gallery_elements[nextkey].click();
});
document.getElementById('prev').addEventListener("click", function() {
gallery_elements[prevkey].click();
});
}
}

document.addEventListener("DOMContentLoaded", function() {

//create lightbox div in the footer
var newdiv = document.createElement("div");
newdiv.setAttribute('id',"lightbox");
document.body.appendChild(newdiv);

//add classes to links to be able to initiate lightboxes
var elements = document.querySelectorAll('a');
elements.forEach(element => {
var url = element.getAttribute('href');
if(url) {
if(url.indexOf('vimeo') !== -1 && !element.classList.contains('no-lightbox')) {
is_vimeolink(url,element);
}
if(is_youtubelink(url) && !element.classList.contains('no-lightbox')) {
element.classList.add('lightbox-youtube');
element.setAttribute('data-id',is_youtubelink(url));
}
if(is_imagelink(url) && !element.classList.contains('no-lightbox')) {
element.classList.add('lightbox-image');
var href = element.getAttribute('href');
var filename = href.split('/').pop();
var split = filename.split(".");
var name = split[0];
element.setAttribute('title',name);
}
}
});

//remove the clicked lightbox
document.getElementById('lightbox').addEventListener("click", function(event) {
if(event.target.id != 'next' && event.target.id != 'prev'){
this.innerHTML = '';
document.getElementById('lightbox').style.display = 'none';
}
});

//add the youtube lightbox on click
var elements = document.querySelectorAll('a.lightbox-youtube');
elements.forEach(element => {
element.addEventListener("click", function(event) {
event.preventDefault();
document.getElementById('lightbox').innerHTML = '<a id="close"></a><a id="next">&rsaquo;</a><a id="prev">&lsaquo;</a><div class="videoWrapperContainer"><div class="videoWrapper"><iframe src="https://www.youtube.com/embed/'+this.getAttribute('data-id')+'?autoplay=1&showinfo=0&rel=0"></iframe></div>';
document.getElementById('lightbox').style.display = 'block';

setGallery(this);
});
});

//add the image lightbox on click
var elements = document.querySelectorAll('a.lightbox-image');
elements.forEach(element => {
element.addEventListener("click", function(event) {
event.preventDefault();
document.getElementById('lightbox').innerHTML = '<a id="close"></a><a id="next">&rsaquo;</a><a id="prev">&lsaquo;</a><div class="img" style="background: url(\''+this.getAttribute('href')+'\') center center / contain no-repeat;" title="'+this.getAttribute('title')+'" ><img src="'+this.getAttribute('href')+'" alt="'+this.getAttribute('title')+'" /></div><span>'+this.getAttribute('title')+'</span>';
document.getElementById('lightbox').style.display = 'block';

setGallery(this);
});
});

});

0 comments on commit c7d028b

Please sign in to comment.