212 lines
10 KiB
JavaScript
212 lines
10 KiB
JavaScript
/*
|
|
* This file is part of Toolkit.
|
|
*
|
|
* Toolkit is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* Toolkit is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General
|
|
* Public License along with this program; if not, write to the
|
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA
|
|
*/
|
|
"use strict";
|
|
(function(w, TK){
|
|
TK.Gradient = TK.class({
|
|
/**
|
|
* TK.Gradient provides a function to set the background of a
|
|
* DOM element to a CSS gradient according on the users browser and version.
|
|
* TK.Gradient needs a {@link TK.Range} to be implemented on.
|
|
*
|
|
* @mixin TK.Gradient
|
|
*
|
|
* @param {Object} [options={ }] - An object containing initial options.
|
|
*
|
|
* @property {Object|Boolean} options.gradient - Gradient definition for the background.
|
|
* Keys are ints or floats as string corresponding to the widgets scale.
|
|
* Values are valid css color strings like <code>#ff8000</code> or <code>rgb(0,56,103)</code>.
|
|
* If set to false the css style color is used.
|
|
* @property {String|Boolean} [options.background="#000000"] - Background color if no gradient is used.
|
|
* Values are valid css color strings like <code>#ff8000</code> or <code>rgb(0,56,103)</code>.
|
|
* If set to false the css style color is used.
|
|
*/
|
|
_class: "Gradient",
|
|
Implements: TK.Ranged,
|
|
_options: Object.assign(TK.Ranged.prototype._options, {
|
|
gradient: "mixed",
|
|
background: "mixed",
|
|
}),
|
|
options: {
|
|
gradient: false,
|
|
background: false
|
|
},
|
|
draw_gradient: function (element, gradient, fallback, range) {
|
|
/**
|
|
* This function generates a string from a given
|
|
* gradient object to set as a CSS background for a DOM element.
|
|
* If element is given, the function automatically sets the
|
|
* background. If gradient is omitted, the gradient is taken from
|
|
* options. Fallback is used if no gradient can be created.
|
|
* If fallback is omitted, <code>options.background</code> is used. if no range
|
|
* is set Gradient assumes that the implementing instance has
|
|
* {@link TK.Range} functionality.
|
|
*
|
|
* @method TK.Gradient#draw_gradient
|
|
*
|
|
* @param {DOMNode} element - The DOM node to apply the gradient to.
|
|
* @param {Object} [gradient=this.options.gradient] - Gradient definition for the background, e.g. <code>{"-96": "rgb(30,87,153)", "-0.001": "rgb(41,137,216)", "0": "rgb(32,124,202)", "24": "rgb(125,185,232)"}</code>.
|
|
* @param {string} [fallback=this.options.background] - If no gradient can be applied, use this as background color string.
|
|
* @param {TK.Range} [range=this] - If a specific range is set, it is used for the calculations. If not, we expect the widget itself provides {@link TK.Ranged} functionality.
|
|
*
|
|
* @returns {string} A string to be used as background CSS.
|
|
*
|
|
* @mixes TK.Ranged
|
|
*
|
|
* @emits TK.Gradient#backgroundchanged
|
|
*/
|
|
|
|
// {"-96": "rgb(30,87,153)", "-0.001": "rgb(41,137,216)", "0": "rgb(32,124,202)", "24": "rgb(125,185,232)"}
|
|
// becomes:
|
|
// background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><linearGradient id='gradient'><stop offset='10%' stop-color='#F00'/><stop offset='90%' stop-color='#fcc'/> </linearGradient><rect fill='url(#gradient)' x='0' y='0' width='100%' height='100%'/></svg>");
|
|
// background: -moz-linear-gradient(top, rgb(30,87,153) 0%, rgb(41,137,216) 50%, rgb(32,124,202) 51%, rgb(125,185,232) 100%);
|
|
// background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgb(30,87,153)), color-stop(50%,rgb(41,137,216)), color-stop(51%,rgb(32,124,202)), color-stop(100%,rgb(125,185,232)));
|
|
// background: -webkit-linear-gradient(top, rgb(30,87,153) 0%,rgb(41,137,216) 50%,rgb(32,124,202) 51%,rgb(125,185,232) 100%);
|
|
// background: -o-linear-gradient(top, rgb(30,87,153) 0%,rgb(41,137,216) 50%,rgb(32,124,202) 51%,rgb(125,185,232) 100%);
|
|
// background: -ms-linear-gradient(top, rgb(30,87,153) 0%,rgb(41,137,216) 50%,rgb(32,124,202) 51%,rgb(125,185,232) 100%);
|
|
// background: linear-gradient(to bottom, rgb(30,87,153) 0%,rgb(41,137,216) 50%,rgb(32,124,202) 51%,rgb(125,185,232) 100%);
|
|
// filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1e5799', endColorstr='#7db9e8',GradientType=0 );
|
|
|
|
var bg = "";
|
|
range = range || this;
|
|
if (!gradient && !this.options.gradient)
|
|
bg = fallback || this.options.background;
|
|
else {
|
|
gradient = gradient || this.options.gradient;
|
|
|
|
var ms_first = "";
|
|
var ms_last = "";
|
|
var m_svg = "";
|
|
var m_regular = "";
|
|
var m_webkit = "";
|
|
var s_ms = "background filter: progid:DXImageTransform."
|
|
+ "Microsoft.gradient( startColorstr='%s', "
|
|
+ "endColorstr='%s',GradientType='%d' )";
|
|
var s_svg = "url(\"data:image/svg+xml;utf8,<svg "
|
|
+ "xmlns='http://www.w3.org/2000/svg' width='100%%' "
|
|
+ "height='100%%'>"
|
|
+ "<linearGradient id='%s_gradient' %s>%s"
|
|
+ "</linearGradient><rect fill='url(#%s_gradient)' "
|
|
+ "x='0' y='0' width='100%%' "
|
|
+ "height='100%%'/></svg>\")";
|
|
var s_regular = "%slinear-gradient(%s, %s)";
|
|
var s_webkit = "-webkit-gradient(linear, %s, %s)";
|
|
var c_svg = "<stop offset='%s%%' stop-color='%s'/>";
|
|
var c_regular = "%s %s%%, ";
|
|
var c_webkit = "color-stop(%s%%, %s), ";
|
|
|
|
var d_w3c = {};
|
|
d_w3c["s"+"left"] = "to top";
|
|
d_w3c["s"+"right"] = "to top";
|
|
d_w3c["s"+"top"] = "to right";
|
|
d_w3c["s"+"bottom"] = "to right";
|
|
|
|
var d_regular = {};
|
|
d_regular["s"+"left"] = "bottom";
|
|
d_regular["s"+"right"] = "bottom";
|
|
d_regular["s"+"top"] = "left";
|
|
d_regular["s"+"bottom"] = "left";
|
|
|
|
var d_webkit = {};
|
|
d_webkit["s"+"left"] = "left bottom, left top";
|
|
d_webkit["s"+"right"] = "left bottom, left top";
|
|
d_webkit["s"+"top"] = "left top, right top";
|
|
d_webkit["s"+"bottom"] = "left top, right top";
|
|
|
|
var d_ms = {};
|
|
d_ms["s"+"left"] = 'x1="0%" y1="0%" x2="0%" y2="100%"';
|
|
d_ms["s"+"right"] = 'x1="0%" y1="0%" x2="0%" y2="100%"';
|
|
d_ms["s"+"top"] = 'x1="100%" y1="0%" x2="0%" y2="0%"';
|
|
d_ms["s"+"bottom"] = 'x1="100%" y1="0%" x2="0%" y2="0%"';
|
|
|
|
var keys = Object.keys(gradient);
|
|
for (var i = 0; i < keys.length; i++) {
|
|
keys[i] = parseFloat(keys[i]);
|
|
}
|
|
keys = keys.sort(this.options.reverse ?
|
|
function (a,b) { return b-a } : function (a,b) { return a-b });
|
|
|
|
for (var i = 0; i < keys.length; i++) {
|
|
var ps = (100*range.val2coef(range.snap(keys[i]))).toFixed(2);
|
|
if (!ms_first) ms_first = gradient[i];
|
|
ms_last = gradient[keys[i] + ""];
|
|
|
|
m_svg += TK.sprintf(c_svg, ps, gradient[keys[i] + ""]);
|
|
m_regular += TK.sprintf(c_regular, gradient[keys[i] + ""], ps);
|
|
m_webkit += TK.sprintf(c_webkit, ps, gradient[keys[i] + ""]);
|
|
}
|
|
m_regular = m_regular.substr(0, m_regular.length -2);
|
|
m_webkit = m_regular.substr(0, m_webkit.length -2);
|
|
|
|
if (TK.browser.name === "IE" && TK.browser.version <= 8)
|
|
bg = (TK.sprintf(s_ms, ms_last, ms_first, this._vert() ? 0:1));
|
|
|
|
else if (TK.browser.name === "IE" && TK.browser.version === 9)
|
|
bg = (TK.sprintf(s_svg, this.options.id,
|
|
d_ms["s"+this.options.layout],
|
|
m_svg, this.options.id));
|
|
|
|
else if (TK.browser.name === "IE" && TK.browser.version >= 10)
|
|
bg = (TK.sprintf(s_regular, "-ms-",
|
|
d_regular["s" + this.options.layout],
|
|
m_regular));
|
|
|
|
else if (TK.browser.name=="Firefox")
|
|
bg = (TK.sprintf(s_regular, "-moz-",
|
|
d_regular["s"+this.options.layout],
|
|
m_regular));
|
|
|
|
else if (TK.browser.name === "Opera" && TK.browser.version >= 11)
|
|
bg = (TK.sprintf(s_regular, "-o-",
|
|
d_regular["s"+this.options.layout],
|
|
m_regular));
|
|
|
|
else if (TK.browser.name === "Chrome" && TK.browser.version < 10
|
|
|| TK.browser.name === "Safari" && TK.browser.version < 5.1)
|
|
bg = (TK.sprintf(s_webkit,
|
|
d_webkit["s"+this.options.layout],
|
|
m_regular));
|
|
|
|
else if (TK.browser.name === "Chrome" || TK.browser.name === "Safari")
|
|
bg = (TK.sprintf(s_regular, "-webkit-",
|
|
d_regular["s"+this.options.layout],
|
|
m_regular));
|
|
|
|
else
|
|
bg = (TK.sprintf(s_regular, "",
|
|
d_w3c["s"+this.options.layout],
|
|
m_regular));
|
|
}
|
|
|
|
if (element) {
|
|
element.style.background = bg ? bg : void 0;
|
|
/**
|
|
* Is fired when the gradient was created.
|
|
*
|
|
* @event TK.Gradient#backgroundchanged
|
|
*
|
|
* @param {HTMLElement} element - The element which background has changed.
|
|
* @param {string} background - The background of the element as CSS color string.
|
|
*/
|
|
this.fire_event("backgroundchanged", element, bg);
|
|
}
|
|
return bg;
|
|
}
|
|
});
|
|
})(this, this.TK);
|