Commit 70fc8f31 authored by Julien Bouquillon's avatar Julien Bouquillon Committed by Jean-Baptiste Kempf

Add the classic VLCobject and VLCcontrol libraries

Signed-off-by: Jean-Baptiste Kempf's avatarJean-Baptiste Kempf <jb@videolan.org>
parent 0d5c0526
var loaded_libs = new Array();
function ExternalLibLoader() {
this.libs = loaded_libs;
}
ExternalLibLoader.prototype.addLib = function(uri, callback) {
var idx = this.libs.length;
this.libs[idx] = new Array();
this.libs[idx].uri = uri;
this.libs[idx].callback = callback;
this.libs[idx].loaded = false;
}
CheckExternalLibs = function() {
for (var i=0; i<loaded_libs.length; i++) {
if (!loaded_libs[i].loaded) {
setTimeout("CheckExternalLibs", 250);
return;
}
}
// all libs loaded, execute all
for (var i=0; i<loaded_libs.length; i++) {
if (loaded_libs[i].callback) {
loaded_libs[i].callback();
}
}
}
ExternalLibLoader.prototype.LoadLibs = function() {
for (var i=0; i<this.libs.length; i++) {
this.LoadLib(this.libs[i]);
}
setTimeout("CheckExternalLibs", 250);
}
ExternalLibLoader.prototype.LoadLib = function(lib) {
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.callback = lib.callback;
script.loaded = false;
script.onreadystatechange= function () {
if (this.readyState == 'complete' || this.readyState == 'loaded') {
this.loaded = true;
this.callback(this);
}
};
script.onload=function() {
this.loaded = true;
this.callback(this);
};
script.src=lib.uri;
head.appendChild(script);
}
VLC plugin javascript wrapper
-----------------------------
VLCcontrols is a Jquery class that embeds and controls VLC in your webpage.
**NB: DEPRECATED, LAST UPDATE : OCT, 2010**
Detection and embedding is based on [swfobject][3]
recent VLC >= 1.0 new security restrictions disable lots of plugin functionnality (output). now need some serious rewrite so moved to github !
28/06/2010 : just dropped a new jQuery class that works better and with new VLC versions. see jquery.html
**Examples :**
- The example are on GitHub pages : [http://revolunet.github.com/VLCcontrols][4]
**API :**
// create a player in div '#vlc1'
var player = VLCobject.embedPlayer('vlc1', 400, 300, true);
player.play('http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi');
// set a [VLC option][2]
player.options.set("start-time", 50);
// reset all VLC options
player.options.clear();
// start playing uri
player.play(uri);
// stop playing
player.stop();
**INSTALLATION**
You can directly use our hosting and google jQuery CDN for js+images+css :
<script language="javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script language="javascript" src="http://revolunet.github.com/VLCcontrols/src/jquery-vlc.js"></script>
<link rel="stylesheet" type="text/css" href="http://revolunet.github.com/VLCcontrols/src/styles.css" />
[1]: http://www.revolunet.com/labo/code/VLCcontrols
[2]: http://wiki.videolan.org/VLC_command-line_help
[3]: http://blog.deconcept.com/swfobject/
[4]: http://revolunet.github.com/VLCcontrols
\ No newline at end of file
/*
<OWNER> = revolunet
<ORGANIZATION> = revolunet - Julien Bouquillon
<YEAR> = 2008
Copyright (c) 2008, revolunet
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met :
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE, DATA, OR PROFITS ; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var sliders = new Array();
function Slider(sliderID, width, height) {
this.position=0;
sliders[sliderID] = this;
var tgt = document.getElementById(sliderID);
this.tgt = tgt;
if(!tgt) return;
//alert((width - 2) + "px");
tgt.style.width = (width - 2) + "px";
tgt.style.height = height + "px";
tgt.style.backgroundColor = "silver";
tgt.style.border = "1px solid black";
tgt.style.cursor = "pointer";
tgt.style.textAlign="left";
tgt.style.zIndex="1";
//tgt.style.position = "absolute";
//tgt.style.left = "0px";
var thumb = document.createElement("div");
thumb.setAttribute("id", sliderID + "_thumb");
thumb.slider = this;
thumb.setAttribute("style", "float:left");
thumb.style.display = "inline";
thumb.style.width = "5px";
thumb.style.height = height + "px";
//alert( tgt.style.height );
//alert( thumb.style.height );
//thumb.style.zIndex="1000";
thumb.style.backgroundColor = "#666666";
thumb.style.borderLeft = "0px solid black";
thumb.style.borderRight = "0px solid black";
thumb.style.cursor = "pointer";
thumb.style.position = "relative";
thumb.dragging = false;
tgt.onmousedown = function() {eval("Slider_click('" + sliderID + "')");}
thumb.onmousedown = function() {eval("Slider_startDrag('" + sliderID + "')");}
thumb.onmousemove = function() {eval("Slider_Drag('" + sliderID + "')");}
tgt.onmousemove = function() {eval("Slider_Drag('" + sliderID + "')");}
//thumb.onmouseup = function() {eval("Slider_stopDrag('" + sliderID + "')");}
//thumb.onmouseout = function() {eval("Slider_stopDrag('" + sliderID + "')");}
//tgt.onmouseup = this.stopDrag;
//tgt.innerHTML+="";
tgt.appendChild(thumb);
// thumb.innerHTML+="-";
// alert(tgt.innerHTML);
this.thumb = document.getElementById(sliderID + "_thumb");
//this.thumb.style.top="50px";
//this.thumb.style.left="50px";
//alert(this.thumb.style.left);
//alert(this.thumb);
document.onmousemove = doSomething;
// alert(window.document.onmousemove);
}
Slider.prototype.setPosition = function(position) {
this.position = position;
Slider_setXFromPosition(this.tgt.id, position);
}
function getX( oElement )
{
var iReturnValue = 0;
while( oElement != null ) {
iReturnValue += oElement.offsetLeft;
//alert(oElement.offsetLeft);
oElement = oElement.offsetParent;
}
return iReturnValue;
}
function Slider_click(id, e) {
//var tgt = sliders[id]
//var lbase = getX(tgt.tgt);
//var relpos = parseInt(event.clientX - lbase - (parseInt((tgt.thumb.style.width.replace("px",""))) / 2));
//tgt.thumb.style.left = relpos + "px";
//alert(e);
Slider_setXfromevent(id);
Slider_gotnewposition(id);
}
function Slider_startDrag(id) {
var tgt = sliders[id];
// var lbase = getX(tgt.tgt);
// var offset = parseInt((tgt.thumb.style.width.replace("px","")));
//var relpos = parseInt(event.clientX - lbase - offset);
//tgt.thumb.style.left = relpos + "px";
document.onmouseup = function() {eval("Slider_stopDrag('" + id + "')");}
tgt.thumb.dragging = true;
}
function Slider_Drag(id) {
var tgt = sliders[id];
if (!tgt.thumb.dragging) return;
Slider_setXfromevent(id);
}
function Slider_setXfromevent(id) {
var event = window.event||window.Event;
var tgt = sliders[id];
var lbase = getX(tgt.tgt);
var thumb_width = parseInt(tgt.thumb.style.width.replace("px",""))
var offset = parseInt(thumb_width / 2);
var relpos = parseInt(posx - lbase - offset);
var bar_width = parseInt(tgt.tgt.style.width.replace("px",""));
if (relpos >= (bar_width - thumb_width)) relpos = bar_width - thumb_width;
if (relpos < 0) relpos=0;
Slider_setX(id, relpos);
}
function Slider_setXFromPosition(id, position) {
var tgt = sliders[id];
var lbase = getX(tgt.tgt);
var thumb_width = parseInt(tgt.thumb.style.width.replace("px",""))
var bar_width = parseInt(tgt.tgt.style.width.replace("px",""));
var offset = parseInt(thumb_width / 2);
var relpos = parseInt((position * bar_width) - offset );
if (relpos >= (bar_width - thumb_width)) relpos = bar_width - thumb_width;
if (relpos < 0) relpos=0;
Slider_setX(id, relpos);
}
function Slider_setX(id, x) {
var tgt = sliders[id];
tgt.thumb.style.left = x + "px";
}
function Slider_stopDrag(id) {
//alert(event.clientX);
// alert(this.thumb);
//this.thumb.style.left = event.clientX;
Slider_setXfromevent(id);
var tgt = sliders[id];
tgt.thumb.dragging = false;
document.onmouseup = null;
Slider_gotnewposition(id);
}
function Slider_gotnewposition(id) {
var tgt = sliders[id];
var thumb_pos = parseInt(tgt.thumb.style.left.replace("px",""));
if (thumb_pos < 0) thumb_pos=0;
if (thumb_pos > parseInt(tgt.tgt.style.width.replace("px",""))) thumb_pos=parseInt(tgt.tgt.style.width.replace("px",""));
var value = thumb_pos / parseInt(tgt.tgt.style.width.replace("px",""));
tgt.position = value;
//alert(value);
if (tgt.onNewPosition) tgt.onNewPosition();
}
var posx = 0;
var posy = 0;
function doSomething(e) {
if (!e) var e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop
+ document.documentElement.scrollTop;
}
// posx and posy contain the mouse position relative to the document
// Do something with this information
}
//SimpleSliderLibReceived();
\ No newline at end of file
/*
<OWNER> = revolunet
<ORGANIZATION> = revolunet - Julien Bouquillon
<YEAR> = 2008
Copyright (c) 2008, revolunet
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met :
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE, DATA, OR PROFITS ; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//var SimpleSlider_Lib_Uri = "SimpleSlider.js";
var VLC_controller= null;
// theses image are in the subfolder 'images' of your VLCjs lib
var VLC_controller_icon_play = "player_play.png";
var VLC_controller_icon_stop = "player_stop.png";
var VLC_controller_icon_voldown = "moins.gif";
var VLC_controller_icon_volup = "plus.gif";
var VLC_controller_icon_pause = "player_pause.png";
var VLC_controller_icon_sound = "sound.png";
var VLC_controller_icon_soundoff = "sound_mute.png";
var VLC_controller_icon_options = "options.png";
var VLC_controller_icon_infos = "info.png";
var VLC_controller_icon_fullscreen = "fullscreen.gif";
var VLC_status = new Array("standby", "ouverture", "buffering", "lecture", "pause", "stop", "erreur");
var VLC_controller_default_buffersize = "5";
var VLC_controller_log_verbosity = -1;
// function SimpleSliderLibReceived() {
// VLC_controller.slider = new Slider(VLC_controller.id+"_slider", VLC_controller.width, "10");
// VLC_controller.slider.onNewPosition = VLC_controller.slider_position_changed;
// }
function toolbar_icon(icon, alt, onclick, id) {
return "<img id='" + id + "' width='16' height='16' src='" + icon + "' style='vertical-align:middle;cursor:pointer;margin:3px' onclick='" + onclick + "'/>";
}
function changeImageSrc(imgID, newSrc) {
var tgt = document.getElementById(imgID);
cursrc = tgt.src.substring(tgt.src.length - newSrc.length);
if (cursrc != newSrc) tgt.src=newSrc;
}
// HTML FUNCTIONS
// function injectJS(uri) {
// var s = document.createElement('script');
// s.src = uri;
// s.type = 'text/javascript';
// document.body.appendChild(s);
// }
function addHTMLtoObj(obj, html, position) {
if(self.Node&&self.Node.prototype){
// mozilla
var range = document.createRange();
range.selectNode(obj);
var htmlnode = range.createContextualFragment(html);
var parent = obj.parentNode;
position = position.toLowerCase();
if (position=="beforebegin") parent.insertBefore(htmlnode, obj);
else if(position=="afterend") parent.insertBefore(htmlnode, obj.nextSibling);
else if(position=="afterbegin") obj.insertBefore(htmlnode, obj.childNodes[0]);
else if(position=="beforeend") obj.appendChild(htmlnode);
}
else {
//ie
obj.insertAdjacentHTML(position, html);
}
}
function SimpleSlider_received() {
//VLC_controller.target = new VLCobject(VLC_controller.id, VLC_controller.with, VLC_controller.height);
//alert(VLC_controller);
VLC_controller.libsReady();
}
function VLCcontrols(VLCobject, dodebug) {
this.id = VLCobject.getAttribute('id');
this.idleimage = null;
this.isVideoVisible = true;
this.target = document.getElementById(this.id);
//this.updateTarget();
this.root = ""
this.options = new VLC_options(this);
//this.options.VLCcontrol = this;
this.loaded = false;
this.onready = null;
this.libloader = new ExternalLibLoader();
//this.libloader.addLib("VLCobject.js", VLCobject_received);
this.libloader.addLib("SimpleSlider.js", SimpleSlider_received);
this.libloader.LoadLibs();
//this.options.set("http-caching", parseInt(VLC_controller_default_buffersize) * 1000);
// this.options.set("udp-caching", parseInt(VLC_controller_default_buffersize) * 1000);
//this.options.set("http-reconnect", "true");
VLC_controller = this;
this.dodebug = false;
this.width = VLCobject.getAttribute("width");
//this.target.width;
this.height = VLCobject.getAttribute("height");
if (dodebug) this.dodebug = dodebug;
// detect lib path (dirty)
var sc = document.getElementsByTagName("SCRIPT");
for (var i=0;i<sc.length;i++) {
if(sc[i].src.indexOf("VLCcontrols.js")>-1) {
this.root = sc[i].src.replace("VLCcontrols.js","");
}
}
// if(!this.target) {
// var errorinfo = "<span class='VLC_controller_notdetected'><b>Plugin VLC non dtct !</b> --> telechargez le sur <a href='http://www.videolan.org/vlc/' target='_blank'>http://www.videolan.org/vlc/</a></span>";
// document.body.innerHTML = errorinfo + document.body.innerHTML;
//// return;
// }
}
VLCcontrols.prototype.libsReady = function() {
//alert(1);
//alert(Slider);
var bg_img = '<img style="display:" src="#" width="1" height="1" id="' + this.target.id +'_idleimage">';
addHTMLtoObj(this.target, bg_img, "beforebegin");
var toolbar = "";
toolbar += '<div style="display:block;width:'+this.width +'px" id="'+this.id+'_slider"></div>';
toolbar += "<div id='" + this.target.id + "_toolbar' class='VLC_toolbar' style='background:lightgrey;width:" + this.width + "px'>";
toolbar += "<table border=0 cellpading=0 cellspacing=0 width='100%'><tr><td >";
toolbar += toolbar_icon(this.root + "images/" + VLC_controller_icon_play, "Play/Pause", "VLC_controller.btn_play_clicked()", this.id + "_btn_play");
toolbar += toolbar_icon(this.root + "images/" + VLC_controller_icon_stop, "Stop", "VLC_controller.btn_stop_clicked()", this.id + "_btn_stop");
// toolbar += toolbar_icon("/vlcjs/images/player_prev.png", "Prev", "", this.id + "_btn_prev");
//toolbar += toolbar_icon("/vlcjs/images/player_next.png", "Next", "", this.id + "_btn_next");
toolbar += toolbar_icon(this.root + "images/" + VLC_controller_icon_sound, "Volume", "VLC_controller.btn_mute_clicked()", this.id + "_btn_mute");
toolbar += toolbar_icon(this.root + "images/" + VLC_controller_icon_voldown, "Volume down", "VLC_controller.btn_voldown_clicked()", this.id + "_btn_voldown");
toolbar += "<span style='font-size:10px'><span id='" + this.target.id + "_vollabel'>100</span>%</span>";
toolbar += toolbar_icon(this.root + "images/" + VLC_controller_icon_volup, "Volume up", "VLC_controller.btn_volup_clicked()", this.id + "_btn_volup");
toolbar += toolbar_icon(this.root + "images/" + VLC_controller_icon_fullscreen, "FullScreen", "VLC_controller.btn_fullscreen_clicked()", this.id + "_btn_fullscreen");
toolbar += "</td><td align=center width=60>";
toolbar += '<span style="vertical-align:middle;position:relative;" id="infosPosition">00:00/00:00</span>';
toolbar += "</td><td align=center width=65>";
toolbar += '&nbsp;&nbsp;<span style="vertical-align:middle;" id="infosStatus">stopped</span>';
toolbar += "</td><td align=center width=45>";
toolbar += toolbar_icon(this.root + "images/" + VLC_controller_icon_options, "Options", "VLC_controller.btn_options_clicked()", this.id + "_btn_options");
toolbar += toolbar_icon(this.root + "images/" + VLC_controller_icon_infos, "About", "VLC_controller.btn_infos_clicked()", this.id + "_btn_infos");
toolbar += "</td></tr></table>";
toolbar += '<div style="display:none" id="VLC_controller_options">';
toolbar += '&nbsp;buffer : <input size=1 style="vertical-align:middle;" id="VLC_controller_options_http-caching" value="' + VLC_controller_default_buffersize + '" /> sec.';
toolbar += '&nbsp;&nbsp;<input type="checkbox" ' + (this.dodebug && 'checked=1' || '') + '" style="vertical-align:middle;" onclick="VLC_controller.setdebug(this.checked)" id="VLC_controller_dodebugcheckbox"/><label for="VLC_controller_dodebugcheckbox">debug</label>';
// toolbar += '<span style="display:none">&nbsp;&nbsp;<input type="checkbox" ' + (this.dodebugvlc && 'checked=1' || 'checked=1') + '" style="vertical-align:middle;" onclick="VLC_controller.setdebugvlc(this.checked)" id="VLC_controller_dodebugvlccheckbox"/><label for="VLC_controller_dodebugvlccheckbox">debug VLC</label></span>';
toolbar += '&nbsp;&nbsp;<input type="checkbox" style="vertical-align:middle;" id="VLC_controller_DesktopOutputcheckbox"/><label for="VLC_controller_DesktopOutputcheckbox">set as wallpaper</label>';
toolbar += '<span style="display:none">&nbsp;&nbsp;<input type="checkbox" style="vertical-align:middle;" id="VLC_controller_FreeplayerModecheckbox"/><label for="VLC_controller_FreeplayerModecheckbox">FreePlayer</label></span>';
toolbar += '&nbsp;&nbsp;&nbsp;&nbsp;<button style="vertical-align:middle;" onclick="VLC_controller.saveOptions()">ok</button></div>';
toolbar += "<div id='VLC_controller_debug_div' style='display:block'><textarea id='VLC_controller_debug' style='display:block;width:" + this.width + "px;height:200px'></textarea>";
toolbar += "</div>";
toolbar += '<div style="display:none" id="VLC_controller_infos">';
toolbar += '<br>This VLC widget has been created by the <a href="http://www.revolunet.com">revolunet</a> team.<br>Comments welcome on <a href="mailto:contact@revolunet.com?subject=VLCcontrols">contact@revolunet.com</a> !<br><br>';
toolbar += "</div>";
//this.target.insertAdjacentHTML("afterEnd", toolbar);
addHTMLtoObj(this.target, toolbar, "afterEnd");
//alert(this.width);
this.slider = new Slider(this.id+"_slider", this.width, "10");
this.slider.onNewPosition = this.slider_position_changed;
//this.slider = null;
// trick to load external JS file
//injectJS(this.root + SimpleSlider_Lib_Uri);
this.load();
setInterval("VLC_controller.updateStatus()", 1000 );
this.loaded = true;
if (this.onready) this.onready();
//this.debug("plugin loaded v." + this.target.versionInfo);
}
VLCcontrols.prototype.changeVolume = function(newVolume) {
// prends une valeur entre 0 et 100
document.getElementById(this.id + "_vollabel").innerHTML = newVolume;
//var vlc_volume = parseInt(newVolume)
this.target.audio.volume = newVolume;
if (newVolume > 0) changeImageSrc(this.id + "_btn_mute", this.root + "images/" + VLC_controller_icon_sound);
else changeImageSrc(this.id + "_btn_mute", this.root + "images/" + VLC_controller_icon_soundoff);
}
VLCcontrols.prototype.btn_voldown_clicked = function() {
if (!this.target.audio) return;
var curvolume = this.target.audio.volume;
curvolume -= 10;
if (curvolume <= 0) this.changeVolume(0);
else if (curvolume >= 200) this.changeVolume(200);
else this.changeVolume(curvolume);
}
VLCcontrols.prototype.btn_fullscreen_clicked = function() {
this.target.video.toggleFullscreen();
// = true;
}
VLCcontrols.prototype.btn_volup_clicked = function() {
if (!this.target.audio) return;
var curvolume = this.target.audio.volume;
curvolume += 10;
if (curvolume <= 0) this.changeVolume(0);
else if (curvolume >= 200) this.changeVolume(200);
else this.changeVolume(curvolume);
}
VLCcontrols.prototype.setFreeplayerMode = function(checked) {
}
VLCcontrols.prototype.updateTarget = function() {
this.target = document.getElementById(this.id);
if (!document.all) {
this.target.innerHTML += '<embed type="application/x-vlc-plugin" pluginspage="http://www.videolan.org" version="VideoLAN.VLCPlugin.2" id="' + this.id + '_moz"/>';
this.target = document.getElementById(this.id + "_moz");
}
}
VLCcontrols.prototype.setIdleImage = function(imgSrc) {