UNPKG

kea-react

Version:

Componentes comunes de react

377 lines (376 loc) 14.4 kB
"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;