goog.provide('M.Style');
/**
* @namespace M.Style
*/
(function() {
/** * Rec. options que es el json del estilo */
/**
* Abstract class
*
* @api stable
*/
M.Style = (function(options, impl) {
/**
* User options for this style
* @private
* @type {Object}
*/
this.options_ = options;
/**
* The canvas element to draw the style
* into a layer swticher
* @private
* @type {HTMLCanvasElement}
*/
this.canvas_ = document.createElement('canvas');
/**
* The updateCanvas promise to manage
* asynchronous request with icon images
*
* @private
* @type {Promirse}
*/
this.updateCanvasPromise_ = null;
/**
* Layer which this style is applied
* @private
* @type {M.layer.Vector}
*/
this.layer_ = null;
goog.base(this, impl);
// this.updateCanvas();
});
goog.inherits(M.Style, M.facade.Base);
/**
* This function apply style
*
* @public
* @param {M.layer.Vector} layer - Layer to apply the styles
* @function
* @api stable
*/
M.Style.prototype.apply = function(layer) {
this.layer_ = layer;
this.getImpl().applyToLayer(layer);
this.updateCanvas();
};
/**
* This function apply style
*
* @function
* @protected
* @param {M.layer.Vector} layer - Layer to apply the styles
* @api stable
*/
M.Style.prototype.unapply = function(layer) {};
/**
* This function returns the value of the indicated attribute
*
* @function
* @public
* @param {String} attribute - Attribute to know the value
* @return {Object} Attribute Value
*/
M.Style.prototype.get = function(attribute) {
let attrValue;
attrValue = this.options_[attribute];
if (M.utils.isNullOrEmpty(attrValue)) {
// we look up the attribute by its path. Example: getAttribute('foo.bar.attr')
// --> return feature.properties.foo.bar.attr value
let attrPath = attribute.split('.');
if (attrPath.length > 1) {
attrValue = attrPath.reduce((obj, attr) => !M.utils.isNullOrEmpty(obj) ? ((obj instanceof M.Style) ? obj.get(attr) : obj[attr]) : undefined, this);
}
}
return attrValue;
};
/**
* This function set value to property and apply new property
*
* @public
* @param {String} property - Property to change the value
* @param {String} value - Value to property
* @return {M.Style}
* @function
* @api stable
*/
M.Style.prototype.set = function(property, value) {
M.Style.setValue_(this.options_, property, value);
if (!M.utils.isNullOrEmpty(this.layer_)) {
this.getImpl().updateFacadeOptions(this.options_);
}
if (!M.utils.isNullOrEmpty(this.feature_)) {
this.applyToFeature(this.feature_);
}
this.refresh();
return this;
};
/**
* This function set value to property
*
* @private
* @param {Object} obj - Style
* @param {String} path - Path property
* @param {String} value - Value property
* @return {String} value
* @function
*/
M.Style.setValue_ = function(obj, path, value) {
let keys = M.utils.isArray(path) ? path : path.split('.');
let keyLength = keys.length;
let key = keys[0];
if (keyLength === 1) { // base case
if (M.utils.isArray(value)) {
value = [...value];
}
else if (M.utils.isObject(value)) {
value = Object.assign({}, value);
}
obj[key] = value;
}
else if (keyLength > 1) { // recursive case
if (M.utils.isNullOrEmpty(obj[key])) {
obj[key] = {};
}
M.Style.setValue_(obj[key], keys.slice(1, keyLength), value);
}
};
/**
* This function updates the style of the
* layer
*
* @public
* @function
* @return {String} data url to canvas
* @api stable
*/
M.Style.prototype.refresh = function() {
if (!M.utils.isNullOrEmpty(this.layer_)) {
this.apply(this.layer_);
this.updateCanvas();
}
};
/**
* This function returns data url to canvas
*
* @function
* @public
* @return {String} data url to canvas
*/
M.Style.prototype.toImage = function() {
let styleImgB64;
if (M.utils.isNullOrEmpty(this.updateCanvasPromise_)) {
if (!M.utils.isNullOrEmpty(this.options_.icon) && !M.utils.isNullOrEmpty(this.options_.icon.src)) {
let image = new Image();
image.crossOrigin = "Anonymous";
let can = this.canvas_;
image.onload = function() {
var c = can;
var ctx = c.getContext("2d");
ctx.drawImage(this, 0, 0, 50, 50);
};
image.src = this.options_.icon.src;
styleImgB64 = this.canvas_.toDataURL('png');
}
else {
styleImgB64 = this.canvas_.toDataURL('png');
}
}
else {
styleImgB64 = this.updateCanvasPromise_.then(() => this.canvas_.toDataURL('png'));
}
return styleImgB64;
};
/**
* TODO
*/
M.Style.prototype.serialize = function() {};
/**
* This function updates the styles's canvas
*
* @public
* @function
* @api stable
*/
M.Style.prototype.updateCanvas = function() {
this.updateCanvasPromise_ = this.getImpl().updateCanvas(this.canvas_);
};
/**
* TODO
*
*/
M.Style.prototype.equals = function(style) {
return (this.constructor === style.constructor);
};
/**
* This function clones the style
*
* @public
* @return {M.Style}
* @function
* @api stable
*/
M.Style.prototype.clone = function() {
let optsClone = {};
M.utils.extends(optsClone, this.options_);
let implClass = this.getImpl().constructor;
let implClone = new implClass(optsClone);
return new this.constructor(optsClone, implClone);
};
})();