create repo for 0x2620.org/jpg
286
css/jpg.css
Normal file
|
@ -0,0 +1,286 @@
|
||||||
|
a {
|
||||||
|
color: rgb(255, 255, 255);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
background: rgb(64, 64, 64);
|
||||||
|
font-family: Lucida Grande;
|
||||||
|
font-size: 10px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
div, img {
|
||||||
|
-webkit-user-select: none;
|
||||||
|
}
|
||||||
|
div.button {
|
||||||
|
float: left;
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
border: 3px solid rgba(255, 255, 255, 1);
|
||||||
|
margin: 4px;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
cursor: pointer;
|
||||||
|
-moz-border-radius: 12px;
|
||||||
|
-moz-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
-webkit-border-radius: 12px;
|
||||||
|
-webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
}
|
||||||
|
div.button:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.75);
|
||||||
|
}
|
||||||
|
div.background {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.25);
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 1500;
|
||||||
|
}
|
||||||
|
div.dialog {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 135px;
|
||||||
|
margin: auto;
|
||||||
|
width: 405px;
|
||||||
|
height: 170px;
|
||||||
|
opacity: 0;
|
||||||
|
-moz-border-radius: 8px;
|
||||||
|
-moz-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
-webkit-border-radius: 8px;
|
||||||
|
-webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
}
|
||||||
|
div.dialog > .title {
|
||||||
|
width: 389px;
|
||||||
|
height: 14px;
|
||||||
|
padding: 5px 8px 5px 8px;
|
||||||
|
background: -moz-linear-gradient(top, rgb(80, 80, 80), rgb(48, 48, 48));
|
||||||
|
background: -webkit-gradient(linear, left top, left bottom, from(rgb(80, 80, 80)), to(rgb(48, 48, 48)));
|
||||||
|
font-family: Lucida Grande, Verdana, Calibri, Arial;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 10px;
|
||||||
|
text-align: left;
|
||||||
|
color: rgb(192, 192, 192);
|
||||||
|
-moz-border-radius-topleft: 8px;
|
||||||
|
-moz-border-radius-topright: 8px;
|
||||||
|
-webkit-border-top-left-radius: 8px;
|
||||||
|
-webkit-border-top-right-radius: 8px;
|
||||||
|
}
|
||||||
|
div.dialog > .text {
|
||||||
|
width: 373px;
|
||||||
|
height: 90px;
|
||||||
|
padding: 16px;
|
||||||
|
background: rgb(64, 64, 64);
|
||||||
|
font-family: Lucida Grande, Verdana, Calibri, Arial;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 10px;
|
||||||
|
text-align: left;
|
||||||
|
color: rgb(192, 192, 192);
|
||||||
|
}
|
||||||
|
div.dialog > .buttons {
|
||||||
|
width: 397px;
|
||||||
|
height: 24px;
|
||||||
|
padding: 0 4px 0 4px;
|
||||||
|
background: -moz-linear-gradient(top, rgb(80, 80, 80), rgb(48, 48, 48));
|
||||||
|
background: -webkit-gradient(linear, left top, left bottom, from(rgb(80, 80, 80)), to(rgb(48, 48, 48)));
|
||||||
|
-moz-border-radius-bottomleft: 8px;
|
||||||
|
-moz-border-radius-bottomright: 8px;
|
||||||
|
-webkit-border-bottom-left-radius: 8px;
|
||||||
|
-webkit-border-bottom-right-radius: 8px;
|
||||||
|
}
|
||||||
|
div.map {
|
||||||
|
position: fixed;
|
||||||
|
right: 8px;
|
||||||
|
bottom: 32px;
|
||||||
|
height: 90px;
|
||||||
|
border: 2px solid rgba(255, 255, 255, 1);
|
||||||
|
z-index: 500;
|
||||||
|
-moz-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
-webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
}
|
||||||
|
div.map > .box {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
border: 2px solid rgba(255, 255, 255, 1);
|
||||||
|
-moz-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
-webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
div.map > .interface {
|
||||||
|
position: fixed;
|
||||||
|
right: 8px;
|
||||||
|
bottom: 32px;
|
||||||
|
height: 90px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
div.input {
|
||||||
|
font-family: Lucida Grande, Verdana, Calibri, Arial;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 10px;
|
||||||
|
color: rgb(192, 192, 192);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
div.input, div.select {
|
||||||
|
float: left;
|
||||||
|
width: 117px;
|
||||||
|
height: 12px;
|
||||||
|
padding: 1px 8px 1px 8px;
|
||||||
|
border: 1px solid rgb(128, 128, 128);
|
||||||
|
margin: 4px;
|
||||||
|
background: rgba(0, 0, 0, 0.25);
|
||||||
|
cursor: pointer;
|
||||||
|
-moz-border-radius: 8px;
|
||||||
|
-webkit-border-radius: 8px;
|
||||||
|
-moz-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
-webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
}
|
||||||
|
div.input:hover, div.select:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
.buttons > div.input {
|
||||||
|
float: right;
|
||||||
|
width: 27px;
|
||||||
|
}
|
||||||
|
div.select > div {
|
||||||
|
width: 117px;
|
||||||
|
font-family: Lucida Grande, Verdana, Calibri, Arial;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 10px;
|
||||||
|
text-align: left;
|
||||||
|
color: rgb(192, 192, 192);
|
||||||
|
}
|
||||||
|
img.button {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
margin: 3px;
|
||||||
|
}
|
||||||
|
img.map {
|
||||||
|
height: 90px;
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
position: relative;
|
||||||
|
left: -9px;
|
||||||
|
top: -17px;
|
||||||
|
width: 135px;
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
.original {
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
|
.photo {
|
||||||
|
background: rgb(128, 128, 128);
|
||||||
|
position: fixed;
|
||||||
|
-moz-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
-webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
}
|
||||||
|
div.spinner {
|
||||||
|
position: fixed;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
background: rgba(0, 0, 0, 0.25);
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 250;
|
||||||
|
-moz-border-radius: 12px;
|
||||||
|
-webkit-border-radius: 12px;
|
||||||
|
}
|
||||||
|
img.spinner {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
margin: 3px;
|
||||||
|
}
|
||||||
|
.thumbnail {
|
||||||
|
float: left;
|
||||||
|
//width: 135px;
|
||||||
|
height: 90px;
|
||||||
|
margin: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
-moz-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
-webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
}
|
||||||
|
.thumbnail.loading {
|
||||||
|
background: rgb(128, 128, 128);
|
||||||
|
}
|
||||||
|
.tooltip {
|
||||||
|
position: fixed;
|
||||||
|
width: 135px;
|
||||||
|
bottom: 6px;
|
||||||
|
font-family: Lucida Grande, Verdana, Calibri, Arial;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 10px;
|
||||||
|
color: rgb(192, 192, 192);
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: rgb(0, 0, 0) 1px 1px 2px;
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
#album {
|
||||||
|
//position: absolute;
|
||||||
|
//top: 0;
|
||||||
|
//width: auto;
|
||||||
|
//margin: 0 auto 36px auto;
|
||||||
|
padding: 12px;
|
||||||
|
display: table-cell;
|
||||||
|
}
|
||||||
|
#buttons {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 160px;
|
||||||
|
height: 32px;
|
||||||
|
bottom: 24px;
|
||||||
|
padding: 4px;
|
||||||
|
margin: 0px auto 0px auto;
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
//background: red;
|
||||||
|
}
|
||||||
|
#interface {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 24px;
|
||||||
|
cursor: move;
|
||||||
|
display: none;
|
||||||
|
opacity: 0;
|
||||||
|
z-index: 500;
|
||||||
|
}
|
||||||
|
#layer {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 24px;
|
||||||
|
background: rgb(64, 64, 64);
|
||||||
|
display: none;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
#menu {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 24px;
|
||||||
|
background: -moz-linear-gradient(top, rgb(80, 80, 80), rgb(48, 48, 48));
|
||||||
|
background: -webkit-gradient(linear, left top, left bottom, from(rgb(80, 80, 80)), to(rgb(48, 48, 48)));
|
||||||
|
//opacity: 0.9;
|
||||||
|
z-index: 500;
|
||||||
|
-moz-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
-webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 1);
|
||||||
|
}
|
||||||
|
#left {
|
||||||
|
position: fixed;
|
||||||
|
left: 4px;
|
||||||
|
}
|
||||||
|
#right {
|
||||||
|
position: fixed;
|
||||||
|
right: 4px;
|
||||||
|
}
|
17
index.html
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>0x2620.org/jpg</title>
|
||||||
|
<link rel="shortcut icon" type="image/png" href="../png/0x2620.16.png"/>
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/jpg.css"/>
|
||||||
|
<script type="text/javascript" src="js/jquery.js"></script>
|
||||||
|
<script type="text/javascript" src="js/jpg.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="album"></div>
|
||||||
|
<div id="menu">
|
||||||
|
<div id="left"></div>
|
||||||
|
<div id="right"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
767
js/jpg.js
Normal file
|
@ -0,0 +1,767 @@
|
||||||
|
/*
|
||||||
|
2010 0x2620.org GPL v3
|
||||||
|
TODO: migrate to ox.js
|
||||||
|
(& sorry for the mess)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
|
||||||
|
if ($.browser.msie) {
|
||||||
|
alert("Please use Firefox, Safari or Chrome.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var $body = $("body"),
|
||||||
|
$document = $(document),
|
||||||
|
$window = $(window),
|
||||||
|
$album = $("#album"),
|
||||||
|
json,
|
||||||
|
users = [],
|
||||||
|
albums = {},
|
||||||
|
split = location.hash.substr(1).replace("_", " ").split("/"),
|
||||||
|
user = split[0] || "S",
|
||||||
|
album = split[1] || "Beirut",
|
||||||
|
photoid = split[2] || "",
|
||||||
|
hash = photoid ? [user, album, photoid].join("/") : [user, album].join("/"),
|
||||||
|
windowWidth = $window.width(),
|
||||||
|
windowHeight = $window.height() - 24,
|
||||||
|
windowRatio = windowWidth / windowHeight,
|
||||||
|
photo = -1,
|
||||||
|
photos = [],
|
||||||
|
thumbnails = [],
|
||||||
|
playInterval,
|
||||||
|
buttonTimeout,
|
||||||
|
$layer,
|
||||||
|
spinner;
|
||||||
|
|
||||||
|
location.hash = hash;
|
||||||
|
|
||||||
|
$.each(["Loading", "Close", "Previous", "Play", "Pause", "Next", "ZoomIn", "ZoomOut"], function(i, name) {
|
||||||
|
$("<img>").attr({
|
||||||
|
src: "png/symbol" + name + ".png"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function Album(username, albumname) {
|
||||||
|
var that = this,
|
||||||
|
data = json[username][albumname];
|
||||||
|
that.show = function() {
|
||||||
|
playInterval && $("#play").trigger("click");
|
||||||
|
$("#zoomin").attr("src") == "png/symbolZoomOut.png" && $("#zoomin").trigger("click");
|
||||||
|
$(".photo") && $("#close").trigger("click");
|
||||||
|
$album.empty();
|
||||||
|
album = albumname;
|
||||||
|
photos = [];
|
||||||
|
photo = -1;
|
||||||
|
$.each(data, function(i, image) {
|
||||||
|
photos[i] = image,
|
||||||
|
thumbnails[i] = new Thumbnail(i).show();
|
||||||
|
});
|
||||||
|
$("<br/>").attr({clear: "all"}).appendTo($album);
|
||||||
|
$("<div>")
|
||||||
|
.css({
|
||||||
|
height: "24px"
|
||||||
|
})
|
||||||
|
.appendTo($album);
|
||||||
|
$interface = $("<div>")
|
||||||
|
.attr({
|
||||||
|
id: "interface"
|
||||||
|
})
|
||||||
|
.appendTo($album);
|
||||||
|
$layer = $("<div>")
|
||||||
|
.attr({
|
||||||
|
id: "layer"
|
||||||
|
})
|
||||||
|
.appendTo($album);
|
||||||
|
setTimeout(function() {
|
||||||
|
location.hash = [user, album.replace(" ", "_")].join("/");
|
||||||
|
}, 500);
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Button(photo, name, tooltip) {
|
||||||
|
var that = this,
|
||||||
|
$div = $("<div>")
|
||||||
|
.addClass("button")
|
||||||
|
.mouseenter(showTooltip)
|
||||||
|
.mouseleave(hideTooltip)
|
||||||
|
.click(function() {
|
||||||
|
hideTooltip();
|
||||||
|
photo.click(name);
|
||||||
|
}),
|
||||||
|
$img = $("<img>")
|
||||||
|
.addClass("button")
|
||||||
|
.attr({
|
||||||
|
id: name.toLowerCase().replace(" ", ""),
|
||||||
|
src: "png/symbol" + name.replace(" ", "") + ".png",
|
||||||
|
})
|
||||||
|
.appendTo($div),
|
||||||
|
$tooltip;
|
||||||
|
function hideTooltip() {
|
||||||
|
$tooltip.animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 50, function() {
|
||||||
|
$tooltip.remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function showTooltip() {
|
||||||
|
$tooltip.html(that.tooltip).appendTo($body).animate({
|
||||||
|
opacity: 1
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
that.tooltip = tooltip;
|
||||||
|
that.show = function() {
|
||||||
|
$div.appendTo("#buttons");
|
||||||
|
$tooltip = $("<div>")
|
||||||
|
.addClass("tooltip")
|
||||||
|
.css({
|
||||||
|
left: ($div.offset().left - 52) + "px"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Dialog(title, text, buttons) {
|
||||||
|
var that = this,
|
||||||
|
$div = $("<div>")
|
||||||
|
.addClass("background");
|
||||||
|
$dialog = $("<div>")
|
||||||
|
.addClass("dialog")
|
||||||
|
.appendTo($div);
|
||||||
|
$title = $("<div>")
|
||||||
|
.addClass("title")
|
||||||
|
.html(title)
|
||||||
|
.appendTo($dialog);
|
||||||
|
$text = $("<div>")
|
||||||
|
.addClass("text")
|
||||||
|
.html(text)
|
||||||
|
.appendTo($dialog);
|
||||||
|
$buttons = $("<div>")
|
||||||
|
.addClass("buttons")
|
||||||
|
.appendTo($dialog);
|
||||||
|
new Input("Close", function() {
|
||||||
|
that.close();
|
||||||
|
}, $buttons).show();
|
||||||
|
that.close = function() {
|
||||||
|
$div.animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 250, function() {
|
||||||
|
$div.remove();
|
||||||
|
});
|
||||||
|
$dialog.animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 250);
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
that.open = function() {
|
||||||
|
$div.appendTo($body).animate({
|
||||||
|
opacity: 1
|
||||||
|
}, 250);
|
||||||
|
$dialog.animate({
|
||||||
|
opacity: 1
|
||||||
|
}, 250);
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Input(name, fn, $parent) {
|
||||||
|
var that = this,
|
||||||
|
$parent = $parent || $("#right"),
|
||||||
|
$div = $("<div>")
|
||||||
|
.addClass("input")
|
||||||
|
.html(name)
|
||||||
|
.click(fn);
|
||||||
|
that.show = function() {
|
||||||
|
$parent.append($div);
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Map() {
|
||||||
|
var that = this,
|
||||||
|
offset = $(".original").offset(), // fixme: needed?
|
||||||
|
thumbnailWidth = 90 * photos[photo].width / photos[photo].height,
|
||||||
|
thumbnailHeight = 90,
|
||||||
|
boxWidth = thumbnailWidth / photos[photo].width * windowWidth,
|
||||||
|
boxHeight = thumbnailHeight / photos[photo].height * windowHeight,
|
||||||
|
$div = $("<div>")
|
||||||
|
.addClass("map")
|
||||||
|
.css({
|
||||||
|
width: thumbnailWidth + "px"
|
||||||
|
}),
|
||||||
|
$img = $("<img>")
|
||||||
|
.addClass("map")
|
||||||
|
.attr({
|
||||||
|
src: photos[photo].file.replace("/IMG", "/90/IMG"),
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: thumbnailWidth + "px"
|
||||||
|
})
|
||||||
|
.appendTo($div),
|
||||||
|
$interface = $("<div>")
|
||||||
|
.addClass("interface")
|
||||||
|
.css({
|
||||||
|
width: thumbnailWidth + "px"
|
||||||
|
})
|
||||||
|
.click(function(e) {
|
||||||
|
var offset = $div.offset(),
|
||||||
|
left = Math.min(Math.max(e.clientX - offset.left - boxWidth / 2 - 2, 0), thumbnailWidth - boxWidth),
|
||||||
|
top = Math.min(Math.max(e.clientY - offset.top + $body.scrollTop() - boxHeight / 2 - 2, 0), thumbnailHeight - boxHeight);
|
||||||
|
$(".original").animate({
|
||||||
|
left: -(left * photos[photo].width / thumbnailWidth) + "px",
|
||||||
|
top: -(top * photos[photo].height / thumbnailHeight) + "px"
|
||||||
|
}, 250, function() {
|
||||||
|
that.update(true);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.appendTo($div);
|
||||||
|
$box = $("<div>")
|
||||||
|
.addClass("box")
|
||||||
|
.css({
|
||||||
|
width: boxWidth + "px",
|
||||||
|
height: boxHeight + "px"
|
||||||
|
})
|
||||||
|
.mousedown(function(e) {
|
||||||
|
var left = parseInt($box.css("left")) + 2,
|
||||||
|
top = parseInt($box.css("top")) + 2,
|
||||||
|
x = e.clientX,
|
||||||
|
y = e.clientY;
|
||||||
|
$window.mousemove(function(e) {
|
||||||
|
left = Math.min(Math.max(left + e.clientX - x, 0), thumbnailWidth - boxWidth);
|
||||||
|
top = Math.min(Math.max(top + e.clientY - y, 0), thumbnailHeight - boxHeight);
|
||||||
|
x = e.clientX;
|
||||||
|
y = e.clientY;
|
||||||
|
$(".original").css({
|
||||||
|
left: -(left * photos[photo].width / thumbnailWidth) + "px",
|
||||||
|
top: -(top * photos[photo].height / thumbnailHeight) + "px"
|
||||||
|
});
|
||||||
|
that.update();
|
||||||
|
});
|
||||||
|
$window.mouseup(function() {
|
||||||
|
$window.unbind("mousemove");
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.appendTo($div);
|
||||||
|
that.show = function() {
|
||||||
|
$div.appendTo($album);
|
||||||
|
that.update();
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
that.update = function(animate) {
|
||||||
|
var left = -parseInt($(".original").css("left")) * thumbnailWidth / photos[photo].width - 2,
|
||||||
|
top = -parseInt($(".original").css("top")) * thumbnailHeight / photos[photo].height - 2;
|
||||||
|
if (animate) {
|
||||||
|
$box.animate({
|
||||||
|
left: left + "px",
|
||||||
|
top: top + "px"
|
||||||
|
}, 250);
|
||||||
|
} else {
|
||||||
|
$box.css({
|
||||||
|
left: left + "px",
|
||||||
|
top: top + "px"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Photo(i) {
|
||||||
|
var that = this,
|
||||||
|
image = photos[i],
|
||||||
|
id = image.file.substr(-8, 4),
|
||||||
|
title = image.file.substr(4, 8), // fixme: needed?
|
||||||
|
zoomedIn = false,
|
||||||
|
keepVisible = false,
|
||||||
|
$buttons = $("<div>")
|
||||||
|
.attr({
|
||||||
|
id: "buttons"
|
||||||
|
})
|
||||||
|
.mouseenter(function() {
|
||||||
|
//console.log("mouseenter")
|
||||||
|
clearTimeout(buttonTimeout);
|
||||||
|
keepVisible = true;
|
||||||
|
})
|
||||||
|
.mouseleave(function() {
|
||||||
|
buttonTimeout = setTimeout(hideButtons, 2500);
|
||||||
|
keepVisible = false;
|
||||||
|
})
|
||||||
|
.appendTo($body),
|
||||||
|
map;
|
||||||
|
$img = $("<img>")
|
||||||
|
.addClass("photo")
|
||||||
|
.attr({
|
||||||
|
src: image.file.replace("/IMG", "/90/IMG"),
|
||||||
|
});
|
||||||
|
$.each([
|
||||||
|
["Close", "CLOSE [ESCAPE]"],
|
||||||
|
["Previous", "PREVIOUS [LEFT]"],
|
||||||
|
["Play", "PLAY/PAUSE [SPACE]"],
|
||||||
|
["Next", "NEXT [RIGHT]"],
|
||||||
|
["Zoom In", "ZOOM [=/-]"]
|
||||||
|
], function(i, button) {
|
||||||
|
new Button(that, button[0], button[1]).show();
|
||||||
|
});
|
||||||
|
function getOriginalCSS(i) {
|
||||||
|
return {
|
||||||
|
width: photos[i].width + "px",
|
||||||
|
height: photos[i].height + "px"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getPhotoCSS(i) {
|
||||||
|
var size = getSize(i);
|
||||||
|
return {
|
||||||
|
left: ((windowWidth - size.width) / 2) + "px",
|
||||||
|
top: ((windowHeight - size.height) / 2) + "px",
|
||||||
|
width: size.width + "px",
|
||||||
|
height: size.height + "px"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getSize(i) {
|
||||||
|
var photoRatio = photos[i].width / photos[i].height;
|
||||||
|
return {
|
||||||
|
width: windowRatio > photoRatio ? windowHeight * photoRatio : windowWidth,
|
||||||
|
height: windowRatio > photoRatio ? windowHeight : windowWidth / photoRatio
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function hideButtons() {
|
||||||
|
return;
|
||||||
|
//console.log("hideButtons")
|
||||||
|
$("#buttons").animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 250);
|
||||||
|
}
|
||||||
|
function showButtons() {
|
||||||
|
//console.log("showButtons")
|
||||||
|
clearTimeout(buttonTimeout);
|
||||||
|
$("#buttons").animate({
|
||||||
|
opacity: 1
|
||||||
|
}, 250);
|
||||||
|
buttonTimeout = setTimeout(hideButtons, 2500);
|
||||||
|
}
|
||||||
|
that.click = function(button) {
|
||||||
|
//console.log("click " + button)
|
||||||
|
if (button == "Close") {
|
||||||
|
that.close();
|
||||||
|
} else if (button == "Previous") {
|
||||||
|
photo = photo == 0 ? photos.length - 1 : photo - 1;
|
||||||
|
that.show(photo);
|
||||||
|
playInterval && updateInterval();
|
||||||
|
} else if (button == "Play") {
|
||||||
|
if (!playInterval) {
|
||||||
|
$("#play").attr({
|
||||||
|
src: "png/symbolPause.png"
|
||||||
|
});
|
||||||
|
playInterval = setInterval(function() {
|
||||||
|
$("#next").trigger("click");
|
||||||
|
}, 5000);
|
||||||
|
setTimeout(function() {
|
||||||
|
$("#next").trigger("click");
|
||||||
|
}, 500);
|
||||||
|
} else {
|
||||||
|
$("#play").attr({
|
||||||
|
src: "png/symbolPlay.png"
|
||||||
|
});
|
||||||
|
clearInterval(playInterval);
|
||||||
|
playInterval = 0;
|
||||||
|
}
|
||||||
|
} else if (button == "Next") {
|
||||||
|
photo = photo == photos.length - 1 ? 0 : photo + 1;
|
||||||
|
that.show(photo);
|
||||||
|
playInterval && updateInterval();
|
||||||
|
} else if (button == "Zoom In") {
|
||||||
|
var left = (photos[photo].width - windowWidth) / -2,
|
||||||
|
top = (photos[photo].height - windowHeight) / -2,
|
||||||
|
x, y;
|
||||||
|
if (!zoomedIn) {
|
||||||
|
zoomedIn = true;
|
||||||
|
spinner = new Spinner().start();
|
||||||
|
var $img_ = $("<img>")
|
||||||
|
.attr({
|
||||||
|
src: photos[photo].file
|
||||||
|
})
|
||||||
|
.load(function() {
|
||||||
|
$img.attr({
|
||||||
|
src: photos[photo].file
|
||||||
|
});
|
||||||
|
spinner.stop();
|
||||||
|
});
|
||||||
|
$img
|
||||||
|
.animate({
|
||||||
|
width: photos[photo].width,
|
||||||
|
height: photos[photo].height,
|
||||||
|
left: left,
|
||||||
|
top: top
|
||||||
|
}, 250, function() {
|
||||||
|
$("#zoomin").attr({
|
||||||
|
src: "png/symbolZoomOut.png"
|
||||||
|
});
|
||||||
|
$img.addClass("original");
|
||||||
|
$interface
|
||||||
|
.show()
|
||||||
|
.mousedown(function(e) {
|
||||||
|
left = parseInt($img.css("left"));
|
||||||
|
top = parseInt($img.css("top"));
|
||||||
|
x = e.clientX;
|
||||||
|
y = e.clientY;
|
||||||
|
$window.mousemove(function(e) {
|
||||||
|
left = Math.max(Math.min(left + e.clientX - x, 0), windowWidth - photos[photo].width);
|
||||||
|
top = Math.max(Math.min(top + e.clientY - y, 0), windowHeight - photos[photo].height);
|
||||||
|
x = e.clientX;
|
||||||
|
y = e.clientY;
|
||||||
|
$img.css({
|
||||||
|
left: left + "px",
|
||||||
|
top: top + "px"
|
||||||
|
});
|
||||||
|
map.update();
|
||||||
|
});
|
||||||
|
$window.mouseup(function() {
|
||||||
|
$window.unbind("mousemove");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
map = new Map().show();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
zoomedIn = false;
|
||||||
|
$(".map").remove();
|
||||||
|
$interface.hide();
|
||||||
|
spinner = new Spinner().start();
|
||||||
|
var $img_ = $("<img>")
|
||||||
|
.attr({
|
||||||
|
src: photos[photo].file.replace("/IMG", "/720/IMG")
|
||||||
|
})
|
||||||
|
.load(function() {
|
||||||
|
$img.attr({
|
||||||
|
src: photos[photo].file.replace("/IMG", "/720/IMG")
|
||||||
|
});
|
||||||
|
spinner.stop();
|
||||||
|
});
|
||||||
|
$img.animate(getPhotoCSS(photo), 250, function() {
|
||||||
|
$("#zoomin").attr({
|
||||||
|
src: "png/symbolZoomIn.png"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function updateInterval() {
|
||||||
|
clearInterval(playInterval);
|
||||||
|
playInterval = setInterval(function() {
|
||||||
|
$("#next").trigger("click");
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
that.close = function() {
|
||||||
|
var thumbnailPosition = thumbnails[photo].position();
|
||||||
|
if (playInterval) {
|
||||||
|
$("#play").trigger("click");
|
||||||
|
}
|
||||||
|
$("#buttons").remove();
|
||||||
|
$(".map").remove();
|
||||||
|
$img.animate({
|
||||||
|
left: thumbnailPosition.left,
|
||||||
|
top: thumbnailPosition.top,
|
||||||
|
width: thumbnailPosition.width,
|
||||||
|
height: thumbnailPosition.height
|
||||||
|
}, 250, function() {
|
||||||
|
location.hash = [user, album].join("/");
|
||||||
|
$img.unbind("mouseenter");
|
||||||
|
$img.unbind("mouseleave");
|
||||||
|
$img.unbind("mousemove");
|
||||||
|
$img.remove();
|
||||||
|
});
|
||||||
|
$layer.animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 250, function() {
|
||||||
|
$layer.hide();
|
||||||
|
});
|
||||||
|
spinner.stop();
|
||||||
|
$interface.hide();
|
||||||
|
$document.unbind("keydown");
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
that.open = function() {
|
||||||
|
var thumbnailPosition = thumbnails[i].position();
|
||||||
|
$img.css({
|
||||||
|
left: thumbnailPosition.left,
|
||||||
|
top: thumbnailPosition.top,
|
||||||
|
width: thumbnailPosition.width,
|
||||||
|
height: thumbnailPosition.height
|
||||||
|
})
|
||||||
|
.appendTo($album)
|
||||||
|
.animate(getPhotoCSS(i), 250, function() {
|
||||||
|
location.hash = [user, album, id].join("/");
|
||||||
|
spinner = new Spinner().start();
|
||||||
|
var $img_ = $("<img>")
|
||||||
|
.attr({
|
||||||
|
src: photos[i].file.replace("/IMG", "/720/IMG")
|
||||||
|
})
|
||||||
|
.load(function() {
|
||||||
|
$img.attr({
|
||||||
|
src: photos[i].file.replace("/IMG", "/720/IMG")
|
||||||
|
});
|
||||||
|
spinner.stop();
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
$img.mouseenter(showButtons)
|
||||||
|
.mouseleave(hideButtons)
|
||||||
|
.mousemove(function() {
|
||||||
|
if (!keepVisible) {
|
||||||
|
showButtons();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
showButtons();
|
||||||
|
$document.keydown(function(e) {
|
||||||
|
//console.log(e.keyCode);
|
||||||
|
var d = 0;
|
||||||
|
if (photo > -1) {
|
||||||
|
if (e.keyCode == 27) {
|
||||||
|
$("#close").trigger("click");
|
||||||
|
} else if (e.keyCode == 32) {
|
||||||
|
showButtons();
|
||||||
|
$("#play").trigger("click");
|
||||||
|
} else if (e.keyCode == 37) {
|
||||||
|
showButtons();
|
||||||
|
$("#previous").trigger("click");
|
||||||
|
} else if (e.keyCode == 39) {
|
||||||
|
showButtons();
|
||||||
|
$("#next").trigger("click");
|
||||||
|
} else if (e.keyCode == 187) {
|
||||||
|
showButtons();
|
||||||
|
!zoomedIn && $("#zoomin").trigger("click");
|
||||||
|
} else if (e.keyCode == 189) {
|
||||||
|
showButtons();
|
||||||
|
zoomedIn && $("#zoomin").trigger("click");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$layer.show().animate({
|
||||||
|
opacity: 1
|
||||||
|
}, 250);
|
||||||
|
photo = i;
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
that.remove = function() {
|
||||||
|
$img.remove();
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
that.show = function(i) {
|
||||||
|
var $imgOld = $img,
|
||||||
|
offset = $img.offset(),
|
||||||
|
size = {
|
||||||
|
width: $img.width(),
|
||||||
|
height: $img.height()
|
||||||
|
};
|
||||||
|
$img = $("<img>")
|
||||||
|
.addClass(zoomedIn ? "original" : "photo")
|
||||||
|
.attr({
|
||||||
|
src: photos[i].file.replace("/IMG", "/90/IMG"),
|
||||||
|
})
|
||||||
|
.css(zoomedIn ? $.extend(getOriginalCSS(i), {
|
||||||
|
left: offset.left + "px",
|
||||||
|
top: offset.top + "px"
|
||||||
|
}) : getPhotoCSS(i))
|
||||||
|
.css({
|
||||||
|
opacity: 0
|
||||||
|
})
|
||||||
|
.appendTo($album)
|
||||||
|
.animate({
|
||||||
|
opacity: 1
|
||||||
|
}, playInterval ? 500 : 250, function() {
|
||||||
|
location.hash = [user, album, photos[i].file.substr(-8, 4)].join("/");
|
||||||
|
$imgOld.remove();
|
||||||
|
photo = i;
|
||||||
|
if (zoomedIn) {
|
||||||
|
if (photos[i].width / size.width == size.width && photos[i].height == size.height) {
|
||||||
|
$("img.map")
|
||||||
|
.attr({
|
||||||
|
src: photos[photo].file.replace("/IMG", "/90/IMG"),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$img.css({
|
||||||
|
left: offset.left * (photos[i].width - windowWidth) / (size.width - windowWidth),
|
||||||
|
top: offset.top * (photos[i].height - windowHeight) / (size.height - windowHeight)
|
||||||
|
});
|
||||||
|
$("div.map").remove();
|
||||||
|
map = new Map().show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
spinner = new Spinner().start();
|
||||||
|
var $img_ = $("<img>")
|
||||||
|
.attr({
|
||||||
|
src: photos[photo].file.replace("/IMG", "/720/IMG")
|
||||||
|
})
|
||||||
|
.load(function() {
|
||||||
|
$img.attr({
|
||||||
|
src: photos[photo].file.replace("/IMG", "/720/IMG")
|
||||||
|
});
|
||||||
|
if (zoomedIn) {
|
||||||
|
$img_ = $("<img>")
|
||||||
|
.attr({
|
||||||
|
src: photos[photo].file
|
||||||
|
})
|
||||||
|
.load(function() {
|
||||||
|
$img.attr({
|
||||||
|
src: photos[photo].file
|
||||||
|
});
|
||||||
|
spinner.stop();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
spinner.stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Select(name, options, selected) {
|
||||||
|
var that = this,
|
||||||
|
$div = $("<div>")
|
||||||
|
.addClass("select");
|
||||||
|
$val = $("<div>")
|
||||||
|
.html(name + ": " + selected)
|
||||||
|
.appendTo($div);
|
||||||
|
$select = $("<select>")
|
||||||
|
.change(function() {
|
||||||
|
var val = $select.val()
|
||||||
|
$val.html(name + ": " + val);
|
||||||
|
new Album(user, val).show();
|
||||||
|
})
|
||||||
|
.appendTo($div);
|
||||||
|
$.each(options, function(i, option) {
|
||||||
|
var $option = $("<option>")
|
||||||
|
.html(option)
|
||||||
|
.appendTo($select);
|
||||||
|
option == selected && $option.attr({
|
||||||
|
selected: "selected"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
that.show = function() {
|
||||||
|
$("#left").append($div);
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Spinner() {
|
||||||
|
var that = this,
|
||||||
|
$div = $("<div>")
|
||||||
|
.addClass("spinner")
|
||||||
|
.css({
|
||||||
|
left: ((windowWidth - 16 - 24) / 2) + "px",
|
||||||
|
top: ((windowHeight - 24) / 2) + "px",
|
||||||
|
}),
|
||||||
|
$img = $("<img>")
|
||||||
|
.addClass("spinner")
|
||||||
|
.attr({
|
||||||
|
src: "png/symbolLoading.png"
|
||||||
|
})
|
||||||
|
.appendTo($div),
|
||||||
|
deg = 0,
|
||||||
|
interval;
|
||||||
|
function update() {
|
||||||
|
$img.css({
|
||||||
|
MozTransform: "rotate(" + deg + "deg)",
|
||||||
|
WebkitTransform: "rotate(" + deg + "deg)"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
that.start = function() {
|
||||||
|
var spinner_ = $(".spinner");
|
||||||
|
if (spinner_) {
|
||||||
|
spinner_.remove();
|
||||||
|
}
|
||||||
|
deg = 0;
|
||||||
|
$div.appendTo($album).animate({
|
||||||
|
opacity: 1
|
||||||
|
}, 250);
|
||||||
|
interval = setInterval(function() {
|
||||||
|
deg = (deg + 30) % 360;
|
||||||
|
update();
|
||||||
|
}, 83);
|
||||||
|
return that;
|
||||||
|
};
|
||||||
|
that.stop = function() {
|
||||||
|
$div.animate({
|
||||||
|
opacity: 0
|
||||||
|
}, 250, function() {
|
||||||
|
$div.remove();
|
||||||
|
clearTimeout(interval);
|
||||||
|
deg = 0;
|
||||||
|
});
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
function Thumbnail(i) {
|
||||||
|
var that = this,
|
||||||
|
image = photos[i],
|
||||||
|
width = image.width * 90 / image.height,
|
||||||
|
marginLeft = 16 + Math.floor((135 - width) / 2),
|
||||||
|
marginRight = 16 + Math.ceil((135 - width) / 2),
|
||||||
|
$img = $("<img>")
|
||||||
|
.addClass("thumbnail loading")
|
||||||
|
.attr({
|
||||||
|
id: image.file.substr(-8, 4),
|
||||||
|
src: image.file.replace("/IMG", "/90/IMG"),
|
||||||
|
})
|
||||||
|
.css({
|
||||||
|
width: width + "px",
|
||||||
|
marginLeft: marginLeft + "px",
|
||||||
|
marginRight: marginRight + "px"
|
||||||
|
})
|
||||||
|
.click(function() {
|
||||||
|
new Photo(i).open();
|
||||||
|
})
|
||||||
|
.load(function() {
|
||||||
|
$(this).removeClass("loading");
|
||||||
|
});
|
||||||
|
that.position = function() {
|
||||||
|
var offset = $img.offset();
|
||||||
|
return {
|
||||||
|
left: offset.left + 4,
|
||||||
|
top: offset.top + 4 - $body.scrollTop(),
|
||||||
|
width: $img.width(),
|
||||||
|
height: $img.height()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
that.show = function() {
|
||||||
|
$img.appendTo($album);
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
return that;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.getJSON("json/jpg.json", function(data) {
|
||||||
|
json = data;
|
||||||
|
$.each(data, function(username, albumnames) {
|
||||||
|
users.push(username);
|
||||||
|
albums[username] = [];
|
||||||
|
$.each(albumnames, function(albumname, photos) {
|
||||||
|
albums[username].push(albumname);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
new Select("User", users, user).show();
|
||||||
|
new Select("Album", albums[user], album).show();
|
||||||
|
new Input("About: Photos", function() {
|
||||||
|
new Dialog("About: Photos", "2005-2010 Robert Luxemburg<br/><br/>Creative Commons Attribution Non-Commercial Share Alike 3.0").open();
|
||||||
|
}).show();
|
||||||
|
new Input("About: Software", function() {
|
||||||
|
new Dialog("About: Software", "2010 Robert Luxemburg<br/><br/>GNU General Public License 3.0<br/><br/><a href=\"zip/jpg.zip\">Download</a> (0.1.0, 2010-05-05, 150 KB)").open();
|
||||||
|
}).show();
|
||||||
|
new Album(user, album).show();
|
||||||
|
photoid && setTimeout(function() {
|
||||||
|
$("#" + photoid).trigger("click")
|
||||||
|
}, 500);
|
||||||
|
//$body.append("<br clear=\"all\"/>");
|
||||||
|
//$body.append("5DM2 - GPL V3 - <a href=\"5DM2.zip\">Download</a>");
|
||||||
|
});
|
||||||
|
});
|
6240
js/jquery.js
vendored
Normal file
BIN
png/symbolClose.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
png/symbolLoading.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
png/symbolNext.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
png/symbolPause.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
png/symbolPlay.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
png/symbolPrevious.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
png/symbolZoomIn.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
png/symbolZoomOut.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
48
py/jpg.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
from __future__ import division
|
||||||
|
import os
|
||||||
|
import Image
|
||||||
|
import simplejson
|
||||||
|
|
||||||
|
sourcePath = "../jpg/"
|
||||||
|
json = {}
|
||||||
|
|
||||||
|
for dirname, dirs, files in os.walk(sourcePath):
|
||||||
|
for filename in files:
|
||||||
|
if len(filename) == 12 and filename[-4:] == ".JPG" and not "90" in dirname and not "720" in dirname:
|
||||||
|
split = dirname.split("/")
|
||||||
|
username = split[-2]
|
||||||
|
albumname = split[-1]
|
||||||
|
if not username in json:
|
||||||
|
json[username] = {}
|
||||||
|
if not albumname in json[username]:
|
||||||
|
json[username][albumname] = []
|
||||||
|
sourceFile = dirname + "/" + filename
|
||||||
|
sourceImage = Image.open(sourceFile)
|
||||||
|
sourceWidth = sourceImage.size[0]
|
||||||
|
sourceHeight = sourceImage.size[1]
|
||||||
|
print "reading " + sourceFile + " (" + str(sourceWidth) + "x" + str(sourceHeight) + ")"
|
||||||
|
for targetSize in [90, 720]:
|
||||||
|
targetPath = dirname + "/" + str(targetSize) + "/"
|
||||||
|
if not os.path.exists(targetPath):
|
||||||
|
os.makedirs(targetPath)
|
||||||
|
targetFile = targetPath + filename
|
||||||
|
if not os.path.exists(targetFile):
|
||||||
|
if sourceWidth > sourceHeight:
|
||||||
|
targetWidth = int(targetSize * sourceWidth / sourceHeight)
|
||||||
|
targetHeight = targetSize
|
||||||
|
else:
|
||||||
|
targetWidth = targetSize
|
||||||
|
targetHeight = int(targetSize * sourceHeight / sourceWidth)
|
||||||
|
print "writing " + targetFile + " (" + str(targetWidth) + "x" + str(targetHeight) + ")"
|
||||||
|
targetImage = Image.new("RGB", (targetWidth, targetHeight))
|
||||||
|
targetImage.paste(sourceImage.resize((targetWidth, targetHeight), Image.ANTIALIAS), (0, 0, targetWidth, targetHeight))
|
||||||
|
targetImage.save(targetFile)
|
||||||
|
json[username][albumname].append({
|
||||||
|
"file": sourceFile[3:],
|
||||||
|
"width": sourceWidth,
|
||||||
|
"height": sourceHeight
|
||||||
|
})
|
||||||
|
|
||||||
|
f = open("../json/jpg.json", "w")
|
||||||
|
f.write(simplejson.dumps(json, sort_keys=True, indent=4))
|
||||||
|
f.close()
|
17
readme.txt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
0x2620.org/jpg 0.1.0 2010-05-05
|
||||||
|
a lightweight photo sharing web app
|
||||||
|
|
||||||
|
2010 robert luxemburg
|
||||||
|
published under the GPL v3
|
||||||
|
|
||||||
|
put your photos in jpg/username/albumname
|
||||||
|
and run jpg.py to create smaller versions
|
||||||
|
|
||||||
|
then put the whole thing on a web server
|
||||||
|
or just open index.html in your browser
|
||||||
|
|
||||||
|
works with firefox, safari and chrome
|
||||||
|
does not work with internet explorer
|
||||||
|
|
||||||
|
this software will evolve eventually, but for now it's just
|
||||||
|
intended to allow a few friends to drop picasa and/or flickr
|