kea-react
Version:
Componentes comunes de react
377 lines (376 loc) • 14.4 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __values = (this && this.__values) || function (o) {
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
};
Object.defineProperty(exports, "__esModule", { value: true });
var React = require("react");
var paperColor = "#f4f4f4";
function mul(a, b) {
return { x: a.x * b, y: a.y * b };
}
function add(a, b) {
return { x: a.x + b.x, y: a.y + b.y };
}
/**Resta 2 vectores */
function sub(a, b) {
return { x: a.x - b.x, y: a.y - b.y };
}
/**Producto punto de dos vectores */
function dot(a, b) {
return a.x * b.x + a.y * b.y;
}
/**Longitud de un vector */
function len(a) {
return Math.sqrt(dot(a, a));
}
function min(a, b) {
return { x: Math.min(a.x, b.x), y: Math.min(a.y, b.y) };
}
function max(a, b) {
return { x: Math.max(a.x, b.x), y: Math.max(a.y, b.y) };
}
function boxFromPoints(points) {
return {
min: points.reduce(min),
max: points.reduce(max)
};
}
function boxFromBoxes(boxes) {
return {
min: boxes.map(function (x) { return x.min; }).reduce(min),
max: boxes.map(function (x) { return x.max; }).reduce(max)
};
}
function signatureWidth(deltaLen) {
return Math.min(Math.round(0.5 + (15 / (deltaLen + 1))), 4);
}
/**Dibuja una linea de una firma */
function drawStroke2(c, a, b) {
var delta = sub(a, b);
var deltaLen = len(delta);
c.lineCap = "round";
c.lineWidth = signatureWidth(deltaLen);
c.beginPath();
c.moveTo(b.x, b.y);
c.lineTo(a.x, a.y);
c.stroke();
}
/**Agrupa un arreglo todos los elementos contiguos que encajen entre si */
function groupByAdjacent(items, isAdjacentGroup) {
if (items.length == 0)
return [];
var ret = [];
var current = [];
try {
for (var items_1 = __values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
var x = items_1_1.value;
if (ret.length == 0 && current.length == 0) {
current.push(x);
}
else {
var last = current[current.length - 1];
if (isAdjacentGroup(last, x)) {
current.push(x);
}
else {
//Agregamos current:
ret.push(current);
current = [x];
}
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
}
finally { if (e_1) throw e_1.error; }
}
ret.push(current);
return ret;
var e_1, _a;
}
/**Dibuja un trazo de una firma */
function drawStroke(c, stroke) {
if (stroke.length < 2)
return;
//Por cada punto agrupamos los anchos:
var widths = stroke
.map(function (x, i, arr) {
var a = arr[i - 1];
var b = x;
var delta = a && sub(a, b);
var deltaLen = a && len(delta);
var width = a && signatureWidth(deltaLen);
return { x: x.x, y: x.y, width: width };
})
.map(function (x, i, arr) { return i == 0 ? Object.assign({}, x, { width: arr[1].width }) : x; });
//Agrupamos por ancho de linea:
var groups = groupByAdjacent(widths, function (a, b) { return a.width == b.width; }).map(function (x) { return ({ width: x[0].width, points: x.map(function (y) { return y; }) }); });
//A cada grupo le pegamos el ultimo punto del grupo anterior:
var groups2 = groups.map(function (x, i, arr) {
if (i == 0)
return x;
else {
var puntosAnt = arr[i - 1].points;
var puntoAnt = puntosAnt[puntosAnt.length - 1];
var nuevosPuntos = [puntoAnt].concat(x.points);
return Object.assign({}, x, { points: nuevosPuntos });
}
});
try {
//Dibuja los grupos
for (var groups2_1 = __values(groups2), groups2_1_1 = groups2_1.next(); !groups2_1_1.done; groups2_1_1 = groups2_1.next()) {
var st = groups2_1_1.value;
c.lineCap = "round";
c.lineWidth = st.width;
c.lineJoin = "round";
c.beginPath();
var points = st.points;
c.moveTo(points[0].x, points[0].y);
for (var i = 1; i < points.length; i++) {
c.lineTo(points[i].x, points[i].y);
}
c.stroke();
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (groups2_1_1 && !groups2_1_1.done && (_a = groups2_1.return)) _a.call(groups2_1);
}
finally { if (e_2) throw e_2.error; }
}
var e_2, _a;
}
function drawStrokes(c, strokes, target) {
if (strokes.length == 0)
return;
if (target) {
//Escalamos la caja para que encaje en target:
var strokeBox_1 = boxFromBoxes(strokes.map(boxFromPoints));
var targetSize = sub(target.max, target.min);
var strokeSize = sub(strokeBox_1.max, strokeBox_1.min);
var scale_1 = Math.min(targetSize.y / strokeSize.y, targetSize.x / strokeSize.x);
var pretransform_1 = function (x) { return add(mul(sub(x, strokeBox_1.min), scale_1), target.min); };
var preTransformStrokeBox = { min: pretransform_1(strokeBox_1.min), max: pretransform_1(strokeBox_1.max) };
var boxCenter = function (box) { return mul(add(box.min, box.max), 0.5); };
var centerTranslate_1 = sub(boxCenter(target), boxCenter(preTransformStrokeBox));
var transform_1 = function (x) { return add(pretransform_1(x), centerTranslate_1); };
var newStroke = strokes.map(function (x) { return x.map(transform_1); });
drawStrokes(c, newStroke);
}
else {
try {
for (var strokes_1 = __values(strokes), strokes_1_1 = strokes_1.next(); !strokes_1_1.done; strokes_1_1 = strokes_1.next()) {
var s = strokes_1_1.value;
drawStroke(c, s);
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (strokes_1_1 && !strokes_1_1.done && (_a = strokes_1.return)) _a.call(strokes_1);
}
finally { if (e_3) throw e_3.error; }
}
}
var e_3, _a;
}
function mouseToVector(source, pageX, pageY) {
var bounding = source.getBoundingClientRect();
var boundingMin = { x: bounding.left, y: bounding.top };
var scroll = { x: window.scrollX, y: window.scrollY };
var offset = add(boundingMin, scroll);
var eventPage = { x: pageX, y: pageY };
return sub(eventPage, offset);
}
var CanvasSignature = /** @class */ (function () {
function CanvasSignature(canvas, onStroke) {
var _this = this;
this.onResize = function () {
_this.context = _this.canvas.getContext("2d");
};
this.lastDownPos = null;
this.currentStroke = [];
this.isReadOnly = false;
this.onTouchStart = function () {
_this.touchDown = true;
};
this.onTouchEnd = function () {
_this.touchDown = false;
_this.onMouseUp();
};
this.onTouchMove = function (event) {
var down = _this.touchDown;
var dibujando = down && !_this.isReadOnly;
if (dibujando) {
//prevenir el scroll en el celular, ocasiona problemas con la firma en android y iphone
event.preventDefault();
}
var touch = event.touches[0];
var pos = mouseToVector(event.srcElement, touch.pageX, touch.pageY);
_this.processMouseMove(down, pos);
};
this.onMouseMove = function (event) {
//Si el mouse esta presionado
var down = event.buttons == 1;
var pos = mouseToVector(event.srcElement, event.pageX, event.pageY);
_this.processMouseMove(down, pos);
};
this.onMouseUp = function () {
if (_this.currentStroke.length > 1) {
_this.onStroke(_this.currentStroke);
}
_this.currentStroke = [];
_this.lastDownPos = null;
};
this.canvas = canvas;
this.onStroke = onStroke;
this.context = canvas.getContext("2d");
this.addEventListeners();
}
CanvasSignature.prototype.addEventListeners = function () {
var c = this.canvas;
c.addEventListener("mouseup", this.onMouseUp);
c.addEventListener("touchend", this.onTouchEnd);
c.addEventListener("touchstart", this.onTouchStart);
c.addEventListener("mousemove", this.onMouseMove);
c.addEventListener("touchmove", this.onTouchMove);
};
CanvasSignature.prototype.removeEventListeners = function () {
var c = this.canvas;
c.removeEventListener("mouseup", this.onMouseUp);
c.removeEventListener("touchend", this.onTouchEnd);
c.removeEventListener("touchstart", this.onTouchStart);
c.removeEventListener("mousemove", this.onMouseMove);
c.removeEventListener("touchmove", this.onTouchMove);
};
CanvasSignature.prototype.processMouseMove = function (down, pos) {
var lastPos = this.lastDownPos;
if (down && !this.isReadOnly) {
this.currentStroke.push(pos);
if (lastPos) {
drawStroke2(this.context, pos, lastPos);
}
this.lastDownPos = pos;
}
else {
this.lastDownPos = null;
}
};
return CanvasSignature;
}());
/**Elemento editor de una firma */
var SignatureCanvas = /** @class */ (function (_super) {
__extends(SignatureCanvas, _super);
function SignatureCanvas() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.handleCanvas = function (canvas) {
if (canvas == null) {
_this.canvas = undefined;
_this.drawer.removeEventListeners();
window.removeEventListener("resize", _this.onResize);
}
else {
_this.canvas = canvas;
_this.setCanvasSize();
_this.drawer = new CanvasSignature(canvas, _this.handleStroke);
_this.refresh(_this.props);
window.addEventListener("resize", _this.onResize);
_this.onResize();
}
};
_this.onResize = function () {
var doResize = function () {
if (_this.setCanvasSize()) {
_this.drawer.onResize();
}
};
var times = [10, 50, 100, 200];
doResize();
try {
for (var times_1 = __values(times), times_1_1 = times_1.next(); !times_1_1.done; times_1_1 = times_1.next()) {
var time = times_1_1.value;
setTimeout(doResize, time);
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (times_1_1 && !times_1_1.done && (_a = times_1.return)) _a.call(times_1);
}
finally { if (e_4) throw e_4.error; }
}
var e_4, _a;
};
_this.handleStroke = function (stroke) {
if (_this.props.onChange) {
_this.props.onChange(_this.props.value.concat([stroke]));
_this.refresh(_this.props);
}
};
return _this;
}
SignatureCanvas.prototype.componentWillUnmount = function () {
window.removeEventListener("resize", this.onResize);
};
SignatureCanvas.prototype.componentWillReceiveProps = function (props) {
this.refresh(props);
};
/**Dibuja los strokes */
SignatureCanvas.prototype.refresh = function (props) {
var strokes = props.value;
if (!this.canvas)
return;
if (this.drawer)
this.drawer.isReadOnly = props.onChange == null;
//Limpia el canvas
var context = this.canvas.getContext("2d");
context.clearRect(0, 0, this.canvas.width, this.canvas.height);
//Dibujamos los strokes:
var margin = 10;
var targetBox = { min: { x: margin, y: margin }, max: { x: this.canvas.width - margin * 2, y: this.canvas.height - margin * 2 } };
drawStrokes(context, strokes, this.props.zoomToFit ? targetBox : undefined);
};
SignatureCanvas.prototype.setCanvasSize = function () {
if (this.canvas) {
var newWidth = this.canvas.offsetWidth;
var newHeight = this.canvas.offsetHeight;
if (this.canvas.width != newWidth || this.canvas.height != newHeight) {
this.canvas.width = newWidth;
this.canvas.height = newHeight;
this.refresh(this.props);
return true;
}
}
return false;
};
SignatureCanvas.prototype.render = function () {
return (React.createElement("canvas", { ref: this.handleCanvas, style: {
background: paperColor,
width: "100%",
height: "100%"
} }));
};
return SignatureCanvas;
}(React.Component));
exports.SignatureCanvas = SignatureCanvas;