1

I am looking at this slider http://jsfiddle.net/sCanr/1/.

(function () {
    var $container = $('#container');
    var $slider = $('#slider');
    var sliderW2 = $slider.width()/2;
    var sliderH2 = $slider.height()/2;    
    var radius = 200;
    var deg = 0;    
    var elP = $('#container').offset();
    var elPos = { x: elP.left, y: elP.top};
    var X = 0, Y = 0;
    var mdown = false;
    $('#container')
    .mousedown(function (e) { mdown = true; })
    .mouseup(function (e) { mdown = false; })
    .mousemove(function (e) {
        if (mdown) {
           var mPos = {x: e.clientX-elPos.x, y: e.clientY-elPos.y};
           var atan = Math.atan2(mPos.x-radius, mPos.y-radius);
           deg = -atan/(Math.PI/180) + 180; // final (0-360 positive) degrees from mouse position 

           X = Math.round(radius* Math.sin(deg*Math.PI/180));    
           Y = Math.round(radius*  -Math.cos(deg*Math.PI/180));
           $slider.css({ left: X+radius-sliderW2, top: Y+radius-sliderH2 });              
           // AND FINALLY apply exact degrees to ball rotation
           $slider.css({ WebkitTransform: 'rotate(' + deg + 'deg)'});
           $slider.css({ '-moz-transform': 'rotate(' + deg + 'deg)'});
           //
           // PRINT DEGREES               
           $('#test').html('angle deg= '+deg); 
        }
    });

})();

What i want to do it turn this into a time line control for a html5 video. However, i am having some trouble with calculating the math behind this.

John williams
  • 654
  • 1
  • 8
  • 22
  • It would be useful if you could describe *how* this should become a time line control, and *what* kind of trouble you have with the math. So far I'd say take the degrees, divide by 360, multiply by length of video, and you have your time. – MvG Dec 11 '13 at 10:51
  • I believe a 'normal' rotary dial behaviour is needed, where rotating clockwise moves forward through the video, and anticlockwise moves backward. The problem facing the OP is that going past the 12 o'clock position resets the value to 0. Usually a rotary dial encodes a fixed advance per click, so doesn't depend on the length of the clip, as mapping the whole clip to 1 revolution would do. – Phil H Dec 13 '13 at 11:43
  • Just to note, this behaviour is only clunky with a mouse - with a touchpad or a touchscreen, this makes a very neat input. – Phil H Dec 13 '13 at 12:54

1 Answers1

0

Try this:

http://jsfiddle.net/phdphil/Zv4K7/#base

It works by keeping global variables for the current position and last angle (you should change this setup to construct a specific dial with its own state). Each movement then calculates the delta (modulo 360, which requires a proper modulus function) and assumes that movements of < 180 degrees are forward movements, and > 180 degrees (remember -1 modulo 360 is 359) are negative movements. This then updates the cumulative total position:

var current = 0;
var lastAngle = 0;

           // ... inside the handler
           var delta = 0;
           var dir = 0;
           var rawDelta = mod(deg-lastAngle,360.0);
           if(rawDelta < 180) {
              dir = 1;
              delta = rawDelta;
           } else {
              dir = -1;
              delta = rawDelta-360.0;
           }
           current += delta;
           lastAngle = deg;
           $('#test').html('angle deg= '+current);  // current instead of deg

Just for clarity, the dir variable holds the direction of this movement, which could be used to update a >> or << indicator onscreen.

The real modulus function, taken from this SO answer:

function mod(x,n) {
   return ((x%n)+n)%n;
}
Community
  • 1
  • 1
Phil H
  • 19,928
  • 7
  • 68
  • 105