enhance collection and add slideshow with images and fragments.
--- a/src/egonomy/models.py Thu Jun 27 18:47:14 2013 +0200
+++ b/src/egonomy/models.py Thu Jun 27 18:58:35 2013 +0200
@@ -176,13 +176,15 @@
class Collection(models.Model):
- SLIDESHOW = 1
+ LIST = 1
MOSAIC = 2
- GEOGRAPHICAL = 3
+ SLIDESHOW = 3
+ GEOGRAPHICAL = 4
PUBLICATION_CHOICES = (
+ (LIST, 'list'),
+ (MOSAIC, 'mosaic'),
(SLIDESHOW, 'slideshow'),
- (MOSAIC, 'mosaic'),
(GEOGRAPHICAL, 'geographical')
)
@@ -193,7 +195,7 @@
creation = models.DateTimeField(auto_now_add=True)
modification = models.DateTimeField(auto_now=True)
public = models.BooleanField(null=False, default=True) # Collection is published or not, always published by default
- publication_type = models.IntegerField(choices=PUBLICATION_CHOICES, default=1) # slideshow, mosaic ou geographical
+ publication_type = models.IntegerField(choices=PUBLICATION_CHOICES, default=1) # list, mosaic, slideshow or geographical
--- a/src/egonomy/static/egonomy/css/slideshow.css Thu Jun 27 18:47:14 2013 +0200
+++ b/src/egonomy/static/egonomy/css/slideshow.css Thu Jun 27 18:58:35 2013 +0200
@@ -10,7 +10,7 @@
position: absolute; opacity: .3; -webkit-filter: blur(5px); filter: blur(5px);
}
-.main-image {
+.image-container {
position: absolute; top: 50px; right: 50px;
}
@@ -24,7 +24,7 @@
padding: 16px 0; margin: 0;
}
-.main-image, .caption {
+.caption {
box-shadow: 4px 4px 2px rgba(0,0,0,.5);
}
--- a/src/egonomy/static/egonomy/css/style.css Thu Jun 27 18:47:14 2013 +0200
+++ b/src/egonomy/static/egonomy/css/style.css Thu Jun 27 18:58:35 2013 +0200
@@ -234,11 +234,18 @@
.item-masonry{margin-bottom: 20px;}
.filters{padding: 10px 0; text-align: center;}
.filters li{ margin-bottom: 10px; position: relative; text-align: left; font-size: 12px; font-family: 'Lato'; display:inline-block; width: 200px; height: 28px; line-height: 28px; background-color: #fff;}
-.filters a.display-keyword{ overflow: hidden; color: #7F7F7F; display: block; height: 28px; overflow: hidden; margin: 0 16px 0 6px; }
+
+.filters a.display-keyword:first-child{ overflow: hidden; color: #7F7F7F; padding-left: 6px; display: block; }
+.filters a.display-keyword{padding-left: 6px;}
.filters li:hover{-webkit-box-shadow : none; -moz-box-shadow : none; box-shadow : none;}
-.filters a.icon-action{float: right; margin: 10px 6px 0 0;width: 10px; height: 10px; display: inline-block; background: url(../img/icon-cross-10.png) 0 0 no-repeat; }
-.filters .disabled .icon-action{width: 10px; height: 10px; -webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px; background: #7F7F7F;}
-.filters .disabled a.display-keyword{opacity: 0.5;}
+
+.filters .icon-action{position: absolute; top: 10px; right: 6px;width: 10px; height: 10px; display: inline-block;}
+
+.filters li.disabled .icon-action{width: 10px; height: 10px; -webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px; background-color: #7F7F7F;}
+.filters li.disabled a{opacity: 0.5;}
+
+
+.filters li .icon-action{background: url(../img/icon-cross-10.png) 0 0 no-repeat;}
.float-left{float: left;}
.filters-wrap{width: 225px; background-color: #EEE; margin-right: 17px;}
--- a/src/egonomy/static/egonomy/js/keyword-mosaic.js Thu Jun 27 18:47:14 2013 +0200
+++ b/src/egonomy/static/egonomy/js/keyword-mosaic.js Thu Jun 27 18:58:35 2013 +0200
@@ -106,5 +106,12 @@
}
updateMasonry();
});
-
+
+ //filters
+ $('.filters a').each(function(){
+ var text = $.trim($(this).text());
+ if(text.length > 26){
+ $(this).text(text.substr(0, 26) + '...')
+ }
+ });
});
--- a/src/egonomy/static/egonomy/js/main.js Thu Jun 27 18:47:14 2013 +0200
+++ b/src/egonomy/static/egonomy/js/main.js Thu Jun 27 18:58:35 2013 +0200
@@ -1,11 +1,5 @@
$(function(){
-//filters
- $('.filters a').each(function(){
- var text = $.trim($(this).text());
- if(text.length > 30){
- $(this).text(text.substr(0, 30) + '...')
- }
- });
+
//masonry
var masonry465 = $('.masonry-465');
masonry465.masonry({
@@ -53,6 +47,7 @@
});
}
+
// add item to collection behaviour
$('.additemtocollection').bind('click', function(e){
@@ -64,27 +59,27 @@
});
- //map
+
if($('#map').length){
initmap()
}
-function initmap() {
- // set up the map
- map = new L.Map('map');
+ function initmap() {
+ // set up the map
+ map = new L.Map('map');
- // create the tile layer with correct attribution
- var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
- var osm = new L.TileLayer(osmUrl, {minZoom: 3, maxZoom: 20});
+ // create the tile layer with correct attribution
+ var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
+ var osm = new L.TileLayer(osmUrl, {minZoom: 3, maxZoom: 20});
- // start the map in South-East England
- map.setView(new L.LatLng(48.833, 2.333),4);
- map.addLayer(osm);
+ // start the map in South-East England
+ map.setView(new L.LatLng(48.833, 2.333),4);
+ map.addLayer(osm);
- // markers
- var marker1 = L.marker([48.833, 2.333]).addTo(map);
- marker1.bindPopup("Beaux-Arts de Paris");
- var marker2 = L.marker([47.233,-1.583]).addTo(map);
- marker2.bindPopup("Beaux-Arts de Nantes");
-}
+ // markers
+ var marker1 = L.marker([48.833, 2.333]).addTo(map);
+ marker1.bindPopup("Beaux-Arts de Paris");
+ var marker2 = L.marker([47.233,-1.583]).addTo(map);
+ marker2.bindPopup("Beaux-Arts de Nantes");
+ }
});//ready
\ No newline at end of file
--- a/src/egonomy/static/egonomy/js/slideshow.js Thu Jun 27 18:47:14 2013 +0200
+++ b/src/egonomy/static/egonomy/js/slideshow.js Thu Jun 27 18:58:35 2013 +0200
@@ -1,7 +1,11 @@
$(function() {
var currentSlide = 0, jqwin = $(window), jqcaption = $(".caption"),
- margin = 50, jqmainimg = $(".main-image"), jqbackdrop = $(".backdrop"),
+ margin = 50,
+ jqimgcontainer = $(".image-container"),
+ jqmainimg = $(".main-image"),
+ jqbackdrop = $(".backdrop"),
+ jqpath = $(".clip-path"),
lastSlide = null;
function showSlide() {
@@ -10,34 +14,53 @@
if (slide !== lastSlide) {
jqcaption.find("h2").text(slide.title);
jqcaption.find("h3").text(slide.author);
- jqcaption.find("p").text(slide.description);
- jqmainimg.attr("src", slide.image.src);
+ var captiondiv = jqcaption.find(".caption-description");
+ captiondiv.empty();
+ slide.description.split(/\s*[\r\n]\s*/gm).forEach(function(p) {
+ captiondiv.append($("<p>").text(p));
+ });
+ jqmainimg.attr("xlink:href", slide.image.src);
jqbackdrop.attr("src", slide.image.src);
+ jqpath.attr("d", slide.path);
}
lastSlide = slide;
if (slide.image && slide.image.width) {
- var ww = jqwin.width(),
+ var pathcoords = slide.path.match(/[\d\.]+/g),
+ pathx = pathcoords.filter(function(p,i) {
+ return !(i%2);
+ }),
+ pathy = pathcoords.filter(function(p,i) {
+ return (i%2);
+ }),
+ minpx = Math.min.apply(Math,pathx),
+ maxpx = Math.max.apply(Math,pathx),
+ minpy = Math.min.apply(Math,pathy),
+ maxpy = Math.max.apply(Math,pathy),
+ ww = jqwin.width(),
wh = jqwin.height(),
cw = jqcaption.outerWidth(),
ch = jqcaption.outerHeight(),
wi = slide.image.width,
- hi = slide.image.height,
+ hi = slide.image.height,
+ wp = wi * (maxpx - minpx),
+ hp = hi * (maxpy - minpy),
w1 = ww - 2 * margin, w2 = w1 - cw
h1 = wh - 2 * margin, h2 = h1 - ch,
ra = Math.max(
- Math.min((h1 / hi), (w2 / wi)),
- Math.min((h2 / hi), (w1 / wi))
+ Math.min((h1 / hp), (w2 / wp)),
+ Math.min((h2 / hp), (w1 / wp))
),
- wa = wi * ra, ha = hi * ra,
+ wa = wp * ra, ha = hp * ra,
rb = Math.max(ww / wi, wh / hi),
wb = wi * rb, hb = hi * rb,
xb = (ww - wb) / 2, yb = (wh - hb) / 2;
- jqmainimg.css({
+ jqimgcontainer.css({
width: wa,
height: ha
});
+ jqimgcontainer[0].setAttribute("viewBox", [minpx,minpy,(maxpx-minpx),(maxpy-minpy)].join(" "));
jqbackdrop.css({
width: wb,
height: hb,
@@ -86,13 +109,16 @@
$(".right-arrow").click(nextSlide);
slides.forEach(function(slide, k) {
+ if (!slide.path) {
+ slide.path = "M0 0L1 0L1 1L0 1Z"
+ }
slide.image = new Image();
slide.image.onload = function() {
if (k === currentSlide) {
showSlide();
}
};
- slide.image.src = imgurlbase + slide.url;
+ slide.image.src = imgurlbase + slide.src;
});
showSlide();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/templates/egonomy_embed_slideshow.html Thu Jun 27 18:58:35 2013 +0200
@@ -0,0 +1,79 @@
+{% load static %}
+{% load i18n %}
+{% load egostringfilters %}
+<!DOCTYPE html>
+<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
+<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
+<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+ <meta name="description" content="eGonomy">
+ <title>eGonomy : Diaporama</title>
+ <link rel="stylesheet" href="{% static 'egonomy/css/reset.css' %}" />
+ <link rel="stylesheet" href="{% static 'egonomy/css/fonts.css' %}" />
+ <link rel="stylesheet" href="{% static 'egonomy/css/slideshow.css' %}" />
+</head>
+<body>
+ <div class="slideshow-wrap">
+ <img class="backdrop" />
+ <div class="caption-wrap">
+ <div class="caption">
+ <h2></h2>
+ <h3></h3>
+ <div class="caption-description"></div>
+ </div>
+ </div>
+ <svg class="image-container" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1 1" preserveAspectRatio="none">
+ <defs>
+ <clipPath id="fragment-clip">
+ <path d="" class="clip-path" />
+ </clipPath>
+ </defs>
+ <image class="main-image" xlink:href="" x="0" y="0" preserveAspectRatio="none" width="1" height="1" clip-path="url(#fragment-clip)" />
+ </svg>
+ <div class="arrow-wrap left-arrow">
+ <a class="arrow" href="#"></a>
+ </div>
+ <div class="arrow-wrap right-arrow">
+ <a class="arrow" href="#"></a>
+ </div>
+ </div><!-- /.wrap -->
+
+ <script type="text/javascript" src="{% static 'egonomy/lib/jquery.min.js' %}"></script>
+ <script type="text/javascript" src="{% static 'egonomy/js/slideshow.js' %}"></script>
+ <script>
+ {% autoescape off %}
+ var imgurlbase = "";
+ var slides = [
+ {% for item in items %}
+ {% ifequal item.content_type.model "fragment" %}
+ {% with fragment=item.content_object %}
+ {
+ "type": "fragment",
+ "title": "{{ fragment.title }}",
+ "author": "{{ fragment.author }}",
+ "src": "{{ fragment.image.info.image_file.url }}",
+ "path": "{{ fragment.coordinates }}",
+ "description": "{{ item.description|linebreaksantislashn }}"
+ }
+ {% endwith %}
+ {% else %}
+ {% with img=item.content_object %}
+ {
+ "type": "image",
+ "title": "{{ img.metadata.titre }}",
+ "author": "{{ img.metadata.titre }}",
+ "src": "{{ img.info.image_file.url }}",
+ "description": "{{ item.description|linebreaksantislashn }}"
+ }
+ {% endwith %}
+ {% endifequal %}
+ {% if not forloop.last %},{% endif %}
+ {% endfor %}
+ ];
+ {% endautoescape %}
+ </script>
+</body>
+</html>
\ No newline at end of file
--- a/src/egonomy/templates/egonomy_view_collection.html Thu Jun 27 18:47:14 2013 +0200
+++ b/src/egonomy/templates/egonomy_view_collection.html Thu Jun 27 18:58:35 2013 +0200
@@ -1,7 +1,6 @@
{% extends "egonomy_newbase.html" %}
{% load static %}
{% load i18n %}
-{% load thumbnail %}
{% block title %}{% trans "View a collection" %}{% endblock %}
@@ -83,10 +82,12 @@
<div class="title-page">
<h2>{{ col.title }} / <span>par {{ col.author }}</span></h2>
<ul class="sub-nav title-menu clearfix">
- <li><a href="{% url 'view_collection' collection_pk=col.pk %}?display=slideshow" {% ifequal display "slideshow" %}class="active"{% endifequal %}>argumentaire</a></li>
+ <li><a href="{% url 'view_collection' collection_pk=col.pk %}?display=list" {% ifequal display "list" %}class="active"{% endifequal %}>liste</a></li>
<li><span class="dot-6"></span></li>
<li><a href="{% url 'view_collection' collection_pk=col.pk %}?display=mosaic" {% ifequal display "mosaic" %}class="active"{% endifequal %}>mosaïque</a></li>
<li><span class="dot-6"></span></li>
+ <li><a href="{% url 'view_collection' collection_pk=col.pk %}?display=slideshow" {% ifequal display "slideshow" %}class="active"{% endifequal %}>diaporama</a></li>
+ <li><span class="dot-6"></span></li>
<li><a href="{% url 'view_collection' collection_pk=col.pk %}?display=geographical" {% ifequal display "geographical" %}class="active"{% endifequal %}>géographique</a></li>
<!--li><span class="dot-6"></span></li>
<li><a href="#">envoyer vers collage</a></li-->
@@ -106,7 +107,7 @@
</ul>
</div>
{% if items %}
- {% ifequal display "slideshow" %}
+ {% ifequal display "list" %}
<ul class="list-projets-3 clearfix masonry-465">
{% for item in items %}
{% include 'partial/item_in_collection_list.html' %}
@@ -116,17 +117,7 @@
{% ifequal display "mosaic" %}
<div class="clearfix">
<div class="filters-wrap float-left">
- <ul class="filters">
- {% comment %}
- {% for item in items %}
- {% for t in item.content_object.tag_list %}
- {% if t != "" %}
- <li class="box-shadow-2"><a class="display-keyword" data-keyword="{{ t }}" href="#">{{ t }} </a><a class="icon-action cross" href="#"></a></li>
- {% endif %}
- {% endfor %}
- {% endfor %}
- {% endcomment %}
- </ul>
+ <ul class="filters"></ul>
</div>
<ul class="list-projets-5 mosaic float-left clearfix masonry-177">
{% for item in items %}
@@ -136,6 +127,11 @@
</div>
{% endifequal %}
{% else %}
+ {% ifequal display "slideshow" %}
+ <div class="clearfix">
+ <iframe width="100%" height="700px" src="{% url 'embed_slideshow' collection_pk=col.pk %}" seamless="seamless"></iframe>
+ </div>
+ {% else %}
<div class="empty-block">
<form class="search-form-big" id="search-form-big" action="{% if search_fragment %}{% url 'all_fragments' %}{% else %}{% url 'all_pictures' %}{% endif %}" method="GET">
<p>
@@ -150,7 +146,8 @@
</p>
</form>
</div>
- {% endif %}
+ {% endifequal %}
+ {% endif %}
{% endblock %}
{% block js_page %}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/egonomy/templatetags/egostringfilters.py Thu Jun 27 18:58:35 2013 +0200
@@ -0,0 +1,20 @@
+from django.template import Library
+from django.template.defaultfilters import stringfilter
+from django.utils.html import escape
+from django.utils.safestring import mark_safe, SafeData
+from django.utils.text import normalize_newlines
+
+register = Library()
+
+
+@register.filter(is_safe=True, needs_autoescape=True)
+@stringfilter
+def linebreaksantislashn(value, autoescape=None):
+ """
+ Converts all newlines in a piece of plain text to '\n' string
+ """
+ autoescape = autoescape and not isinstance(value, SafeData)
+ value = normalize_newlines(value)
+ if autoescape:
+ value = escape(value)
+ return mark_safe(value.replace('\n', '\\n'))
--- a/src/egonomy/urls.py Thu Jun 27 18:47:14 2013 +0200
+++ b/src/egonomy/urls.py Thu Jun 27 18:58:35 2013 +0200
@@ -24,6 +24,7 @@
url(r'^newcollection/$', 'egonomy.views.new_collection', name='new_collection'),
url(r'^viewcollection/(?P<collection_pk>.*)/$', 'egonomy.views.view_collection', name='view_collection'),
url(r'^additem/$', 'egonomy.views.add_item_to_collection', name='add_item'),
+ url(r'^embedslideshow/(?P<collection_pk>.*)/$', 'egonomy.views.embed_slideshow', name='embed_slideshow'),
# Uncomment the admin/doc line below to enable admin documentation:
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
--- a/src/egonomy/views.py Thu Jun 27 18:47:14 2013 +0200
+++ b/src/egonomy/views.py Thu Jun 27 18:58:35 2013 +0200
@@ -440,16 +440,31 @@
def view_collection(request, collection_pk):
- display = request.GET.get("display") or "slideshow"
- if display!="slideshow" and display!="mosaic" and display!="geographical":
- display = "slideshow"
+ display = request.GET.get("display") or "list"
+ if display!="list" and display!="mosaic" and display!="slideshow" and display!="geographical":
+ display = "list"
+
+ col = get_object_or_404(Collection.objects.select_related('author'), pk=collection_pk)
+ items = None
+ if display!="slideshow":
+ # Avoid useless database query. The query will be done by embed_slideshow view
+ items = CollectionItem.objects.filter(collection=col).select_related('author', 'content_type', 'object_id', 'content_object').order_by("order")
+
+ return render_to_response("egonomy_view_collection.html",
+ {'col':col, 'items':items, 'display':display,
+ 'current_user_collection_list':current_user_collection_list(request)},
+ context_instance=RequestContext(request))
+
+
+
+
+def embed_slideshow(request, collection_pk):
col = get_object_or_404(Collection.objects.select_related('author'), pk=collection_pk)
items = CollectionItem.objects.filter(collection=col).select_related('author', 'content_type', 'object_id', 'content_object').order_by("order")
- return render_to_response("egonomy_view_collection.html",
- {'col':col, 'items':items, 'display':display,
- 'current_user_collection_list':current_user_collection_list(request)},
+ return render_to_response("egonomy_embed_slideshow.html",
+ {'col':col, 'items':items},
context_instance=RequestContext(request))