define([], function() { function ViewFinder(dispatcher, visibility) { // constructor // private variables this._dispatcher = dispatcher; this._state = null; this._visibility = visibility; this._viewerID = ''; //var this._cta; this._vfHeight; this._vfWidth; this._vfTop; this._vfLeft; this._vfScale; this._vfBoxWidth; this._vfBoxHeight; this._vfBoxLeft; this._vfBoxTop; this._clickStartTime = 0; // privileged functions this.initialiseViewFinder = function() { var imageWidth = RICHFX.jQuery('#RICHFXViewerContainer_'+this._viewerID).width(); var imageHeight = RICHFX.jQuery('#RICHFXViewerContainer_'+this._viewerID).height(); // Work out various values this._vfWidth = 75; this._vfHeight = (this._vfWidth/imageWidth) * imageHeight; this._vfTop = imageHeight - this._vfHeight; this._vfLeft = imageWidth - this._vfWidth; this._vfScale = this._vfWidth/imageWidth; if ( this._visibility ) { // Add required divs this._vf = RICHFX.jQuery('#RICHFXViewerContainer_'+this._viewerID).append('
'); RICHFX.jQuery('#RICHFXViewerContainer_'+this._viewerID).append(''); // find src and update background-image var imgSrc = RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + ' img').attr('src'); var parts = imgSrc.split('&recipe'); var urlStart = parts[0]; var retrievedSrc = urlStart + "&recipeWidth=75&recipeQuality=100"; retrievedSrc = RICHFX.media.buildRequiredUrl(retrievedSrc); // preload image var cacheImage = document.createElement('img'); cacheImage.src = retrievedSrc; RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').html(''); } }; this.attachBindings = function() { if ( this._visibility ) { // attach general events RICHFX.jQuery('#RICHFXViewerContainer_'+this._viewerID).bind('assetstate.positionvf.changed', RICHFX.jQuery.proxy(function(event) { this.updateViewFinder(event); return false; }, this)); RICHFX.jQuery('#RICHFXViewerContainer_'+this._viewerID).bind('viewfinder.change.source', RICHFX.jQuery.proxy(function(event, data){ this.handleSourceChange(data); return false; }, this)); if (Modernizr.touch) { // attach touch events RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').bind("touchstart", RICHFX.jQuery.proxy(function(event) { this.handleViewFinderRePosition(event); return false; }, this)); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').bind("touchstart", RICHFX.jQuery.proxy(function(event) { this.handleViewFinderRePosition(event); return false; }, this)); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').bind("touchmove", RICHFX.jQuery.proxy(function(event) { this.handleViewFinderMousemove(event); return false; }, this)); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').bind("touchmove", RICHFX.jQuery.proxy(function(event) { this.handleViewFinderBoxMousemove(event); return false; }, this)); } else { // attach desktop events RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').bind("click", RICHFX.jQuery.proxy(function(event) { this.handleViewFinderClick(event); return false; }, this)); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').bind("click", RICHFX.jQuery.proxy(function(event) { this.handleViewFinderClick(event); return false; }, this)); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').bind("mousedown", RICHFX.jQuery.proxy(function(event) { this.handleViewFinderMousedown(event); return false; }, this)); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').bind("mousedown", RICHFX.jQuery.proxy(function(event) { this.handleViewFinderMousedown(event); return false; }, this)); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').bind("mouseup", RICHFX.jQuery.proxy(function(event) { RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').unbind("mousemove"); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').unbind("mousemove"); return false; }, this)); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').bind("mouseup", RICHFX.jQuery.proxy(function(event) { RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').unbind("mousemove"); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').unbind("mousemove"); return false; }, this)); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').bind("mouseout", RICHFX.jQuery.proxy(function(event) { RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').unbind("mousemove"); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').unbind("mousemove"); return false; }, this)); } } }; this.updateViewFinder = function (event) { // control values var currVFClickLevel = this._state.getZoomLevel(); var currVFPosScale = ( this._vfWidth / this._state.getWidth()); this._currVFScale = ( this._state.getWidth() / this._state.getAssetWidth()); var currVFWidthAssetScale = ( this._vfWidth / this._state.getAssetWidth()); var currVFHeightAssetScale = ( this._vfHeight / this._state.getAssetHeight()); // positioning var assetPosLeft = -(this._state.getX()); var assetPosTop = -(this._state.getY()); // account for the border size this._vfBoxLeft = ((assetPosLeft * currVFWidthAssetScale) + this._vfLeft); this._vfBoxTop = ((assetPosTop * currVFHeightAssetScale) + this._vfTop); // set min/max values if ( this._vfBoxLeft < this._vfLeft ) { this._vfBoxLeft = this._vfLeft; } if ( this._vfBoxTop < this._vfTop ) { this._vfBoxTop = this._vfTop; } // Adjusting the position of the viewfinder to take padding into account // different adjustment needed per device var paddingAdj = 4; if ( Modernizr.touch ) { paddingAdj = 2; } if ( (this._vfBoxLeft + this._vfBoxWidth) > (this._state.getWidth() - paddingAdj) ) { this._vfBoxLeft = (this._vfBoxLeft - paddingAdj); } if ( (this._vfBoxTop + this._vfBoxHeight) > (this._state.getHeight() - paddingAdj) ) { this._vfBoxTop = (this._vfBoxTop - paddingAdj); } // scale viewfinder box this._vfBoxWidth = ( this._vfWidth * this._currVFScale ); this._vfBoxHeight = ( this._vfHeight * this._currVFScale ); // handle reset if ( currVFClickLevel == 0 ) { this.resetViewFinder(); } else { this.updateViewFinderDisplay(); } return false; }; this.resetViewFinder = function () { // reset values to default RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').css('display', 'none'); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').css('display', 'none'); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').css('width', this._vfWidth + 'px'); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').css('height', this._vfHeight + 'px'); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').css('top', this._vfTop + 'px'); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').css('left', this._vfLeft + 'px'); }; this.updateViewFinderDisplay = function() { // use latest values RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').css('display', 'block'); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').css('display', 'block'); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').css('width', this._vfBoxWidth + 'px'); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').css('height', this._vfBoxHeight + 'px'); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').css('top', this._vfBoxTop + 'px'); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').css('left', this._vfBoxLeft + 'px'); }; this.handleViewFinderClick = function (event) { var now = new Date(); var currClickTime = now.getMilliseconds() + now.getSeconds()*1000; if ( (currClickTime - this._clickStartTime) < 200 ) { this.handleViewFinderRePosition(event); } return false; }; this.handleViewFinderRePosition = function(event) { // Actual click position var mouseX = event.pageX; var mouseY = event.pageY; var vfPosition = RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').offset(); // relative click position var mouseTop = mouseY - vfPosition.top; var mouseLeft = mouseX - vfPosition.left; // ToDo: stop the vfBox from being able to move outside the ViewFinder var boxPosMinLeft = 0; var boxPosMinTop = 0; var boxPosMaxLeft = (this._vfWidth - this._vfBoxWidth); var boxPosMaxTop = (this._vfHeight - this._vfBoxHeight); var boxMoveTop = mouseTop - (this._vfBoxHeight/2); var boxMoveLeft = mouseLeft - (this._vfBoxWidth/2); // ensure it sticks to regions if ( boxMoveTop < boxPosMinTop ) boxMoveTop = boxPosMinTop; if ( boxMoveLeft < boxPosMinLeft ) boxMoveLeft = boxPosMinLeft; if ( boxMoveTop > boxPosMaxTop ) boxMoveTop = boxPosMaxTop; if ( boxMoveLeft > boxPosMaxLeft ) boxMoveLeft = boxPosMaxLeft; var vfBox = RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox'); var vfBoxTop = (this._vfTop + boxMoveTop ); var vfBoxLeft = (this._vfLeft + boxMoveLeft ); // centre box at click vfBox.css('top', vfBoxTop + 'px'); vfBox.css('left', vfBoxLeft + 'px'); var currVFWidthAssetScale = ( this._vfWidth / this._state.getAssetWidth()); var currVFHeightAssetScale = ( this._vfHeight / this._state.getAssetHeight()); var moveLeft = ((vfBoxLeft - this._vfLeft)/currVFWidthAssetScale); var moveTop = ((vfBoxTop - this._vfTop)/currVFHeightAssetScale); // tmp remove this._state.setPosition(-(moveLeft), -(moveTop)); }; this.handleViewFinderMousedown = function(event) { var now = new Date(); this._clickStartTime = now.getMilliseconds() + now.getSeconds()*1000; event.preventDefault(); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').bind("mousemove", RICHFX.jQuery.proxy(function(event) { this.handleViewFinderMouseMove(event); }, this)); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox').bind("mousemove", RICHFX.jQuery.proxy(function(event) { this.handleViewFinderBoxMousemove(event); }, this)); return false; }; this.handleViewFinderMousemove = function(event) { event.preventDefault(); var mouseX = event.pageX; var mouseY = event.pageY; var vfPosition = RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').offset(); // relative click position var mouseTop = mouseY - vfPosition.top; var mouseLeft = mouseX - vfPosition.left; // ToDo: stop the vfBox from being able to move outside the ViewFinder var boxPosMinLeft = 0; var boxPosMinTop = 0; var boxPosMaxLeft = (this._vfWidth - this._vfBoxWidth); var boxPosMaxTop = (this._vfHeight - this._vfBoxHeight); var boxMoveTop = mouseTop - (this._vfBoxHeight/2); var boxMoveLeft = mouseLeft - (this._vfBoxWidth/2); // ensure it sticks to regions if ( boxMoveTop < boxPosMinTop ) boxMoveTop = boxPosMinTop; if ( boxMoveLeft < boxPosMinLeft ) boxMoveLeft = boxPosMinLeft; if ( boxMoveTop > boxPosMaxTop ) boxMoveTop = boxPosMaxTop; if ( boxMoveLeft > boxPosMaxLeft ) boxMoveLeft = boxPosMaxLeft; var vfBox = RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox'); var vfBoxTop = (this._vfTop + boxMoveTop ); var vfBoxLeft = (this._vfLeft + boxMoveLeft ); // centre box at click vfBox.css('top', vfBoxTop + 'px'); vfBox.css('left', vfBoxLeft + 'px'); // move zoomed image var currVFWidthAssetScale = ( this._vfWidth / this._state.getAssetWidth()); var currVFHeightAssetScale = ( this._vfHeight / this._state.getAssetHeight()); var moveLeft = ((vfBoxLeft - this._vfLeft)/currVFWidthAssetScale); var moveTop = ((vfBoxTop - this._vfTop)/currVFHeightAssetScale); this._state.setPosition(-(moveLeft), -(moveTop)); return false; }; this.handleViewFinderBoxMousemove = function(event) { event.preventDefault(); var mouseX = event.pageX; var mouseY = event.pageY; var vfPosition = RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').offset(); // relative click position var mouseTop = mouseY - vfPosition.top; var mouseLeft = mouseX - vfPosition.left; // ToDo: stop the vfBox from being able to move outside the ViewFinder var boxPosMinLeft = 0; var boxPosMinTop = 0; var boxPosMaxLeft = (this._vfWidth - this._vfBoxWidth); var boxPosMaxTop = (this._vfHeight - this._vfBoxHeight); var boxMoveTop = mouseTop - (this._vfBoxHeight/2); var boxMoveLeft = mouseLeft - (this._vfBoxWidth/2); // ensure it sticks to regions if ( boxMoveTop < boxPosMinTop ) boxMoveTop = boxPosMinTop; if ( boxMoveLeft < boxPosMinLeft ) boxMoveLeft = boxPosMinLeft; if ( boxMoveTop > boxPosMaxTop ) boxMoveTop = boxPosMaxTop; if ( boxMoveLeft > boxPosMaxLeft ) boxMoveLeft = boxPosMaxLeft; var vfBox = RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vfBox'); var vfBoxTop = (this._vfTop + boxMoveTop ); var vfBoxLeft = (this._vfLeft + boxMoveLeft ); // centre box at click vfBox.css('top', vfBoxTop + 'px'); vfBox.css('left', vfBoxLeft + 'px'); // move zoomed image var currVFWidthAssetScale = ( this._vfWidth / this._state.getAssetWidth()); var currVFHeightAssetScale = ( this._vfHeight / this._state.getAssetHeight()); var moveLeft = ((vfBoxLeft - this._vfLeft)/currVFWidthAssetScale); var moveTop = ((vfBoxTop - this._vfTop)/currVFHeightAssetScale); this._state.setPosition(-(moveLeft), -(moveTop)); return false; }; this.handleSourceChange = function (data) { // Handle Source Change for both Zoom and Rotate var dataSrc = ''; if ( data != undefined ) { dataSrc = data.src; } else { dataSrc = RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_initialImage').attr('src'); } // find src and update background-image var parts = dataSrc.split('&recipe'); var urlStart = parts[0]; var retrievedSrc = urlStart + "&recipeWidth=75&recipeQuality=100"; retrievedSrc = RICHFX.media.buildRequiredUrl(retrievedSrc); // preload image var cacheImage = document.createElement('img'); cacheImage.src = retrievedSrc; RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID + '_vf').html(''); if ( data != undefined ) { // reset values only in colorChange mode, rotation will need the viewfinder to be viewable this.resetViewFinder(); } return false; }; this.handleViewFinderBoxMove = function () { // to be populated }; }; ViewFinder.prototype = { // variables //functions viewFinderInit: function(){ }, viewFinderReady: function(){ }, setState: function(assetState, viewerID) { this._state = assetState; this._viewerID = viewerID; this.initialiseViewFinder(); this.attachBindings(); }, setVisibility: function(visibility, data) { this._visibility = visibility; if ( visibility == false ) { RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID).unbind('assetstate.positionvf.changed'); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID).unbind('viewfinder.change.source'); } else { RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID).bind('assetstate.positionvf.changed', RICHFX.jQuery.proxy(function(event) { this.updateViewFinder(event); return false; }, this)); RICHFX.jQuery('#RICHFXViewerContainer_' + this._viewerID).bind('viewfinder.change.source', RICHFX.jQuery.proxy(function(event, data){ this.handleSourceChange(data); return false; }, this)); // Ensure that the correct image is displayed this.handleSourceChange(data); } } }; return ViewFinder; });