-/**
-* This script refer to:
-* Title: Signature Pad
-* Author: szimek
-* Availability: https://github.com/szimek/signature_pad
-**/
-
/**
* @class Roo.bootstrap.BezierSignature
* @extends Roo.bootstrap.Component
* Bootstrap BezierSignature class
- *
+ * This script refer to:
+ * Title: Signature Pad
+ * Author: szimek
+ * Availability: https://github.com/szimek/signature_pad
+ *
* @constructor
* Create a new BezierSignature
* @param {Object} config The config object
});
};
-Roo.extend(Roo.bootstrap.BezierSignature, Roo.bootstrap.Component, {
-
- _data: [],
+Roo.extend(Roo.bootstrap.BezierSignature, Roo.bootstrap.Component,
+{
+
+ curve_data: [],
- _isEmpty: true,
+ is_empty: true,
- _mouseButtonDown: true,
+ mouse_btn_down: true,
/**
- * @cfg(int) canvas height
+ * @cfg {int} canvas height
*/
canvas_height: '200px',
/**
- * @cfg(float or function) Radius of a single dot.
+ * @cfg {float|function} Radius of a single dot.
*/
- dotSize: false,
+ dot_size: false,
/**
- * @cfg(float) Minimum width of a line. Defaults to 0.5.
+ * @cfg {float} Minimum width of a line. Defaults to 0.5.
*/
- minWidth: 0.5,
+ min_width: 0.5,
/**
- * @cfg(float) Maximum width of a line. Defaults to 2.5.
+ * @cfg {float} Maximum width of a line. Defaults to 2.5.
*/
- maxWidth: 2.5,
+ max_width: 2.5,
/**
- * @cfg(integer) Draw the next point at most once per every x milliseconds. Set it to 0 to turn off throttling. Defaults to 16.
+ * @cfg {integer} Draw the next point at most once per every x milliseconds. Set it to 0 to turn off throttling. Defaults to 16.
*/
throttle: 16,
/**
- * @cfg(integer) Add the next point only if the previous one is farther than x pixels. Defaults to 5.
+ * @cfg {integer} Add the next point only if the previous one is farther than x pixels. Defaults to 5.
*/
- minDistance: 5,
+ min_distance: 5,
/**
- * @cfg(string) Color used to clear the background. Can be any color format accepted by context.fillStyle. Defaults to "rgba(0,0,0,0)" (transparent black). Use a non-transparent color e.g. "rgb(255,255,255)" (opaque white) if you'd like to save signatures as JPEG images.
+ * @cfg {string} Color used to clear the background. Can be any color format accepted by context.fillStyle. Defaults to "rgba(0,0,0,0)" (transparent black). Use a non-transparent color e.g. "rgb(255,255,255)" (opaque white) if you'd like to save signatures as JPEG images.
*/
- backgroundColor: 'rgba(0, 0, 0, 0)',
+ bg_color: 'rgba(0, 0, 0, 0)',
/**
- * @cfg(string) Color used to draw the lines. Can be any color format accepted by context.fillStyle. Defaults to "black".
+ * @cfg {string} Color used to draw the lines. Can be any color format accepted by context.fillStyle. Defaults to "black".
*/
- penColor: 'black',
+ dot_color: 'black',
/**
- * @cfg(float) Weight used to modify new velocity based on the previous velocity. Defaults to 0.7.
- */
- velocityFilterWeight: 0.7,
+ * @cfg {float} Weight used to modify new velocity based on the previous velocity. Defaults to 0.7.
+ */
+ velocity_filter_weight: 0.7,
/**
- * @cfg(function) Callback when stroke begin.
+ * @cfg {function} Callback when stroke begin.
*/
onBegin: false,
/**
- * @cfg(function) Callback when stroke end.
+ * @cfg {function} Callback when stroke end.
*/
onEnd: false,
width: this.canvas_width
}
]
+ },
+ {
+ tag: 'input',
+ type: 'file',
+ style: 'display: none'
}
]
};
canvas.dom.style.touchAction = 'none';
canvas.dom.style.msTouchAction = 'none';
- this._mouseButtonDown = false;
+ this.mouse_btn_down = false;
canvas.on('mousedown', this._handleMouseDown, this);
canvas.on('mousemove', this._handleMouseMove, this);
Roo.select('html').first().on('mouseup', this._handleMouseUp, this);
- if (window.ontouchstart) {
+ if (window.PointerEvent) {
+ canvas.on('pointerdown', this._handleMouseDown, this);
+ canvas.on('pointermove', this._handleMouseMove, this);
+ Roo.select('html').first().on('pointerup', this._handleMouseUp, this);
+ }
+
+ if ('ontouchstart' in window) {
canvas.on('touchstart', this._handleTouchStart, this);
canvas.on('touchmove', this._handleTouchMove, this);
canvas.on('touchend', this._handleTouchEnd, this);
}
- if(this.resize_to_parent_width) {
- Roo.EventManager.onWindowResize(this.resize, this, true);
- }
+ Roo.EventManager.onWindowResize(this.resize, this, true);
+
+ // file input event
+ this.fileEl().on('change', this.uploadImage, this);
this.clear();
},
resize: function(){
- this.canvasEl().dom.width = this.el.dom.offsetWidth;
+
+ var canvas = this.canvasEl().dom;
+ var ctx = this.canvasElCtx();
+ var img_data = false;
+
+ if(canvas.width > 0) {
+ var img_data = ctx.getImageData(0, 0, canvas.width, canvas.height);
+ }
+ // setting canvas width will clean img data
+ canvas.width = 0;
+
+ var style = window.getComputedStyle ?
+ getComputedStyle(this.el.dom, null) : this.el.dom.currentStyle;
+
+ var padding_left = parseInt(style.paddingLeft) || 0;
+ var padding_right = parseInt(style.paddingRight) || 0;
+
+ canvas.width = this.el.dom.clientWidth - padding_left - padding_right;
+
+ if(img_data) {
+ ctx.putImageData(img_data, 0, 0);
+ }
},
_handleMouseDown: function(e)
{
if (e.browserEvent.which === 1) {
- this._mouseButtonDown = true;
+ this.mouse_btn_down = true;
this.strokeBegin(e);
}
},
_handleMouseMove: function (e)
{
- if (this._mouseButtonDown) {
+ if (this.mouse_btn_down) {
this.strokeMoveUpdate(e);
}
},
_handleMouseUp: function (e)
{
- if (e.browserEvent.which === 1 && this._mouseButtonDown) {
- this._mouseButtonDown = false;
+ if (e.browserEvent.which === 1 && this.mouse_btn_down) {
+ this.mouse_btn_down = false;
this.strokeEnd(e);
}
},
_handleTouchStart: function (e) {
+
e.preventDefault();
if (e.browserEvent.targetTouches.length === 1) {
// var touch = e.browserEvent.changedTouches[0];
e.preventDefault();
// var touch = event.targetTouches[0];
// _this._strokeMoveUpdate(touch);
- this._strokeMoveUpdate(e);
+ this.strokeMoveUpdate(e);
},
_handleTouchEnd: function (e) {
reset: function () {
this._lastPoints = [];
this._lastVelocity = 0;
- this._lastWidth = (this.minWidth + this.maxWidth) / 2;
- this.canvasElCtx().fillStyle = this.penColor;
+ this._lastWidth = (this.min_width + this.max_width) / 2;
+ this.canvasElCtx().fillStyle = this.dot_color;
},
strokeMoveUpdate: function(e)
this.strokeUpdate(e);
if (this.throttle) {
- this.throttle(this.strokeUpdate, this.throttle);
+ this.throttleStroke(this.strokeUpdate, this.throttle);
}
else {
this.strokeUpdate(e);
strokeBegin: function(e)
{
var newPointGroup = {
- color: this.penColor,
+ color: this.dot_color,
points: []
};
this.onBegin(e);
}
- this._data.push(newPointGroup);
+ this.curve_data.push(newPointGroup);
this.reset();
this.strokeUpdate(e);
},
{
var rect = this.canvasEl().dom.getBoundingClientRect();
var point = new this.Point(e.xy[0] - rect.left, e.xy[1] - rect.top, new Date().getTime());
- var lastPointGroup = this._data[this._data.length - 1];
+ var lastPointGroup = this.curve_data[this.curve_data.length - 1];
var lastPoints = lastPointGroup.points;
var lastPoint = lastPoints.length > 0 && lastPoints[lastPoints.length - 1];
var isLastPointTooClose = lastPoint
- ? point.distanceTo(lastPoint) <= this.minDistance
+ ? point.distanceTo(lastPoint) <= this.min_distance
: false;
var color = lastPointGroup.color;
if (!lastPoint || !(lastPoint && isLastPointTooClose)) {
},
calculateCurveWidths: function (startPoint, endPoint) {
- var velocity = this.velocityFilterWeight * endPoint.velocityFrom(startPoint) +
- (1 - this.velocityFilterWeight) * this._lastVelocity;
+ var velocity = this.velocity_filter_weight * endPoint.velocityFrom(startPoint) +
+ (1 - this.velocity_filter_weight) * this._lastVelocity;
- var newWidth = Math.max(this.maxWidth / (velocity + 1), this.minWidth);
+ var newWidth = Math.max(this.max_width / (velocity + 1), this.min_width);
var widths = {
end: newWidth,
start: this._lastWidth
drawDot: function (_a) {
var color = _a.color, point = _a.point;
var ctx = this.canvasElCtx();
- var width = typeof this.dotSize === 'function' ? this.dotSize() : this.dotSize;
+ var width = typeof this.dot_size === 'function' ? this.dot_size() : this.dot_size;
ctx.beginPath();
this.drawCurveSegment(point.x, point.y, width);
ctx.closePath();
var ctx = this.canvasElCtx();
ctx.moveTo(x, y);
ctx.arc(x, y, width, 0, 2 * Math.PI, false);
- this._isEmpty = false;
+ this.is_empty = false;
},
clear: function()
{
var ctx = this.canvasElCtx();
var canvas = this.canvasEl().dom;
- ctx.fillStyle = this.backgroundColor;
+ ctx.fillStyle = this.bg_color;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(0, 0, canvas.width, canvas.height);
- this._data = [];
+ this.curve_data = [];
this.reset();
- this._isEmpty = true;
+ this.is_empty = true;
+ },
+
+ fileEl: function()
+ {
+ return this.el.select('input',true).first();
},
canvasEl: function()
getImage: function(type)
{
- if(this._isEmpty) {
+ if(this.is_empty) {
return false;
}
// encryption ?
- return this.canvasEl().dom.toDataURL('image/'+type, false);
+ return this.canvasEl().dom.toDataURL('image/'+type, 1);
},
drawFromImage: function(img_src)
{
var img = new Image();
+ img.onload = function(){
+ this.canvasElCtx().drawImage(img, 0, 0);
+ }.bind(this);
+
img.src = img_src;
- this.canvasElCtx().drawImage(img, 0, 0);
+ this.is_empty = false;
+ },
+
+ selectImage: function()
+ {
+ this.fileEl().dom.click();
+ },
+
+ uploadImage: function(e)
+ {
+ var reader = new FileReader();
+
+ reader.onload = function(e){
+ var img = new Image();
+ img.onload = function(){
+ this.reset();
+ this.canvasElCtx().drawImage(img, 0, 0);
+ }.bind(this);
+ img.src = e.target.result;
+ }.bind(this);
+
+ reader.readAsDataURL(e.target.files[0]);
},
// Bezier Point Constructor
return Bezier;
}()),
- throttle: function(fn, wait) {
+ throttleStroke: function(fn, wait) {
if (wait === void 0) { wait = 250; }
var previous = 0;
var timeout = null;