diff --git a/api/video.js b/api/video.js
index 277d15a..a342690 100644
--- a/api/video.js
+++ b/api/video.js
@@ -4,6 +4,7 @@ var
that,
oldSource,
opacity,
+ rotation,
isStopped = true,
isLoaded = false,
video = dom.jqPlayerVideo[ 0 ],
@@ -154,6 +155,25 @@ api.video = that = {
jqVideo.trigger( "opacitychange" );
return that;
},
+
+ // Rotation (degrees)
+ rotation: function( deg ) {
+ if ( arguments.length === 0 ) {
+ return rotation;
+ }
+ rotation = utils.range( 0, deg, 360, rotation );
+ jqVideo.trigger( "rotationchange" );
+ return that;
+ },
+
+ // Getter: width/height
+ width: function() {
+ return video.videoWidth;
+ },
+ height: function() {
+ return video.videoHeight;
+ },
+
opacityToggle: function( b ) {
if ( typeof b !== "boolean" ) {
b = opacity < 1;
diff --git a/dom.js b/dom.js
index f3000d5..b683892 100644
--- a/dom.js
+++ b/dom.js
@@ -44,6 +44,10 @@ window.dom = {
jqPlayerOpacityIcon: $( "#ctrl .opacity > .fa" ),
jqPlayerOpacitySlider: $( "#ctrl .opacity .cuteslider" ),
jqPlayerOpacityValue: $( "#ctrl .opacity .val" ),
+ // Rotation
+ jqPlayerRotationIcon: $( "#ctrl .rotation .fa" ),
+ jqPlayerRotationSlider: $( "#ctrl .rotation .cuteslider" ),
+ jqPlayerRotationValue: $( "#ctrl .rotation .val" ),
// CurrentTime
jqPlayerSliderCurrentTime: $( "#ctrl .cuteslider.position" ),
// Thumbnail
diff --git a/index.html b/index.html
index f4527b8..d3bee25 100644
--- a/index.html
+++ b/index.html
@@ -102,6 +102,26 @@
+
diff --git a/init.js b/init.js
index c439df9..f6fdb94 100644
--- a/init.js
+++ b/init.js
@@ -5,6 +5,7 @@ playerUI.textsShowing = false;
api.video
.resizeUpdate()
.opacity( 1 )
+ .rotation( 0 )
// Force the volumechange event
.volume( 0 )
.volume( 1 )
diff --git a/player/css/controls.css b/player/css/controls.css
index e6d1a2e..500f21e 100644
--- a/player/css/controls.css
+++ b/player/css/controls.css
@@ -115,7 +115,8 @@
right: -62px;
}
-#ctrl .opacity .menu .cuteslider {
+#ctrl .opacity .menu .cuteslider,
+#ctrl .rotation .menu .cuteslider {
width: 90px;
height: 14px;
margin: 0 .9em 0 .7em;
@@ -131,3 +132,8 @@
width: 28px;
height: 13px;
}
+
+#ctrl .rotation .menu {
+ min-width: 120px;
+ right: -52px;
+}
diff --git a/player/data-binding.js b/player/data-binding.js
index 2a9e4af..46da958 100644
--- a/player/data-binding.js
+++ b/player/data-binding.js
@@ -50,6 +50,10 @@ dom.jqPlayerVideo.on( {
opacitychange: function() {
lg( "ON: opacitychange" );
playerUI.opacity( api.video.opacity() );
+ },
+ rotationchange: function() {
+ lg( "ON: rotationchange" );
+ playerUI.rotation( api.video.rotation() );
}
});
diff --git a/player/events/rotation.js b/player/events/rotation.js
new file mode 100644
index 0000000..de17aed
--- /dev/null
+++ b/player/events/rotation.js
@@ -0,0 +1,7 @@
+(function(){
+
+dom.jqPlayerRotationSlider.change( function() {
+ api.video.rotation( this.value );
+});
+
+})();
diff --git a/player/player-ui.js b/player/player-ui.js
index 1661de8..64c8a05 100644
--- a/player/player-ui.js
+++ b/player/player-ui.js
@@ -21,6 +21,10 @@ var
// Button: fullscreen.
jqBtnFScr = dom.jqPlayerFullscreenBtn,
+ // Button, slider: rotation.
+ jqRotationIcon = dom.jqPlayerRotationIcon,
+ jqRotationSlider = dom.jqPlayerRotationSlider,
+
// Button, slider: opacity.
jqOpacityIcon = dom.jqPlayerOpacityIcon,
jqOpacitySlider = dom.jqPlayerOpacitySlider,
@@ -158,6 +162,11 @@ window.playerUI = that = {
speed: function( rate ) {
return that.actionDesc( "Speed : " + rate.toFixed( 2 ) + "x" );
},
+ rotation: function( rot ) {
+ dom.jqPlayerVideo.css( { transform: "rotate(" + rot + "deg)" } );
+ dom.jqPlayerRotationValue.text( rot + "°" );
+ return that;
+ },
opacity: function( op ) {
dom.jqPlayerScreen.css( "opacity", op );
jqOpacitySlider.element().val( op );
diff --git a/tools/utils.js b/tools/utils.js
index bd5c140..4458f42 100644
--- a/tools/utils.js
+++ b/tools/utils.js
@@ -18,6 +18,7 @@ window.utils = {
},
range: function( a, val, b, ori ) {
var valn = +val;
+
if ( arguments.length === 4 && val[ 1 ] === "=" ) {
valn =
( ori || 0 ) +