mirror of
https://github.com/hanzoai/jube-fork.git
synced 2026-11-02 14:29:36 +00:00
269 lines
10 KiB
JavaScript
Executable File
269 lines
10 KiB
JavaScript
Executable File
(function($, undefined) {
|
|
|
|
// Removing the G flag will cause infinite loop.
|
|
var gradientRegExp = /(?:-\w+?-)?(?:linear|webkit)-gradient\s*?\((?:linear\s*,\s*)?[\s,]*?(.+?,)([^#t\(]+?,)?\s*((?:(?:(?:rgba?|color-stop|from|to)\(.+?\)|#[\d\w]+|transparent)[\s\d\w%]*?[,\s\)]*)+)\)/ig,
|
|
detailRegExp = /(rgba?\([^\)]+?\)|#[\d\w]+|transparent)\s*([\d\.\w%]*)|color-stop\(([\d.]*)[\s,]*(rgba?\([^\)]+?\)|#[\d\w]+)\s*\)/ig,
|
|
stripRegExp = /^\s*|\s*$|,/g,
|
|
splitRegExp = /\s*,\s*/,
|
|
numberRegExp = /\d/,
|
|
zeroTrimRegExp = /^0+|\.?0+$/g,
|
|
directions = {
|
|
top: {
|
|
value: "0",
|
|
limit: "100%"
|
|
},
|
|
bottom: {
|
|
value: "100%",
|
|
limit: "0"
|
|
},
|
|
left: {
|
|
value: "0",
|
|
limit: "100%"
|
|
},
|
|
right: {
|
|
value: "100%",
|
|
limit: "0"
|
|
},
|
|
center: {
|
|
value: "50%",
|
|
limit: "50%"
|
|
}
|
|
}, angles = { // hopefully temporary
|
|
percent: { "0 50%": 0, "50% 100%": 90, "100% 50%": 180, "50% 0": 270, "0 100%": 45, "100% 100%": 135, "100% 0": 225, "0 0": 315 },
|
|
directions: { "0": "left", "90": "bottom", "180": "right", "270": "top", "45": "bottom left", "135": "bottom right", "225": "top right", "315": "top left" },
|
|
reverted: { "left": "0", "bottom": "90", "right": "180", "top": "270", "bottom left": "45", "bottom right": "135", "top right": "225", "top left": "315" }
|
|
};
|
|
|
|
function trimZeroes(value) {
|
|
return value.toPrecision(2).replace(zeroTrimRegExp, "");
|
|
}
|
|
|
|
function normalizePosition(value, inverted) {
|
|
var output = value.split(" ");
|
|
|
|
if (output.length == 1) {
|
|
if (/left|right/.test(output[0])) {
|
|
output = output.concat("center");
|
|
} else {
|
|
output = [ "center" ].concat(output);
|
|
}
|
|
}
|
|
|
|
for (var i = 0, len = output.length; i < len; i++) {
|
|
if (!numberRegExp.test(output[i])) {
|
|
if (inverted) {
|
|
output[i] = directions[output[i]].limit;
|
|
} else {
|
|
output[i] = directions[output[i]].value;
|
|
}
|
|
} else {
|
|
if (inverted) {
|
|
output[i] = 100 - parseFloat(output[i]) + "%";
|
|
}
|
|
|
|
output[i] = output[i].replace(/^0%/, "0");
|
|
}
|
|
}
|
|
|
|
return output.join(" ");
|
|
}
|
|
|
|
window.Gradient = kendo.Observable.extend({
|
|
init: function(cssValue) {
|
|
this.set(cssValue);
|
|
|
|
return this;
|
|
},
|
|
|
|
set: function (cssValue) {
|
|
cssValue = cssValue && cssValue.indexOf("gradient") != -1 ? cssValue : "linear-gradient(top,rgba(0,0,0,0),rgba(0,0,0,0))";
|
|
this.value = this.parseGradient(cssValue);
|
|
|
|
return this;
|
|
},
|
|
|
|
get: function ( prefixes, index, direction ) {
|
|
var output = "", that = this, gradients = [],
|
|
target = !isNaN(index) ? [ that.value[index]] : that.value;
|
|
|
|
if (prefixes == "svg") {
|
|
return that._getSVGGradient(target[0], direction);
|
|
}
|
|
|
|
if (typeof prefixes == "undefined") {
|
|
prefixes = [ kendo.support.transforms.css ];
|
|
} else if (typeof prefixes == "string") {
|
|
prefixes = prefixes.split(splitRegExp);
|
|
}
|
|
|
|
$.each (prefixes, function (idx, value) {
|
|
output = "";
|
|
|
|
target.forEach(function(gradient) {
|
|
if (gradient.stops.length == 2 && gradient.stops[0].color.get() == "rgba(0,0,0,0)" && gradient.stops[1].color.get() == "rgba(0,0,0,0)") {
|
|
output += "none,";
|
|
} else if (value == "-webkit-") {
|
|
output += that._getWebKitGradient(gradient, direction);
|
|
} else {
|
|
output += that._getStandardGradient(gradient, value, direction);
|
|
}
|
|
});
|
|
|
|
gradients.push(output.substring(0, output.length-1));
|
|
});
|
|
|
|
return gradients[1] ? gradients : gradients[0];
|
|
},
|
|
|
|
parseGradient: function (cssValue) {
|
|
var output = [], counter = -1, matches, details, i, lastPosition, color, position, isStandard, buf;
|
|
|
|
while((matches = gradientRegExp.exec(cssValue)) !== null) {
|
|
output[++counter] = {};
|
|
|
|
buf = matches[1].replace(stripRegExp, "");
|
|
output[counter].start = {
|
|
original: buf,
|
|
normalized: normalizePosition(buf)
|
|
};
|
|
|
|
output[counter].angle = angles.percent[output[counter].start.normalized];
|
|
output[counter].stops = [];
|
|
|
|
if (matches[2]) {
|
|
buf = matches[2].replace(stripRegExp, "");
|
|
output[counter].end = {
|
|
original: buf,
|
|
normalized: normalizePosition(buf)
|
|
};
|
|
} else {
|
|
output[counter].end = {
|
|
original: false,
|
|
normalized: normalizePosition(buf, true)
|
|
};
|
|
}
|
|
|
|
i = 0;
|
|
|
|
while((details = detailRegExp.exec(matches[3])) !== null) {
|
|
color = details[1] || details[4];
|
|
isStandard = typeof details[2] != "undefined";
|
|
position = isStandard ? details[2] || 0 : details[3] * 100 || 0;
|
|
lastPosition = isStandard ? details[2] : details[3] * 100;
|
|
|
|
output[counter].stops[i++] = {
|
|
color: new Color(color),
|
|
position: parseFloat(position)
|
|
};
|
|
}
|
|
|
|
if (output[counter].stops[i-1].position === 0 && lastPosition == "") {
|
|
output[counter].stops[i-1].position = 100;
|
|
}
|
|
}
|
|
|
|
return output;
|
|
},
|
|
|
|
getAngle: function (index) {
|
|
return this.value[index].angle;
|
|
},
|
|
|
|
getDirection: function (index) {
|
|
return angles.directions[this.getAngle(index)];
|
|
},
|
|
|
|
setAngle: function (index, angle) {
|
|
if (typeof angle == "string") {
|
|
angle = angles.reverted[angle];
|
|
}
|
|
|
|
angle = angle % 360;
|
|
|
|
var that = this,
|
|
direction = angles.directions[angle];
|
|
|
|
if (that.value[index]) {
|
|
that.value[index].angle = angle;
|
|
|
|
that.value[index].start.original = direction;
|
|
that.value[index].start.normalized = normalizePosition(direction);
|
|
that.value[index].end.original = false;
|
|
that.value[index].end.normalized = normalizePosition(direction, true);
|
|
}
|
|
|
|
return that;
|
|
},
|
|
|
|
closestStop: function (position, index) {
|
|
var lastValue = { position: 10000 };
|
|
|
|
this.value[index].stops.forEach(function(value) {
|
|
if (Math.abs(value.position - position) < Math.abs(lastValue.position - position)) {
|
|
lastValue = value;
|
|
}
|
|
});
|
|
|
|
return lastValue;
|
|
},
|
|
|
|
_getStandardGradient: function (gradient, prefix, direction) {
|
|
var output = "", parsed, clone = $.extend([], gradient.stops);
|
|
|
|
output += prefix + "linear-gradient(" + (direction ? direction : gradient.start.original) + "," + (gradient.end.original ? gradient.end.original + "," : "" );
|
|
|
|
clone.sort(function(a,b) {
|
|
return a.position - b.position; // Always return sorted stops or W3C gradients get confused.
|
|
}).forEach(function(stop) {
|
|
if (stop.position >= 0) {
|
|
parsed = parseInt(stop.position, 10);
|
|
|
|
output += stop.color.get() + (parsed != 0 && stop.position != "100" ? " " + stop.position + "%" : "") + ",";
|
|
}
|
|
});
|
|
|
|
return output.substring(0, output.length - 1) + "),";
|
|
},
|
|
|
|
_getWebKitGradient: function (gradient, direction) {
|
|
var output = "",
|
|
normalizedStart = direction ? normalizePosition(direction) : null,
|
|
normalizedEnd = direction ? normalizePosition(direction, true) : null;
|
|
|
|
output += "-webkit-gradient(linear," + (direction ? normalizedStart : gradient.start.normalized) + "," + (direction ? normalizedEnd : gradient.end.normalized) + ",";
|
|
|
|
gradient.stops.forEach(function(stop) {
|
|
if (stop.position >= 0) {
|
|
output += "color-stop(" + (trimZeroes(stop.position / 100) || "0") + ", " + stop.color.get() + "),";
|
|
}
|
|
});
|
|
|
|
return output.substring(0, output.length - 1) + "),";
|
|
},
|
|
|
|
_getSVGGradient: function (gradient, id, units) {
|
|
var output = "", color, alpha, clone = $.extend([], gradient.stops),
|
|
startDirection = gradient.start.normalized.split(" "),
|
|
endDirection = gradient.end.normalized.split(" ");
|
|
|
|
output += '<linearGradient id="' + (id ? id : "ID") + '" gradientUnits="' + (units ? units : "objectBoundingBox") + '" x1="' + startDirection[0] + '" y1="' +
|
|
startDirection[1] + '" x2="' + endDirection[0] + '" y2="' + endDirection[1] + '">';
|
|
|
|
clone.sort(function(a,b) {
|
|
return a.position - b.position; // Always return sorted stops or W3C gradients get confused.
|
|
}).forEach(function(stop) {
|
|
if (stop.position >= 0) {
|
|
color = $.extend(stop.color.value);
|
|
alpha = color.alpha;
|
|
color.alpha = 1;
|
|
|
|
output += '<stop offset="' + (trimZeroes(stop.position / 100) || "0") + '" stop-color="' + stop.color.color2css(color) + '" stop-opacity="' + alpha + '" %2F>';
|
|
}
|
|
});
|
|
|
|
return output.replace(/#/g, "%23") + "<%2FlinearGradient>";
|
|
}
|
|
});
|
|
|
|
})(jQuery);
|