enhance collection and add slideshow with images and fragments.
authorcavaliet
Thu, 27 Jun 2013 18:58:35 +0200
changeset 191 d7b30914607d
parent 190 ebb8b58fc2b8
child 192 9ce87d383c85
enhance collection and add slideshow with images and fragments.
src/egonomy/models.py
src/egonomy/static/egonomy/css/slideshow.css
src/egonomy/static/egonomy/css/style.css
src/egonomy/static/egonomy/js/keyword-mosaic.js
src/egonomy/static/egonomy/js/main.js
src/egonomy/static/egonomy/js/slideshow.js
src/egonomy/templates/egonomy_embed_slideshow.html
src/egonomy/templates/egonomy_view_collection.html
src/egonomy/templatetags/egostringfilters.py
src/egonomy/urls.py
src/egonomy/views.py
--- 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))