/* <copyright> This file contains proprietary software owned by Motorola Mobility, Inc.<br/> No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. </copyright> */ //////////////////////////////////////////////////////////////////////// // var Montage = require("montage/core/core").Montage, Component = require("montage/ui/component").Component; //////////////////////////////////////////////////////////////////////// //Exporting as ColorBar exports.ColorBar = Montage.create(Component, { //////////////////////////////////////////////////////////////////// //No reel needed since it's just a bar component hasTemplate: { value: true }, //////////////////////////////////////////////////////////////////// //Width of spectrum (not including b/w buttons) _colorBarSpectrumWidth: { enumerable: false, value: null }, //////////////////////////////////////////////////////////////////// //Width of spectrum steps (used to calculate size of B/W buttons) _colorBarSpectrumWidthSteps: { enumerable: false, value: 10 }, //////////////////////////////////////////////////////////////////// //Default value _value: { enumerable: false, value: {h: 0, s: 0, v: 0} }, //////////////////////////////////////////////////////////////////// //HSV Value selected from bar value: { enumerable: true, get: function() { return this._value; }, set: function(value) { if (value) { //Checking for limits (Max and Min HSV values) if (value.h > Math.PI*2) { value.h = Math.PI*2; } else if (value.h < 0) { value.h = 0; } // if (value.s > 1) { value.s = 1; } else if (value.s < 0) { value.s = 0; } // if (value.v > 1) { value.v = 1; } else if (value.v < 0) { value.v = 0; } //Setting value this._value = value; // if (!this._isMouseDown) { this._dispatchActionEvent('change', true); } } } }, //////////////////////////////////////////////////////////////////// // prepareForDraw: { enumerable: false, value: function() { //Nothing } }, //////////////////////////////////////////////////////////////////// //Setting up and drawing canvas to object willDraw: { enumerable: false, value: function() { //Setting the width and height of the canvas to match container this.element.width = parseInt(window.getComputedStyle(this.element, null).width); this.element.height = parseInt(window.getComputedStyle(this.element, null).height); } }, //////////////////////////////////////////////////////////////////// // draw: { value: function () { //Local variables var cb_canvas = this.element, cb_ctx, cb_grdnt, cb_slc, cb_gwidth, PI = Math.PI, i; //calculating width of spectrum (remainder is used for B/W buttons) cb_gwidth = Math.round(cb_canvas.width - cb_canvas.width/this._colorBarSpectrumWidthSteps); //Context and Gradient cb_ctx = cb_canvas.getContext('2d'); cb_grdnt = cb_ctx.createLinearGradient(0, cb_canvas.height, cb_gwidth, cb_canvas.height); //////////////////////////////////////////////////////// //Looping through set intervals (Creating spectrum) for (i=0; i<60; i++) { //Calculating slice number cb_slc = Math.round(255*i/60); //Creating gradient slices (6 colors in color theory) cb_grdnt.addColorStop(i/360, 'rgb(255, '+cb_slc+', 0)'); cb_grdnt.addColorStop((i+60)/360, 'rgb('+(255-cb_slc)+', 255, 0)'); cb_grdnt.addColorStop((i+120)/360, 'rgb(0, 255, '+cb_slc+')'); cb_grdnt.addColorStop((i+180)/360, 'rgb(0, '+(255-cb_slc)+', 255)'); cb_grdnt.addColorStop((i+240)/360, 'rgb('+cb_slc+', 0, 255)'); cb_grdnt.addColorStop((i+300)/360, 'rgb(255, 0,'+(255-cb_slc)+')'); } //Adding Color Bar to the canvas (Gradients) cb_ctx.fillStyle = cb_grdnt; cb_ctx.fillRect(0, 0, cb_gwidth, cb_canvas.height); //////////////////////////////////////////////////////// //White Gradient overlay to simulate L cb_grdnt = cb_ctx.createLinearGradient(0, 0, 0, cb_canvas.height); cb_grdnt.addColorStop(0.0, 'rgba(255, 255, 255, 1)'); cb_grdnt.addColorStop(0.5, 'rgba(255, 255, 255, 0)'); cb_ctx.fillStyle = cb_grdnt; cb_ctx.fillRect(0, 0, cb_gwidth, cb_canvas.height); //Black Gradient overlay to simulate S cb_grdnt = cb_ctx.createLinearGradient(0,0,0,cb_canvas.height); cb_grdnt.addColorStop(0.5, 'rgba(0, 0, 0, 0)'); cb_grdnt.addColorStop(1.0, 'rgba(0, 0, 0, 1)'); cb_ctx.fillStyle = cb_grdnt; cb_ctx.fillRect(0, 0, cb_gwidth, cb_canvas.height); //Black "button" cb_ctx.fillStyle = "#000"; cb_ctx.fillRect(cb_gwidth, cb_canvas.height/2, cb_gwidth, cb_canvas.height/2); //Black line divider cb_ctx.fillStyle = "#000"; cb_ctx.fillRect(cb_gwidth-1, 0, cb_gwidth+1, cb_canvas.height); //White "button" cb_ctx.fillStyle = "#FFF"; cb_ctx.fillRect(cb_gwidth, 0, cb_gwidth, cb_canvas.height/2); //Saving cb_ctx.restore(); cb_ctx.save(); //Cleaning up cb_canvas = cb_ctx = cb_grdnt = cb_slc = cb_gwidth = PI = i = null; } }, //////////////////////////////////////////////////////////////////// //Adding ColorBar to the element didDraw: { value: function() { //Adding functionality via events this.element.addEventListener("mousedown", this, false); this.element.addEventListener("mouseover", this, false); this.element.addEventListener("mousemove", this, false); } }, //////////////////////////////////////////////////////////////////// //Mouse Down (adds other events and updates HSV) handleMousedown: { value: function (e) { if (!this._colorBarSpectrumWidth) this._colorBarSpectrumWidth = (this.element.width - this.element.width/this._colorBarSpectrumWidthSteps)-1; this._isMouseDown = true; document.addEventListener("mouseup", this, false); this._updateHsv(e); } }, //////////////////////////////////////////////////////////////////// //Used to check mouse mode and display cursor _isMouseDown: { enumerable: false, value: false }, //////////////////////////////////////////////////////////////////// //Mouse Move (updates HSV) handleMousemove: { value: function (e) { //Changing cursors style for appropiate user feedback if (e.offsetX > this._colorBarSpectrumWidth) {this.element.style.cursor = 'pointer';} else {this.element.style.cursor = 'crosshair';} //Checking for mouse down to scan for color if (this._isMouseDown) {this._updateHsv(e);} } }, //////////////////////////////////////////////////////////////////// //Mouse Up (Removes events) handleMouseup: { value: function (e) { this._isMouseDown = false; document.removeEventListener("mouseup", this, false); this._dispatchActionEvent('change', false); } }, //////////////////////////////////////////////////////////////////// //Updating HSV values _updateHsv: { value: function (e) { if (e.offsetX > this._colorBarSpectrumWidth) { //Faking button functionality - Simple B/W selection if (e.offsetY >= this.element.offsetHeight/2) { this.value = {h: this.value.h, s: 1, v: 0};} // White else { this.value = {h: this.value.h, s: 0, v: 1};} // Black } else { //Checking for S or V to be applied (no mixing on bar) if (e.offsetY >= this.element.offsetHeight/2) { //Saturation this.value = {h: e.offsetX/this._colorBarSpectrumWidth*Math.PI*2, v: 1-(e.offsetY-this.element.offsetHeight/2)/((this.element.offsetHeight/2-1)), s: 1}; } else { //Vibrance this.value = {h: e.offsetX/this._colorBarSpectrumWidth*Math.PI*2, v: 1, s: (e.offsetY)/((this.element.offsetHeight/2))}; } } // this._dispatchActionEvent('changing', false); } }, //////////////////////////////////////////////////////////////////// //Dispatching "Change" event _dispatchActionEvent: { value: function(type, userInitiated) { var actionEvent = document.createEvent("CustomEvent"); actionEvent.initEvent(type, true, true); actionEvent.type = type; actionEvent.wasSetByCode = userInitiated; actionEvent.hsv = this.value; this.dispatchEvent(actionEvent); } } //////////////////////////////////////////////////////////////////// });