]> git.parisson.com Git - telemeta.git/commitdiff
using svg + raphael library
authorriccardo <riccardo@parisson.com>
Tue, 24 May 2011 14:42:42 +0000 (16:42 +0200)
committerriccardo <riccardo@parisson.com>
Tue, 24 May 2011 14:42:42 +0000 (16:42 +0200)
telemeta/htdocs/timeside/js/playerLoader.js
telemeta/htdocs/timeside/js/ruler.js
telemeta/htdocs/timeside/js/rulermarker.js
telemeta/htdocs/timeside/js/timeside.js
telemeta/templates/telemeta_default/mediaitem_detail.html

index 1de86e3c82a6c8e08c1072ade7c36c23e5e4277c..89a21a9e42443a9f937a51844318e16b5e4e0c78 100644 (file)
@@ -56,6 +56,57 @@ function togglePlayerMaximization() {
     }
 }
 
+//function loadPlayer_(htmlContainer, w, h, durationInMsec, soundUrl, callback){
+//    var $ = jQuery;
+//    if(w<=0){
+//        w = 360;
+//    }
+//    if(h<=0){
+//        h= 130;
+//    }
+//    if(!callback || (typeof callback !== 'function')){
+//        callback = function(){};
+//    }
+//    if(!(htmlContainer instanceof $)){
+//        htmlContainer = $(htmlContainer);
+//    }
+//    if(htmlContainer.length!=1){
+//        throw 'invalid htmlContainer';
+//    }
+//    var errMsg = '';
+//    if(typeof durationInMsecOrAnalyzerUrl == 'number'){
+//        load_player(soundUrl, durationInMsecOrAnalyzerUrl, itemId, visualizers, currentUserName);
+//    }else{
+//
+//        $.ajax({
+//            url: durationInMsecOrAnalyzerUrl, //'analyze/xml',
+//            dataType: 'xml',
+//            success: function(data){
+//                //populatetable
+//                $J.each($J(data).find('data'),function(index,element){
+//                    var elm = $J(element);
+//                    tableBody.append('<tr><td>'+elm.attr('name')+'</td><td>'+elm.attr('value')+'</td><td>'
+//                        +elm.attr('unit')+'</td></tr>');
+//                });
+//                //loaded analizer, loading player
+//                if(msgElm){
+//                    msgElm.html('Loading player...');
+//                }
+//                var duration = $J(data).find('#duration').attr('value');
+//                duration = duration.split(":");
+//                //format duration
+//                var pin = parseInt;
+//                var pfl = parseFloat;
+//                var timeInMSecs=pin(duration[0])*3600+pin(duration[1])*60+pfl(duration[2]);
+//                timeInMSecs = Math.round(timeInMSecs*1000);
+//                load_player(soundUrl, timeInMSecs, itemId, visualizers, currentUserName);
+//            },
+//            error:function(){
+//                errMsg = 'Error loading analyzer';
+//            }
+//        });
+//    }
+//}
 
 
 function loadPlayer(analizerUrl, soundUrl, itemId, visualizers, currentUserName, isStaffOrSuperuser){
index d686ac2f1cbaadb3164f7485657be5dc0a418672..d7173f8556d0909963e2ae141a3ed103746d1488 100644 (file)
 
 /**
  * Class representing the ruler (upper part) of the player. Requires jQuery
- * wz_jsgraphics.
+ * and Raphael
  */
 var Ruler = TimesideArray.extend({
+
     //init constructor: soundDuration is IN SECONDS!!! (float)
     init: function(viewer, soundDuration){
         this._super();
@@ -42,19 +43,14 @@ var Ruler = TimesideArray.extend({
         this.getWaveContainer =function(){
             return waveContainer;
         };
-        //ts-image-canvas has width=0. Why was not the case in old code?
-        //BECAUSE IN OLD CODE ts-image-canvas has style="width..height" defined, and not HERE!!!!
+        //TODO: we dont need containerWiever here!!!
+        //better: it is usefult only for the canvas defined below. However...
         this.getContainerWidth =function(){
             return waveContainer.width();
         };
-        
-        
         this.debug( 'init ruler: container width '+this.getContainerWidth());
         
-        
         //private function used in resize() defined below
-        
-
         var container = viewer.find('.' + cssPref + 'ruler');
         
         this.getRulerContainer = function(){
@@ -63,174 +59,44 @@ var Ruler = TimesideArray.extend({
     },
 
     resize : function(){
-        //code copied from old implementation, still to get completely what is going on here...
-        var sectionSteps = [[5, 1], [10, 1], [20, 2], [30, 5], [60, 10], [120, 20], [300, 30],
-        [600, 60], [1800, 300], [3600, 600]];
-        //old computeLayout code
-        var fullSectionDuration,sectionSubDivision, sectionsNum;
-        var width = this.getContainerWidth();
-        var duration = this.getSoundDuration();
-        var cssPref = this.cssPrefix;//defined in superclass
-        var fontSize = 10;
-        var mfloor = Math.floor; //instanciating once increases performances
-        var $J = this.$J; //reference to jQuery
-        //this.debug('container width: ' +" "+width);
-
-
-        var i, ii = sectionSteps.length;
-        var timeLabelWidth = this.textWidth('00:00', fontSize);
-        for (i = 0; i < ii; i++) {
-            var tempDuration = sectionSteps[i][0];
-            var subDivision = sectionSteps[i][1];
-            var labelsNum = mfloor(duration / tempDuration);
-            if ((i == ii - 1) || (width / labelsNum > timeLabelWidth * 2)) {
-                fullSectionDuration = tempDuration;
-                sectionSubDivision = subDivision;
-                sectionsNum = mfloor(duration / fullSectionDuration);
-                //this.debug('(in _computeLayout) this.fullSectionDuration: ' + fullSectionDuration);
-                //this.debug('(in _computeLayout) sectionsNum: ' +sectionsNum);
-                //this.debug('(in _computeLayout) sectionSubDivision: ' +sectionSubDivision);
-                break;
-            }
-        }
-        //old draw() code:
+        var duration = this.getSoundDuration(); //in seconds
         if (!duration) {
             this.debug("Can't draw ruler with a duration of 0");
             return;
         }
-        //this.debug("draw ruler, duration: " + duration);
-
-        var container = this.getRulerContainer();
-        var layout = container.find("."+cssPref + 'layout');
-        //REDONE: if does not exists, create it
-        if(!layout || !(layout.length)){
-            layout = $J('<div/>')
-            .addClass(cssPref + 'layout')
-            .css({
-                position: 'relative'
-            }) // bugs on IE when resizing
-            //TODO: bind doubleclick events!!!!!!
-            //.bind('dblclick', this.attachWithEvent(this._onDoubleClick))
-            //.bind('resize', this.attachWithEvent(this.resize)) // Can loop ?
-            .appendTo(container);
-        }else{
-            //remove all elements neither pointer (or children of it) nor marker (or children of it)
-            layout.find(':not(a.ts-pointer,a.ts-marker,a.ts-pointer>*,a.ts-marker>*)').remove();
-        }
-
-        //        if (layout && layout.length){
-        //            layout.remove();
-        //        }
-        //        layout = $J('<div/>')
-        //        .addClass(cssPref + 'layout')
-        //        .css({
-        //            position: 'relative'
-        //        }) // bugs on IE when resizing
-        //        //TODO: bind doubleclick events!!!!!!
-        //        //.bind('dblclick', this.attachWithEvent(this._onDoubleClick))
-        //        //.bind('resize', this.attachWithEvent(this.resize)) // Can loop ?
-        //        .appendTo(container);
 
         
+        //build a canvas with raphael:
+        //setting global attributes:
+        var backgroundcolor = '#333';
+        var lineAttr = {
+                        'stroke-width':1,
+                        'stroke':'#eeeeee'
+                    };
+        var rulerContainer = this.getRulerContainer();
+        rulerContainer.css({'backgroundColor':backgroundcolor});
 
-        //creating sections
-        //defining function maketimelabel
-        var makeTimeLabel = this.makeTimeLabel;
-            
-        //defining the function createSection
-        var _createSection = function(timeOffset, pixelWidth,timeLabelWidth) {
-            var section = $J('<div/>')
-            .addClass(cssPref + 'section')
-            .css({
-                fontSize: fontSize + 'px',
-                fontFamily: 'monospace',
-                width: pixelWidth,
-                overflow: 'hidden'
-            })
-            .append($J('<div />').addClass(cssPref + 'canvas'));
-
-            var topDiv = $J('<div/>')
-            .addClass(cssPref + 'label')
-            .appendTo(section);
-            var bottomDiv = $J('<div/>')
-            .addClass(cssPref + 'lines')
-                
-            .appendTo(section);
-            var empty = $J('<span/>').css({
-                visibility: 'hidden'
-            }).text('&nbsp;');
-            var text;
-
-            if (pixelWidth > timeLabelWidth) {
-                text = $J('<span/>')
-                .text(makeTimeLabel(timeOffset))
-                .bind('mousedown selectstart', function() { //WHY THIS?
-                    return false;
-                });
-            } else {
-                text = empty.clone();
-            }
-            topDiv.append(text);
-            bottomDiv.append(empty);
-            return section;
-        };
-        //function defined, creating sections:
-        var sections = new Array();
-        var currentWidth = 0;
-        var sectionDuration, sectionWidth;
-        for (i = 0; i <= sectionsNum; i++) {
-            if (i < sectionsNum) {
-                sectionDuration = fullSectionDuration;
-                sectionWidth = mfloor(sectionDuration / duration * width);
-            } else {
-                sectionDuration = duration - i * fullSectionDuration;
-                sectionWidth = width - currentWidth;
+        //remove all elements not pointer or marker
+        rulerContainer.find(':not(a.ts-pointer,a.ts-marker,a.ts-pointer>*,a.ts-marker>*)').remove();
 
-            }
-            var section = _createSection(i * fullSectionDuration, sectionWidth, timeLabelWidth);
-            if (i > 0) {
-                section.css({
-                    left: currentWidth,
-                    top: 0,
-                    position: 'absolute'
-                });
-            }
-            section.duration = sectionDuration;
-            layout.append(section);
-            currentWidth += section.width();
-            sections[i] = section;
-        }
+        //set font size (maybe this will be placed in a global or static variable)
+        var h = 28; //TODO: change it (global var?)
+        var obj = this.calculateRulerElements(rulerContainer.width(),h,duration);
+        consolelog(obj);
 
-        //function to draw section rulers:
-        var _drawSectionRuler= function(section, drawFirstMark) {
-            var j;
-               
-            var jg = new jsGraphics(section.find('.' + cssPref + 'canvas').get(0));
-            jg.setColor(layout.find('.' + cssPref + 'lines').css('color'));
-            var height = section.height();
-            var ypos;
-            for (j = 0; j < section.duration; j += sectionSubDivision) {
-                if (j == 0) {
-                    if (drawFirstMark) {
-                        ypos = 0;
-                    } else {
-                        continue;
-                    }
-                } else {
-                    ypos = (j == section.duration / 2) ? 1/2 + 1/8 : 3/4;
-                }
-                //var x = j / this.duration * this.width;
-                var x = j / duration * width;
-                jg.drawLine(x, height * ypos, x, height - 1);
+        var paper = Raphael(rulerContainer[0], rulerContainer.width(), h);
+        var path = paper.path(obj.path);
+        path.attr(lineAttr);
+
+        var labels = obj.labels;
+        if(labels){
+            var $J = this.$J;
+            for(var i=0; i <labels.length;i++){
+                var span = $J('<span/>').html(labels[i][0]).css({'color':'white', 'display':'block','position':'absolute','top':'0', 'left':labels[i][1]+'px'});
+                rulerContainer.append(span);
             }
-            jg.paint();
-        };
-        //draw section rulers
-        for (i = 0; i <= sectionsNum; i++) {
-            _drawSectionRuler(sections[i], (i > 0));
         }
 
-       
         var pointer = undefined;
         if('getPointer' in this){
             pointer = this.getPointer();
@@ -250,6 +116,70 @@ var Ruler = TimesideArray.extend({
 
     },
 
+    /**
+     * returns an object with the following properties:
+     * path: (string) the path of the ruler to be drawn
+     * labels (array) an array of arrays ['text',x,y]
+     */
+    calculateRulerElements: function(w,h){
+        var fontSize = 10;
+        var duration = this.getSoundDuration();
+        
+        //the fontSize is actually a measure og height, seo we can set:
+        var fontMargin = 2;
+
+
+        var timeLabelWidth = this.textWidth('00:00', fontSize);
+        var timeLabelDuration = timeLabelWidth*duration/w;
+
+        //determine the ticks:
+        var sectionDurations = [1,2,5,10,30,60,120,300,1800,3600,7200,18000,36000];
+        //sectionDurations in seconds. Note that 60=1 minute, 3600=1 hour (so the maximum sectionDuration is 36000=10hours)
+        var i=0;
+        var len = sectionDurations.length;
+        while(i<len && timeLabelDuration>sectionDurations[i]){
+            i++;
+        }
+        var sectionDuration = sectionDurations[i];
+        var sectionNums = parseInt(0.5+(duration/sectionDurations[i])); //ceil
+        var sectionWidth = w*sectionDuration/duration;
+
+        var tickCounts = [10,5,2,1];
+        i=0;
+        var tickCount = tickCounts[0];
+        while(i<tickCounts.length-1 && tickCounts[i]*2>sectionWidth){
+            i++;
+        }
+        var tickAtHalfSectionWidthHigher = i==0 || i==2; //draw tick at half section higher if ticks are even
+        tickCount = tickCounts[i];
+        var tickWidth = sectionWidth/tickCount;
+        var makeTimeLabel = this.makeTimeLabel;
+        var h_1 = h-1; //TODO: use line tickness instead of 1
+        var path = new Array(parseInt(0.5+(w/tickWidth)));
+        consolelog(path.length);
+        path[0] = ['M 0 '+h_1];
+        len = path.length;
+        for(i=0;  i < len; i+=tickCount){
+            for(var j=1; j<tickCount+1; j++){
+                var k = i+j;
+                var x = (k*tickWidth);
+                //consolelog(k+') = '+x+' ; '+i+' * '+sectionWidth+' + '+j+' * '+tickWidth);
+                //if(x<w){
+                    var y = (j==tickCount ? 0 : tickAtHalfSectionWidthHigher && j==(tickCount)/2 ? .5*h : .75*h);
+                    var baseline = ' L '+x+' '+h_1;
+                    path[k] = baseline;
+                    path[k] += ' L '+x+' '+y;
+                    path[k] += baseline;
+                //}
+            }
+        }
+        var labels = new Array(sectionNums);
+        for(i=0; i<sectionNums; i++){
+            labels[i] = [makeTimeLabel(sectionDuration*i),fontMargin+i*sectionWidth];
+        }
+        return {'path': path.join('')+' z', 'labels':labels};
+    },
+
     //overridden: Note that the pointer is NOT cleared!!!!!
     clear: function(){
         var markers = this._super();
@@ -302,7 +232,13 @@ var Ruler = TimesideArray.extend({
         var container = this.getRulerContainer();
         var layout = container.find("."+this.cssPrefix + 'layout');
         var $J = this.$J;
-        var pointer = new RulerMarker($J(layout.get(0)),this.getWaveContainer(),markerClass);
+//        var pointer = new RulerMarker($J(layout.get(0)),this.getWaveContainer(),markerClass);
+
+        
+        var pointer = new RulerMarker(this.getRulerContainer(),this.getWaveContainer(),markerClass);
+
+        
+
         //call super constructor
         //if it is a pointer, dont add it
         if(markerClass != 'pointer'){
@@ -358,7 +294,7 @@ var Ruler = TimesideArray.extend({
             evt.stopPropagation(); //dont notify the ruler or other elements;
             var newPos = startPos;
             doc.bind('mousemove.'+eventId, function(evt){
-                var x = evt.pageX; 
+                var x = evt.pageX;
                 newPos = startPos+(x-startX);
                 pointer.move(newPos);
                 //update the text if pointer
index 4ef2e512d9db81c47ab6f907a5c88f82c15a7034..a0097d5f89b026cf61d79bb723f7d36cfca3c87f 100644 (file)
 
 var RulerMarker = TimesideClass.extend({
 
-    init: function(rulerLayout, viewer, className) {
+    class2CanvasColor: {
+        'pointer':'#a10006',
+        'marker':'#e65911'
+    },
+
+    init: function(rulerDiv, waveImgDiv, className) {
         this._super();
         var $J = this.$J;
         var fontSize = 10;
         this.getFontSize = function(){
             return fontSize;
         }
+
         var zIndex = 1000;
         var tooltip = '';
-        //TODO: why viewer get(0) ? more than one? check and maybe simplify
-        var painter = new jsGraphics(viewer.get(0));
-        //from create (oldCode)
+
         var cssPref = this.cssPrefix;
-        var y = rulerLayout.find('.' + cssPref + 'label').outerHeight();
-        //added by me:================
-        if(className == "pointer"){
-            y = 0;
-        }
-        //==========================
+
         var label = $J('<a/>')
         .css({
             display: 'block',
-            width: '10px',
+            width: fontSize +'px',
             textAlign: 'center',
             position: 'absolute',
             fontSize: fontSize + 'px',
             fontFamily: 'monospace',
-            top: y + 'px'
+            top: 0
         })
         .attr('href', '#')
         .addClass(cssPref + className)
-        .append('<span />')
-        //.hide();
-
+        .html('<span>0</span>'); //the text inside the span is FUNDAMENTAL, although it will be replaced later,
+        //to calculate now the label position (see below *)
+       
+        
         if (tooltip){
             label.attr('title', tooltip);
         }
 
-        rulerLayout.append(label);
-        
-        var height = viewer.height();
-        var x = 0;
-        painter.drawLine(x, 0, x, height);
-        
-        x     = [-4, 4, 0];
-        y = [0, 0, 4];
-
-        painter.fillPolygon(x, y);
-        painter.paint();
-        var nodes = $J(painter.cnv).children();
+        if(rulerDiv.css('position')!='relative'){
+            rulerDiv.css({
+                'position':'relative'
+            });
+        }
+        rulerDiv.append(label);
 
+       
+        if(className != "pointer"){
+            label.css('top',rulerDiv.height()-label.outerHeight());
+        }
+        
         var style = {};
         if (zIndex) {
             style.zIndex = zIndex;
             label.css(style);
         }
-        style.backgroundColor = '';
-        //nodes.hide();
-        nodes.css(style).addClass(cssPref + className)
-        .each(function(i, node) {
-            node.originalPosition = parseInt($J(node).css('left'));
-        });
-
+        
         //set the index,
         var index = -1;
         this.setIndex = function(idx, optionalUpdateLabelWidth){
@@ -107,17 +100,51 @@ var RulerMarker = TimesideClass.extend({
         this.getLabel = function(){
             return label;
         }
-        
-        this.getViewer = function(){
-            return viewer;
+
+
+        this.getRulerWidth = function(){
+            return rulerDiv.width();
         }
-        this.getPainter = function(){
-            return painter;
+        this.getWaveHeight = function(){
+            return waveImgDiv.height();
         }
 
         this.positionInPixels = 0;
         this.positionAsViewerRatio = 0;
 
+        var tW = 2*((fontSize - 1) >>> 1)+1; //if fontsize:10 or 9, tW:9, if fontSize:8 or 7, tW:7, and so on
+        
+        var fillColor = this.class2CanvasColor[className];
+        var canvas = undefined;
+        if(this.isSvgSupported()){
+            canvas = this.createCanvasSvg(waveImgDiv, tW);
+            var path = canvas.childNodes[0]; //note that $J(canvas).find('path') does not work in FF at least 3.5
+            path.setAttributeNS(null,'fill',fillColor);
+            path.setAttributeNS(null,'stroke-width',0);
+            this.moveCanvas = function(pixelOffset){
+                //consolelog(pixelOffset);
+                canvas.setAttributeNS( null, "transform", "translate("+pixelOffset+",0)");
+            }
+            this.jQueryCanvas = $J(canvas);
+        }else{
+            canvas = this.createCanvasVml(waveImgDiv, tW);
+            this.jQueryCanvas = $J(canvas.node);
+            var attributes = {
+                'stroke-width':'0',
+                'fill':fillColor
+            };
+            canvas.attr(attributes); //Raphael method
+            this.moveCanvas = function(pixelOffset){
+                //for some reason, coordinates inside the VML object are stored by raphael with a zoom of 10:
+                this.jQueryCanvas.css('left',(10*pixelOffset)+'px');
+            }
+            //apparently, when resizing the markers loose their attributes. Therefore:
+            var r = this.refreshPosition; //reference to current refreshPosition
+            this.refreshPosition = function(){
+                r.apply(this);
+                canvas.attr(attributes);
+            }
+        }
     },
 
     //sets the text of the marker, if the text changes the marker width and optionalUpdateLabelPosition=true,
@@ -143,24 +170,22 @@ var RulerMarker = TimesideClass.extend({
 
 
     getNodes: function(){
-        return this.$J(this.getPainter().cnv).children();
+        return this.$J([]);
+    //return this.$J(this.getPainter().cnv).children();
     },
     //these methods are executed only if marker is movable (see Ruler.js)
 
     move : function(pixelOffset) {
-        var width =  this.getViewer().width();
+        var width =  this.getRulerWidth();
         if (this.positionInPixels != pixelOffset) {
             if (pixelOffset < 0) {
                 pixelOffset = 0;
             } else if (pixelOffset >= width) {
                 pixelOffset = width - 1;
             }
-            var nodes = this.getNodes();
-            var $J = this.$J;
-            var mRound = this.mRound;
-            nodes.each(function(i, node) {
-                $J(node).css('left', mRound(node.originalPosition + pixelOffset) + 'px');
-            });
+           //defined in the conmstructor (it depends on wehter the current browser supports SVG or not)
+            this.moveCanvas(pixelOffset);
+           
             this.positionInPixels = pixelOffset;
             this.refreshLabelPosition(width);
             //store relative position (see refreshPosition below)
@@ -171,7 +196,7 @@ var RulerMarker = TimesideClass.extend({
 
     refreshLabelPosition : function(optionalContainerWidth){
         if(!(optionalContainerWidth)){
-            optionalContainerWidth = this.getViewer().width();
+            optionalContainerWidth = this.getRulerWidth();
         }
         var label = this.getLabel();
         var width = optionalContainerWidth;
@@ -191,37 +216,96 @@ var RulerMarker = TimesideClass.extend({
 
     //function called on ruler.resize. Instead of recreating all markers, simply redraw them
     refreshPosition : function(){
-        var width =  this.getViewer().width();
+        var width =  this.getRulerWidth();
         //store relativePosition:
         var rp = this.positionAsViewerRatio;
         this.move(this.mRound(this.positionAsViewerRatio*width));
         //reset relative position, which does not have to change
         //but in move might have been rounded:
         this.positionAsViewerRatio = rp;
-        //last thing: resize the vertical line.
-        //Assumptions (having a look at the web page element with a debugger and the code above
-        //which uses jsgraphics):
-        //The line is the first item (see drawLine above)
-        //not only the height, but also the height of the clip property must be set
-        var h = this.getViewer().height();
-        var nodes = this.getNodes();
-        var $J = this.$J;
-        $J(nodes[0]).css({
-            'height':h+'px',
-            'clip': 'rect(0px 1px '+h+'px 0px)'
-        });
     },
 
+    
     remove : function() {
-        var $J = this.$J;
-        var painter = this.getPainter();
         var label = this.getLabel();
-        painter.clear();
-        $J(painter.cnv).remove();
         label.remove();
+        this.jQueryCanvas.remove(); //defined in the constructor
         return this;
     },
 
+
+    createCanvasSvg: function(container, arrowBaseWidth){
+        //<path fill="#0000ff" stroke="#000000" d="M0,0L9,0L4.5,5Z" style="stroke-width: 0px; left: 100px; position: absolute;" stroke-width="0" x="100px"></path>
+        var $J = this.$J;
+        var svgNS = "http://www.w3.org/2000/svg";
+        var d = document;
+        var svg = undefined;
+        if(container.children().length>0){
+            svg = container.children().get(0);
+        }else{
+            svg = d.createElementNS(svgNS, "svg:svg");
+            container.append($J(svg));
+        }
+            var group = d.createElementNS(svgNS, "svg:g");
+            group.setAttributeNS( null, "transform", "translate(0,0)");
+
+            var path = d.createElementNS(svgNS, "svg:path");
+            path.setAttributeNS( null, "d", this.createCanvasPath(0,arrowBaseWidth));
+            
+            group.appendChild(path);
+            svg.appendChild(group);
+       
+        return group;
+    //return $J('<path/>').attr('fill',fillColor).attr('style','fill:'+fillColor+';strokeWidth:0');
+    },
+
+    createCanvasVml: function(container, arrowBaseWidth){
+        //for creating a vml object, we make use of raphael to avoid a pain in the ... implementing a non standard Microsoft syntax
+        //(which, after a glance, it's even syntactically a mess)
+        //unfotunately (and this is a real lack not even planned to be fixed, see raphael forums),
+        //raphael does not allow to wrap existing object, so we have to register in this.elementToPaperMap (see timeside.js)
+        //which is a map where to each container is associated a raphael paper:
+        var paper = this.elementToPaperMap && this.elementToPaperMap[container.get(0)];
+        if(!paper){ 
+            var obj = this.elementToPaperMap;
+            if(!obj){
+                this.elementToPaperMap = {};
+                obj = this.elementToPaperMap;
+            }
+            paper = Raphael(container.get(0),container.width(),container.height());
+            obj[container.get(0)] = paper;
+            //paper canvas is a div with weird dimensions. You can check it by printing paper.canvas.outerHTML in IE.
+            //We set them to 100% so we dont have clipping regions when resizing (maximizing)
+            paper.canvas.style.width='100%';
+            paper.canvas.style.height='100%';
+            paper.canvas.width='100%';
+            paper.canvas.height='100%';
+        //apparently, there is also a clip style declaration. The following code trhows an error in IE7:
+        //paper.canvas.style.clip = 'auto';
+        //however, even leaving the clip style declaration as it is, it seems to work (the div spans the whole width)
+        }
+        
+        
+        var shape = paper.path(this.createCanvasPath(0, arrowBaseWidth));
+        return shape;
+    },
+
+    //w must be odd. Cause le central line must be centered. Example:
+    //
+    //      xxxxx
+    //       xxx
+    //        x
+    //        x
+    //        x
+    //
+    createCanvasPath: function(x,w){
+        var halfW = w >>> 1;
+        var h = this.$J(window).height();
+        return 'M '+(x-halfW)+' 0 L '+(x)+' '+(halfW)+' L '+x+' '+h+
+        ' L '+ (x+1)+' '+h+' L '+(x+1)+ ' '+(halfW)+' L '+(x+halfW+1)+' 0 z';
+    },
+
+    //used for faster lookup
     mRound: Math.round
 
 });
index 673a39d41e9eca232f252fa6688e7ef95df4720c..adfaf363200c37968d47a1601dd621c304955465 100644 (file)
 //Defining the base TimeClass class. Player, Ruler, MarkerMap are typical implementations (see js files)
 //Basically we store here static methods which must be accessible in several timside sub-classes
 var TimesideClass = Class.extend({
+    /**
+     * Returns whether SVG is supported. If it is the case, this property can simply return true.
+     * For a more clean code, one should remove this property, elementToPaperMap (see below),
+     * check where we call isSvgSupported (ruler.js and rulermarker.js) and eventually
+     * remove the vml methods in ruler.js and rulermarker.js 
+     */
+    isSvgSupported : function(){return Raphael.svg},
+    /**
+     * Raphael unfortunately does not allow to wrap existing elements, which is a big lack not even planned to be implemented in
+     * future releases (see raphael forum). Therefore, we store here a map which binds html elements -> Raphael paper object
+     * This property can be deleted if svg is supported
+     */
+    elementToPaperMap: {},
 
     /**
      * function to calculate the text width according to a text and a given fontsize
index f71357d14469e7080fdd7c1e48212cd13a4846fd..a5221aeb10798c142e20f23fde3a7c7c2913492e 100644 (file)
@@ -61,7 +61,7 @@
 
     setTimeout(function(){
         if(jQuery('#loading_span').length>0){
-            playerError('SoundManager error. Try to:\n - Reload the page\n - Empty the cache (see browser preferences) and reload the page\n - Restart the browser');
+            playerError('SoundManager is not responding. Try to:\n - Reload the page\n - Empty the cache (see browser preferences) and reload the page\n - Restart the browser');
         }
     },10000);
 
@@ -71,7 +71,7 @@
     visualizers["{{v.name}}"] = "{% url telemeta-item-visualize item.public_id,v.id,"WIDTH","HEIGHT" %}";
     {% endfor %}
     
-    var scripts = ["{% url telemeta-timeside "js/wz_jsgraphics.js" %}", "{% url telemeta-timeside "js/timeside.js" %}","{% url telemeta-timeside "js/playerLoader.js" %}"];
+    var scripts = ["{% url telemeta-timeside "js/raphael-min.js" %}","{% url telemeta-timeside "js/wz_jsgraphics.js" %}", "{% url telemeta-timeside "js/timeside.js" %}","{% url telemeta-timeside "js/playerLoader.js" %}"];
 
     jQuery(window).ready(function(){
         //if soundmanager is ready, the callback is executed immetiately