Files
2022-11-04 13:24:24 +02:00

336 lines
13 KiB
JavaScript
Executable File

(function($, undefined) {
function limitValue(value, minLimit, maxLimit) {
return Math.max( minLimit, Math.min( maxLimit, value));
}
var ui = kendo.ui,
Widget = ui.Widget,
support = kendo.support,
click = support.touch ? "touchend" : "click",
Class = kendo.Class,
rotatorGradient = new Gradient("linear-gradient(top, rgba(255,255,255,.7), rgba(255,255,255,0))"),
proxy = $.proxy,
ACTIVE_STATE = "km-state-active",
DragStop = Widget.extend({
init: function (element, options, stop) {
var that = this;
Widget.fn.init.call(that, element, options);
element = that.element;
options = that.options;
that.stop = stop;
that.parent = options.parent;
that.index = options.index;
that.constrain = element.width();
that.snapPoint = that.constrain / 100;
that.point = $("<div class='stop' />").css({
backgroundColor: stop.color.get(),
left: stop.position + "%" || "1px"
})
.prependTo(element);
that.point
.on(kendo.support.mousedown, function () {
that.select(this);
$(this).trigger(click, { originalEvent: { changedTouches: [] } });
});
that.point.data("stop", that);
that.drag = new kendo.UserEvents(that.point, {
global: true,
stopPropagation: true,
tap: function () {
that.drag.cancel();
that.stopped = false;
},
start: proxy(that._start, that),
move: proxy(that._move, that),
end: proxy(that._stop, that)
});
},
options: {
name: "DragStop"
},
updateColor: function(color) {
this.stop.color.set(color.get());
},
select: function(point) {
point = $(point);
point
.siblings(".k-state-selected")
.removeClass("k-state-selected")
.end()
.addClass("k-state-selected");
},
destroy: function() {
var that = this;
that.parent.picker.popup.close();
that.point.remove();
that.stop = undefined;
Widget.fn.destroy.call(that);
},
_move: function(e) {
var that = this, value;
e.preventDefault();
value = that._position(limitValue((e.touch.x.client - that.targetOffsetX), 0, that.constrain));
if (value != that.stop.position) {
if (e.y.initialDelta > 30) {
that.point.css("display", "none");
that.stop.position = -1;
} else {
that.point.css("display", "");
that.stop.position = value;
}
that.parent._updateConnected(that.element, that.index);
}
},
_position: function(position) {
var that = this;
that.position = position;
that.point.css("left", position + "px");
return that.position / that.snapPoint;
},
_start: function() {
var that = this;
that.targetOffsetX = that.element.offset().left;
that.drag.capture();
that.element.addClass(ACTIVE_STATE);
},
_stop: function(e) {
var that = this,
value = that._position(limitValue((e.touch.x.client - that.targetOffsetX), 0, that.constrain));
that.drag.cancel();
that.stopped = true;
that.element.removeClass(ACTIVE_STATE);
if (that.point.is(":visible")) {
that.stop.position = value;
} else {
that.destroy();
}
that.parent._updateConnected(that.element, that.index);
}
}),
GradientPicker = Widget.extend({
init: function (element, options) {
var that = this;
Widget.fn.init.call(that, element, options);
element = that.element;
options = that.options;
if (!options.filter) {
element.addClass("k-sampler");
}
that.bgcolor = new Color(element.css("background-color"));
that.styleengine = options.styleEngine || that.element.parents(".device").data("kendoStyleEngine");
that.popup = new ui.Popup("<div class='k-gradientpick'></div>", {
anchor: element,
origin: "bottom center",
position: "top center",
open: function () {
},
close: function () {
if (that.styleengine) {
var background = { "background-image": that.gradients.get(support.transforms.css) };
background = that.styleengine.mixBackground(background, that.element);
that.styleengine.update(that.element, background);
}
}
});
that.gradients = new Gradient(element.css("background-image"));
that._addRotators();
that.gradientCollection = $("<div class='collection' />").appendTo(that.popup.element);
that._update();
if (!options.filter) {
$(document.body)
.on(click, ".k-sampler", function(e) {
if (e.currentTarget == element[0]) {
e.preventDefault();
that._toggle();
}
});
} else {
$(element)
.on(click, options.filter, function(e) {
if (support.matchesSelector.call(e.currentTarget, options.filter)) {
e.preventDefault();
that.target = $(e.currentTarget);
that.popup.options.anchor = that.target;
that._toggle();
}
});
}
that.popup.element.addClass("k-list-container");
that.picker = that.popup.element
.kendoHSLPicker({ filter: ".stop", pick: proxy(that._pick, that) })
.data("kendoHSLPicker");
},
options: {
name: "GradientPicker",
filter: null,
toggleTarget: null,
styleEngine: null
},
open: function (target) {
if (typeof target != "undefined") {
this.target = target;
}
this._toggle(true);
},
close: function () {
this._toggle(false);
},
_pick: function (e) {
var target = e.target,
index = target.parent().index(".sample");
target.data("stop").updateColor(e.color);
this._updateConnected(target.parent(), index);
},
_updateConnected: function (element, index) {
var that = this,
filter = that.options.filter,
target = !filter ? that.element : that.target,
gradient = that.gradients.get(support.transforms.css);
element.children(".gradient-preview").css("background-image", that.gradients.get(support.transforms.css, index, "left"));
target.css("background-image", gradient).removeClass("k-none");
target.attr("data-gradient", that.styleengine.createHash(JSON.stringify(kendo.getComputedStyles(target[0], [ "background-image", "background-repeat", "background-position" ]))));
},
_addRotators: function () {
var that = this;
$.each( [ "top", "bottom", "right", "left", "top left", "bottom right", "bottom left", "top right" ], function (index, value) {
$("<div class='rotator' style='background-image: " + rotatorGradient.setAngle(0, value).get() + "' title='" + value + "' />").appendTo(that.popup.element);
});
that.popup.element.on(click, ".rotator", function (e) {
var dragStop = that.gradients.value[0].stops[0].dragStop;
that.gradients.setAngle(0, e.currentTarget.title);
that._updateConnected(dragStop.element, dragStop.index);
$(this)
.siblings(".k-state-active")
.removeClass("k-state-active").end()
.addClass("k-state-active");
});
},
_update: function (updateAttr, trigger) {
var that = this,
target = !that.options.filter ? that.element : that.target;
if (target) {
that.popup.element
.find("[title=" + that.gradients.getDirection(0) + "]")
.siblings(".k-state-active")
.removeClass("k-state-active").end()
.addClass("k-state-active");
that.gradientCollection.empty(); // Do Destroy on Picker/s.
that.bgcolor.set(target.css("background-color"));
that.gradients.value.forEach(function (currentValue, index) {
var sample = currentValue.gradientElement = $("<div class='sample'><div class='gradient-preview'></div></div>");
sample
.children(".gradient-preview")
.css({
backgroundColor: that.bgcolor.get(),
backgroundImage: that.gradients.get(support.transforms.css, index, "left")
})
.end()
.on(click, ".gradient-preview", function(e) {
var element = $(this),
touch = kendo.getTouches(e),
position = (touch[0].location.offsetX || touch[0].location.pageX - element.offset().left) / element.outerWidth() * 100,
closestStop = that.gradients.closestStop(position, index),
newStop = {
color: closestStop.color,
position: position
};
currentValue.stops.push(newStop);
newStop.dragStop = new DragStop(this.parentNode, { parent: that, index: index }, newStop);
that._updateConnected(sample, index);
newStop.dragStop.point.trigger(click, { originalEvent: { changedTouches: [] } });
})
.appendTo(that.gradientCollection);
for (var i = currentValue.stops.length-1; i >= 0; i--) {
currentValue.stops[i].dragStop = new DragStop(sample, { parent: that, index: index }, currentValue.stops[i]);
}
});
if (trigger) {
that.trigger("pick", { color: that.color, target: target });
}
}
},
_toggle: function(open) {
var that = this, target, options = that.options;
if (options.filter) {
that.target = that.target || that.element.find(options.filter);
}
target = !options.filter ? that.element : that.target;
open = open !== undefined? open : that.options.filter ? true : !that.popup.visible();
if (open) {
that.gradients.set(target.css("background-image"));
that._update(true);
}
that.popup[open ? "open" : "close"]();
}
});
ui.plugin(GradientPicker);
})(jQuery);