123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- // Copyright 2008 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- /**
- * @fileoverview An HSVA (hue/saturation/value/alpha) color palette/picker
- * implementation.
- * Without the styles from the demo css file, only a hex color label and input
- * field show up.
- *
- * @author chrisn@google.com (Chris Nokleberg)
- * @see ../demos/hsvapalette.html
- */
- goog.provide('goog.ui.HsvaPalette');
- goog.require('goog.array');
- goog.require('goog.color.alpha');
- goog.require('goog.dom.TagName');
- goog.require('goog.events');
- goog.require('goog.events.EventType');
- goog.require('goog.style');
- goog.require('goog.ui.Component');
- goog.require('goog.ui.HsvPalette');
- /**
- * Creates an HSVA palette. Allows a user to select the hue, saturation,
- * value/brightness and alpha/opacity.
- * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
- * @param {string=} opt_color Optional initial color, without alpha (default is
- * red).
- * @param {number=} opt_alpha Optional initial alpha (default is 1).
- * @param {string=} opt_class Optional base for creating classnames (default is
- * 'goog-hsva-palette').
- * @extends {goog.ui.HsvPalette}
- * @constructor
- * @final
- */
- goog.ui.HsvaPalette = function(opt_domHelper, opt_color, opt_alpha, opt_class) {
- goog.ui.HsvaPalette.base(
- this, 'constructor', opt_domHelper, opt_color, opt_class);
- /**
- * Alpha transparency of the currently selected color, in [0, 1]. When
- * undefined, the palette will behave as a non-transparent HSV palette,
- * assuming full opacity.
- * @type {number}
- * @private
- */
- this.alpha_ = goog.isDef(opt_alpha) ? opt_alpha : 1;
- /**
- * @override
- */
- this.className = opt_class || goog.getCssName('goog-hsva-palette');
- };
- goog.inherits(goog.ui.HsvaPalette, goog.ui.HsvPalette);
- /**
- * DOM element representing the alpha background image.
- * @type {HTMLElement}
- * @private
- */
- goog.ui.HsvaPalette.prototype.aImageEl_;
- /**
- * DOM element representing the alpha handle.
- * @type {HTMLElement}
- * @private
- */
- goog.ui.HsvaPalette.prototype.aHandleEl_;
- /**
- * DOM element representing the swatch backdrop image.
- * @type {Element}
- * @private
- */
- goog.ui.HsvaPalette.prototype.swatchBackdropEl_;
- /** @override */
- goog.ui.HsvaPalette.prototype.getAlpha = function() {
- return this.alpha_;
- };
- /**
- * Sets which color is selected and update the UI. The passed color should be
- * in #rrggbb format. The alpha value will be set to 1.
- * @param {number} alpha The selected alpha value, in [0, 1].
- */
- goog.ui.HsvaPalette.prototype.setAlpha = function(alpha) {
- this.setColorAlphaHelper_(this.color, alpha);
- };
- /**
- * Sets which color is selected and update the UI. The passed color should be
- * in #rrggbb format. The alpha value will be set to 1.
- * @param {string} color The selected color.
- * @override
- */
- goog.ui.HsvaPalette.prototype.setColor = function(color) {
- this.setColorAlphaHelper_(color, 1);
- };
- /**
- * Gets the color that is currently selected in this color picker, in #rrggbbaa
- * format.
- * @return {string} The string of the selected color with alpha.
- */
- goog.ui.HsvaPalette.prototype.getColorRgbaHex = function() {
- var alphaHex = Math.floor(this.alpha_ * 255).toString(16);
- return this.color + (alphaHex.length == 1 ? '0' + alphaHex : alphaHex);
- };
- /**
- * Sets which color is selected and update the UI. The passed color should be
- * in #rrggbbaa format. The alpha value will be set to 1.
- * @param {string} color The selected color with alpha.
- */
- goog.ui.HsvaPalette.prototype.setColorRgbaHex = function(color) {
- var parsed = goog.ui.HsvaPalette.parseColorRgbaHex_(color);
- this.setColorAlphaHelper_(parsed[0], parsed[1]);
- };
- /**
- * Sets which color and alpha value are selected and update the UI. The passed
- * color should be in #rrggbb format.
- * @param {string} color The selected color in #rrggbb format.
- * @param {number} alpha The selected alpha value, in [0, 1].
- * @private
- */
- goog.ui.HsvaPalette.prototype.setColorAlphaHelper_ = function(color, alpha) {
- var colorChange = this.color != color;
- var alphaChange = this.alpha_ != alpha;
- this.alpha_ = alpha;
- this.color = color;
- if (colorChange) {
- // This is to prevent multiple event dispatches.
- this.setColorInternal(color);
- }
- if (colorChange || alphaChange) {
- this.updateUi();
- this.dispatchEvent(goog.ui.Component.EventType.ACTION);
- }
- };
- /** @override */
- goog.ui.HsvaPalette.prototype.createDom = function() {
- goog.ui.HsvaPalette.base(this, 'createDom');
- var dom = this.getDomHelper();
- this.aImageEl_ = /** @type {!HTMLElement} */ (
- dom.createDom(
- goog.dom.TagName.DIV, goog.getCssName(this.className, 'a-image')));
- this.aHandleEl_ = /** @type {!HTMLElement} */ (
- dom.createDom(
- goog.dom.TagName.DIV, goog.getCssName(this.className, 'a-handle')));
- this.swatchBackdropEl_ = dom.createDom(
- goog.dom.TagName.DIV, goog.getCssName(this.className, 'swatch-backdrop'));
- var element = this.getElement();
- dom.appendChild(element, this.aImageEl_);
- dom.appendChild(element, this.aHandleEl_);
- dom.appendChild(element, this.swatchBackdropEl_);
- };
- /** @override */
- goog.ui.HsvaPalette.prototype.disposeInternal = function() {
- goog.ui.HsvaPalette.base(this, 'disposeInternal');
- delete this.aImageEl_;
- delete this.aHandleEl_;
- delete this.swatchBackdropEl_;
- };
- /** @override */
- goog.ui.HsvaPalette.prototype.updateUi = function() {
- goog.ui.HsvaPalette.base(this, 'updateUi');
- if (this.isInDocument()) {
- var a = this.alpha_ * 255;
- var top = this.aImageEl_.offsetTop -
- Math.floor(this.aHandleEl_.offsetHeight / 2) +
- this.aImageEl_.offsetHeight * ((255 - a) / 255);
- this.aHandleEl_.style.top = top + 'px';
- this.aImageEl_.style.backgroundColor = this.color;
- goog.style.setOpacity(this.swatchElement, a / 255);
- }
- };
- /** @override */
- goog.ui.HsvaPalette.prototype.updateInput = function() {
- if (!goog.array.equals(
- [this.color, this.alpha_],
- goog.ui.HsvaPalette.parseUserInput_(this.inputElement.value))) {
- this.inputElement.value = this.getColorRgbaHex();
- }
- };
- /** @override */
- goog.ui.HsvaPalette.prototype.handleMouseDown = function(e) {
- goog.ui.HsvaPalette.base(this, 'handleMouseDown', e);
- if (e.target == this.aImageEl_ || e.target == this.aHandleEl_) {
- // Setup value change listeners
- var b = goog.style.getBounds(this.valueBackgroundImageElement);
- this.handleMouseMoveA_(b, e);
- this.mouseMoveListener = goog.events.listen(
- this.getDomHelper().getDocument(), goog.events.EventType.MOUSEMOVE,
- goog.bind(this.handleMouseMoveA_, this, b));
- this.mouseUpListener = goog.events.listen(
- this.getDomHelper().getDocument(), goog.events.EventType.MOUSEUP,
- this.handleMouseUp, false, this);
- }
- };
- /**
- * Handles mousemove events on the document once a drag operation on the alpha
- * slider has started.
- * @param {goog.math.Rect} b Boundaries of the value slider object at the start
- * of the drag operation.
- * @param {goog.events.Event} e Event object.
- * @private
- */
- goog.ui.HsvaPalette.prototype.handleMouseMoveA_ = function(b, e) {
- e.preventDefault();
- var vportPos = this.getDomHelper().getDocumentScroll();
- var newA =
- (b.top + b.height -
- Math.min(Math.max(vportPos.y + e.clientY, b.top), b.top + b.height)) /
- b.height;
- this.setAlpha(newA);
- };
- /** @override */
- goog.ui.HsvaPalette.prototype.handleInput = function(e) {
- var parsed = goog.ui.HsvaPalette.parseUserInput_(this.inputElement.value);
- if (parsed) {
- this.setColorAlphaHelper_(parsed[0], parsed[1]);
- }
- };
- /**
- * Parses an #rrggbb or #rrggbbaa color string.
- * @param {string} value User-entered color value.
- * @return {Array<?>} A two element array [color, alpha], where color is
- * #rrggbb and alpha is in [0, 1]. Null if the argument was invalid.
- * @private
- */
- goog.ui.HsvaPalette.parseUserInput_ = function(value) {
- if (/^#?[0-9a-f]{8}$/i.test(value)) {
- return goog.ui.HsvaPalette.parseColorRgbaHex_(value);
- } else if (/^#?[0-9a-f]{6}$/i.test(value)) {
- return [value, 1];
- }
- return null;
- };
- /**
- * Parses a #rrggbbaa color string.
- * @param {string} color The color and alpha in #rrggbbaa format.
- * @return {!Array<?>} A two element array [color, alpha], where color is
- * #rrggbb and alpha is in [0, 1].
- * @private
- */
- goog.ui.HsvaPalette.parseColorRgbaHex_ = function(color) {
- var hex = goog.color.alpha.parse(color).hex;
- return [
- goog.color.alpha.extractHexColor(hex),
- parseInt(goog.color.alpha.extractAlpha(hex), 16) / 255
- ];
- };
|