Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

angular-canvas-painter

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

angular-canvas-painter - npm Package Compare versions

Comparing version 0.5.2 to 0.5.3

2

bower.json
{
"name": "angular-canvas-painter",
"version": "0.5.2",
"version": "0.5.3",
"authors": [

@@ -5,0 +5,0 @@ "Philipp Wambach"

@@ -0,1 +1,11 @@

<a name="0.5.3"></a>
# 0.5.3 (2015-11-09)
## Bug fixes
- Fix mouseenter/leave problems in firefox (thanks @w3sami)
([#17](https://github.com/pwambach/angular-canvas-painter/pull/20))
- Convert tabs to spaces
<a name="0.5.2"></a>

@@ -2,0 +12,0 @@ # 0.5.2 (2015-10-27)

@@ -37,271 +37,298 @@ /*!

angular.module('pw.canvas-painter')
.directive('pwCanvas', function () {
return {
restrict: 'AE',
scope: {
options: '=',
version: '='
},
templateUrl: '../templates/canvas.html',
link: function postLink(scope, elm) {
.directive('pwCanvas', function() {
return {
restrict: 'AE',
scope: {
options: '=',
version: '='
},
templateUrl: '../templates/canvas.html',
link: function postLink(scope, elm) {
var isTouch = !!('ontouchstart' in window);
var isTouch = !!('ontouchstart' in window);
var PAINT_START = isTouch ? 'touchstart' : 'mousedown';
var PAINT_MOVE = isTouch ? 'touchmove' : 'mousemove';
var PAINT_END = isTouch ? 'touchend' : 'mouseup';
var PAINT_START = isTouch ? 'touchstart' : 'mousedown';
var PAINT_MOVE = isTouch ? 'touchmove' : 'mousemove';
var PAINT_END = isTouch ? 'touchend' : 'mouseup';
//set default options
var options = scope.options;
options.canvasId = options.customCanvasId || 'pwCanvasMain';
options.tmpCanvasId = options.customCanvasId ? (options.canvasId + 'Tmp') : 'pwCanvasTmp';
options.width = options.width || 400;
options.height = options.height || 300;
options.backgroundColor = options.backgroundColor || '#fff';
options.color = options.color || '#000';
options.undoEnabled = options.undoEnabled || false;
options.opacity = options.opacity || 0.9;
options.lineWidth = options.lineWidth || 1;
options.undo = options.undo || false;
options.imageSrc = options.imageSrc || false;
//set default options
var options = scope.options;
options.canvasId = options.customCanvasId || 'pwCanvasMain';
options.tmpCanvasId = options.customCanvasId ? (options.canvasId + 'Tmp') : 'pwCanvasTmp';
options.width = options.width || 400;
options.height = options.height || 300;
options.backgroundColor = options.backgroundColor || '#fff';
options.color = options.color || '#000';
options.undoEnabled = options.undoEnabled || false;
options.opacity = options.opacity || 0.9;
options.lineWidth = options.lineWidth || 1;
options.undo = options.undo || false;
options.imageSrc = options.imageSrc || false;
// background image
if(options.imageSrc){
var image = new Image();
image.onload = function(){
ctx.drawImage(this, 0, 0);
};
image.src = options.imageSrc;
}
// background image
if (options.imageSrc) {
var image = new Image();
image.onload = function() {
ctx.drawImage(this, 0, 0);
};
image.src = options.imageSrc;
}
//undo
if(options.undo){
var undoCache = [];
scope.$watch(function(){
return undoCache.length;
}, function(newVal){
scope.version = newVal;
});
//undo
if (options.undo) {
var undoCache = [];
scope.$watch(function() {
return undoCache.length;
}, function(newVal) {
scope.version = newVal;
});
scope.$watch('version', function(newVal){
if(newVal < 0){
scope.version = 0;
return;
}
if(newVal >= undoCache.length){
scope.version = undoCache.length;
return;
}
undo(newVal);
});
}
scope.$watch('version', function(newVal) {
if (newVal < 0) {
scope.version = 0;
return;
}
if (newVal >= undoCache.length) {
scope.version = undoCache.length;
return;
}
undo(newVal);
});
}
//create canvas and context
var canvas = document.createElement('canvas');
canvas.id = options.canvasId;
var canvasTmp = document.createElement('canvas');
canvasTmp.id = options.tmpCanvasId;
angular.element(canvasTmp).css({
position: 'absolute',
top: 0,
left: 0
});
elm.find('div').append(canvas);
elm.find('div').append(canvasTmp);
var ctx = canvas.getContext('2d');
var ctxTmp = canvasTmp.getContext('2d');
//create canvas and context
var canvas = document.createElement('canvas');
canvas.id = options.canvasId;
var canvasTmp = document.createElement('canvas');
canvasTmp.id = options.tmpCanvasId;
angular.element(canvasTmp).css({
position: 'absolute',
top: 0,
left: 0
});
elm.find('div').append(canvas);
elm.find('div').append(canvasTmp);
var ctx = canvas.getContext('2d');
var ctxTmp = canvasTmp.getContext('2d');
//inti variables
var point = {x: 0, y: 0};
var ppts = [];
//inti variables
var point = {
x: 0,
y: 0
};
var ppts = [];
//set canvas size
canvas.width = canvasTmp.width = options.width;
canvas.height = canvasTmp.height = options.height;
//set canvas size
canvas.width = canvasTmp.width = options.width;
canvas.height = canvasTmp.height = options.height;
//set context style
ctx.fillStyle = options.backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctxTmp.globalAlpha = options.opacity;
ctxTmp.lineJoin = ctxTmp.lineCap = 'round';
ctxTmp.lineWidth = 10;
ctxTmp.strokeStyle = options.color;
//set context style
ctx.fillStyle = options.backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctxTmp.globalAlpha = options.opacity;
ctxTmp.lineJoin = ctxTmp.lineCap = 'round';
ctxTmp.lineWidth = 10;
ctxTmp.strokeStyle = options.color;
//Watch options
scope.$watch('options.lineWidth', function(newValue){
if(typeof newValue === 'string'){
newValue = parseInt(newValue, 10);
}
if(newValue && typeof newValue === 'number'){
ctxTmp.lineWidth = options.lineWidth = newValue;
}
});
//Watch options
scope.$watch('options.lineWidth', function(newValue) {
if (typeof newValue === 'string') {
newValue = parseInt(newValue, 10);
}
if (newValue && typeof newValue === 'number') {
ctxTmp.lineWidth = options.lineWidth = newValue;
}
});
scope.$watch('options.color', function(newValue){
if(newValue){
//ctx.fillStyle = newValue;
ctxTmp.strokeStyle = ctxTmp.fillStyle = newValue;
}
});
scope.$watch('options.color', function(newValue) {
if (newValue) {
//ctx.fillStyle = newValue;
ctxTmp.strokeStyle = ctxTmp.fillStyle = newValue;
}
});
scope.$watch('options.opacity', function(newValue){
if(newValue){
ctxTmp.globalAlpha = newValue;
}
});
scope.$watch('options.opacity', function(newValue) {
if (newValue) {
ctxTmp.globalAlpha = newValue;
}
});
var getOffset = function(elem) {
var offsetTop = 0;
var offsetLeft = 0;
do {
if (!isNaN(elem.offsetLeft)) {
offsetTop += elem.offsetTop;
offsetLeft += elem.offsetLeft;
}
elem = elem.offsetParent;
} while (elem);
return {
left: offsetLeft,
top: offsetTop
};
};
/* var clearCanvas = function(){
ctx.clearRect(0, 0, canvasTmp.width, canvasTmp.height);
ctxTmp.clearRect(0, 0, canvasTmp.width, canvasTmp.height);
};*/
var setPointFromEvent = function(point, e) {
if (isTouch) {
point.x = e.changedTouches[0].pageX - getOffset(e.target).left;
point.y = e.changedTouches[0].pageY - getOffset(e.target).top;
} else {
point.x = e.offsetX !== undefined ? e.offsetX : e.layerX;
point.y = e.offsetY !== undefined ? e.offsetY : e.layerY;
}
};
var getOffset = function( elem ) {
var offsetTop = 0;
var offsetLeft = 0;
do {
if ( !isNaN( elem.offsetLeft ) )
{
offsetTop += elem.offsetTop;
offsetLeft += elem.offsetLeft;
}
elem = elem.offsetParent;
} while( elem );
return {
left:offsetLeft,
top: offsetTop
};
};
var setPointFromEvent = function(point, e) {
if(isTouch){
point.x = e.changedTouches[0].pageX - getOffset(e.target).left;
point.y = e.changedTouches[0].pageY - getOffset(e.target).top;
} else {
point.x = e.offsetX !== undefined ? e.offsetX : e.layerX;
point.y = e.offsetY !== undefined ? e.offsetY : e.layerY;
}
};
var paint = function(e) {
if (e) {
e.preventDefault();
setPointFromEvent(point, e);
}
// Saving all the points in an array
ppts.push({
x: point.x,
y: point.y
});
var paint = function (e){
if(e){
e.preventDefault();
setPointFromEvent(point, e);
}
if (ppts.length === 3) {
var b = ppts[0];
ctxTmp.beginPath();
ctxTmp.arc(b.x, b.y, ctxTmp.lineWidth / 2, 0, Math.PI * 2, !0);
ctxTmp.fill();
ctxTmp.closePath();
return;
}
// Saving all the points in an array
ppts.push({x: point.x, y: point.y});
// Tmp canvas is always cleared up before drawing.
ctxTmp.clearRect(0, 0, canvasTmp.width, canvasTmp.height);
if (ppts.length === 3) {
var b = ppts[0];
ctxTmp.beginPath();
ctxTmp.arc(b.x, b.y, ctxTmp.lineWidth / 2, 0, Math.PI * 2, !0);
ctxTmp.fill();
ctxTmp.closePath();
return;
}
ctxTmp.beginPath();
ctxTmp.moveTo(ppts[0].x, ppts[0].y);
// Tmp canvas is always cleared up before drawing.
ctxTmp.clearRect(0, 0, canvasTmp.width, canvasTmp.height);
for (var i = 1; i < ppts.length - 2; i++) {
var c = (ppts[i].x + ppts[i + 1].x) / 2;
var d = (ppts[i].y + ppts[i + 1].y) / 2;
ctxTmp.quadraticCurveTo(ppts[i].x, ppts[i].y, c, d);
}
ctxTmp.beginPath();
ctxTmp.moveTo(ppts[0].x, ppts[0].y);
// For the last 2 points
ctxTmp.quadraticCurveTo(
ppts[i].x,
ppts[i].y,
ppts[i + 1].x,
ppts[i + 1].y
);
ctxTmp.stroke();
};
for (var i = 1; i < ppts.length - 2; i++) {
var c = (ppts[i].x + ppts[i + 1].x) / 2;
var d = (ppts[i].y + ppts[i + 1].y) / 2;
ctxTmp.quadraticCurveTo(ppts[i].x, ppts[i].y, c, d);
}
var copyTmpImage = function() {
if (options.undo) {
scope.$apply(function() {
undoCache.push(ctx.getImageData(0, 0, canvasTmp.width, canvasTmp.height));
if (angular.isNumber(options.undo) && options.undo > 0) {
undoCache = undoCache.slice(-1 * options.undo);
}
});
}
canvasTmp.removeEventListener(PAINT_MOVE, paint, false);
ctx.drawImage(canvasTmp, 0, 0);
ctxTmp.clearRect(0, 0, canvasTmp.width, canvasTmp.height);
ppts = [];
};
// For the last 2 points
ctxTmp.quadraticCurveTo(
ppts[i].x,
ppts[i].y,
ppts[i + 1].x,
ppts[i + 1].y
);
ctxTmp.stroke();
};
var startTmpImage = function(e) {
e.preventDefault();
canvasTmp.addEventListener(PAINT_MOVE, paint, false);
var copyTmpImage = function(){
if(options.undo){
scope.$apply(function(){
undoCache.push(ctx.getImageData(0, 0, canvasTmp.width, canvasTmp.height));
if(angular.isNumber(options.undo) && options.undo > 0){
undoCache = undoCache.slice(-1 * options.undo);
}
});
}
canvasTmp.removeEventListener(PAINT_MOVE, paint, false);
ctx.drawImage(canvasTmp, 0, 0);
ctxTmp.clearRect(0, 0, canvasTmp.width, canvasTmp.height);
ppts = [];
};
setPointFromEvent(point, e);
ppts.push({
x: point.x,
y: point.y
});
ppts.push({
x: point.x,
y: point.y
});
var startTmpImage = function(e){
e.preventDefault();
canvasTmp.addEventListener(PAINT_MOVE, paint, false);
paint();
};
setPointFromEvent(point, e);
ppts.push({x: point.x, y: point.y});
ppts.push({x: point.x, y: point.y});
var initListeners = function() {
canvasTmp.addEventListener(PAINT_START, startTmpImage, false);
canvasTmp.addEventListener(PAINT_END, copyTmpImage, false);
paint();
};
if (!isTouch) {
var MOUSE_DOWN;
var initListeners = function(){
canvasTmp.addEventListener(PAINT_START, startTmpImage, false);
canvasTmp.addEventListener(PAINT_END, copyTmpImage, false);
document.body.addEventListener('mousedown', mousedown);
document.body.addEventListener('mouseup', mouseup);
if(!isTouch){
canvasTmp.addEventListener('mouseenter', function(e){
// If the mouse is down when it enters the canvas, start a path
if(e.which === 1){
startTmpImage(e);
}
}, false);
canvasTmp.addEventListener('mouseleave', function(e){
// If the mouse is down when it leaves the canvas, end the path
if(e.which === 1){
copyTmpImage(e);
}
}, false);
}
};
initListeners();
scope.$on('$destroy', removeEventListeners);
canvasTmp.addEventListener('mouseenter', mouseenter);
canvasTmp.addEventListener('mouseleave', mouseleave);
}
function mousedown() {
MOUSE_DOWN = true;
}
var undo = function(version){
if(undoCache.length > 0){
ctx.putImageData(undoCache[version], 0, 0);
undoCache = undoCache.slice(0,version);
}
};
function mouseup() {
MOUSE_DOWN = false;
}
}
};
});
function removeEventListeners() {
document.body.removeEventListener('mousedown', mousedown);
document.body.removeEventListener('mouseup', mouseup);
}
function mouseenter(e) {
// If the mouse is down when it enters the canvas, start a path
if (MOUSE_DOWN) {
startTmpImage(e);
}
}
function mouseleave(e) {
// If the mouse is down when it leaves the canvas, end the path
if (MOUSE_DOWN) {
copyTmpImage(e);
}
}
};
var undo = function(version) {
if (undoCache.length > 0) {
ctx.putImageData(undoCache[version], 0, 0);
undoCache = undoCache.slice(0, version);
}
};
initListeners();
}
};
});
angular.module('pw.canvas-painter')
.directive('pwColorSelector', function () {
return {
restrict: 'AE',
scope: {
colorList: '=pwColorSelector',
selectedColor: '=color'
},
templateUrl: '../templates/color-selector.html',
link: function(scope){
scope.setColor = function(col){
scope.selectedColor = col;
};
}
};
});
.directive('pwColorSelector', function () {
return {
restrict: 'AE',
scope: {
colorList: '=pwColorSelector',
selectedColor: '=color'
},
templateUrl: '../templates/color-selector.html',
link: function(scope){
scope.setColor = function(col){
scope.selectedColor = col;
};
}
};
});
}(this));

@@ -1,1 +0,1 @@

"use strict";!function(t){angular.module("pw.canvas-painter",[]),function(t){try{t=angular.module("pw.canvas-painter")}catch(e){t=angular.module("pw.canvas-painter",[])}t.run(["$templateCache",function(t){t.put("../templates/canvas.html",'<div class="pwCanvasPaint" style="position:relative"></div>')}])}(),function(t){try{t=angular.module("pw.canvas-painter")}catch(e){t=angular.module("pw.canvas-painter",[])}t.run(["$templateCache",function(t){t.put("../templates/color-selector.html",'<ul class="pwColorSelector"><li ng-repeat="color in colorList track by $index" class="pwColor" ng-class="{\'active\': (selectedColor === color)}" ng-style="{\'background-color\':color}" ng-click="setColor(color)"></li></ul>')}])}(),angular.module("pw.canvas-painter").directive("pwCanvas",function(){return{restrict:"AE",scope:{options:"=",version:"="},templateUrl:"../templates/canvas.html",link:function(e,n){var o=!!("ontouchstart"in t),a=o?"touchstart":"mousedown",i=o?"touchmove":"mousemove",r=o?"touchend":"mouseup",l=e.options;if(l.canvasId=l.customCanvasId||"pwCanvasMain",l.tmpCanvasId=l.customCanvasId?l.canvasId+"Tmp":"pwCanvasTmp",l.width=l.width||400,l.height=l.height||300,l.backgroundColor=l.backgroundColor||"#fff",l.color=l.color||"#000",l.undoEnabled=l.undoEnabled||!1,l.opacity=l.opacity||.9,l.lineWidth=l.lineWidth||1,l.undo=l.undo||!1,l.imageSrc=l.imageSrc||!1,l.imageSrc){var c=new Image;c.onload=function(){h.drawImage(this,0,0)},c.src=l.imageSrc}if(l.undo){var s=[];e.$watch(function(){return s.length},function(t){e.version=t}),e.$watch("version",function(t){return 0>t?(e.version=0,void 0):t>=s.length?(e.version=s.length,void 0):(b(t),void 0)})}var u=document.createElement("canvas");u.id=l.canvasId;var d=document.createElement("canvas");d.id=l.tmpCanvasId,angular.element(d).css({position:"absolute",top:0,left:0}),n.find("div").append(u),n.find("div").append(d);var h=u.getContext("2d"),p=d.getContext("2d"),v={x:0,y:0},f=[];u.width=d.width=l.width,u.height=d.height=l.height,h.fillStyle=l.backgroundColor,h.fillRect(0,0,u.width,u.height),p.globalAlpha=l.opacity,p.lineJoin=p.lineCap="round",p.lineWidth=10,p.strokeStyle=l.color,e.$watch("options.lineWidth",function(t){"string"==typeof t&&(t=parseInt(t,10)),t&&"number"==typeof t&&(p.lineWidth=l.lineWidth=t)}),e.$watch("options.color",function(t){t&&(p.strokeStyle=p.fillStyle=t)}),e.$watch("options.opacity",function(t){t&&(p.globalAlpha=t)});var g=function(t){var e=0,n=0;do isNaN(t.offsetLeft)||(e+=t.offsetTop,n+=t.offsetLeft),t=t.offsetParent;while(t);return{left:n,top:e}},m=function(t,e){o?(t.x=e.changedTouches[0].pageX-g(e.target).left,t.y=e.changedTouches[0].pageY-g(e.target).top):(t.x=void 0!==e.offsetX?e.offsetX:e.layerX,t.y=void 0!==e.offsetY?e.offsetY:e.layerY)},w=function(t){if(t&&(t.preventDefault(),m(v,t)),f.push({x:v.x,y:v.y}),3===f.length){var e=f[0];return p.beginPath(),p.arc(e.x,e.y,p.lineWidth/2,0,2*Math.PI,!0),p.fill(),p.closePath(),void 0}p.clearRect(0,0,d.width,d.height),p.beginPath(),p.moveTo(f[0].x,f[0].y);for(var n=1;n<f.length-2;n++){var o=(f[n].x+f[n+1].x)/2,a=(f[n].y+f[n+1].y)/2;p.quadraticCurveTo(f[n].x,f[n].y,o,a)}p.quadraticCurveTo(f[n].x,f[n].y,f[n+1].x,f[n+1].y),p.stroke()},y=function(){l.undo&&e.$apply(function(){s.push(h.getImageData(0,0,d.width,d.height)),angular.isNumber(l.undo)&&l.undo>0&&(s=s.slice(-1*l.undo))}),d.removeEventListener(i,w,!1),h.drawImage(d,0,0),p.clearRect(0,0,d.width,d.height),f=[]},C=function(t){t.preventDefault(),d.addEventListener(i,w,!1),m(v,t),f.push({x:v.x,y:v.y}),f.push({x:v.x,y:v.y}),w()},x=function(){d.addEventListener(a,C,!1),d.addEventListener(r,y,!1),o||(d.addEventListener("mouseenter",function(t){1===t.which&&C(t)},!1),d.addEventListener("mouseleave",function(t){1===t.which&&y(t)},!1))};x();var b=function(t){s.length>0&&(h.putImageData(s[t],0,0),s=s.slice(0,t))}}}}),angular.module("pw.canvas-painter").directive("pwColorSelector",function(){return{restrict:"AE",scope:{colorList:"=pwColorSelector",selectedColor:"=color"},templateUrl:"../templates/color-selector.html",link:function(t){t.setColor=function(e){t.selectedColor=e}}}})}(this);
"use strict";!function(e){angular.module("pw.canvas-painter",[]),function(e){try{e=angular.module("pw.canvas-painter")}catch(t){e=angular.module("pw.canvas-painter",[])}e.run(["$templateCache",function(e){e.put("../templates/canvas.html",'<div class="pwCanvasPaint" style="position:relative"></div>')}])}(),function(e){try{e=angular.module("pw.canvas-painter")}catch(t){e=angular.module("pw.canvas-painter",[])}e.run(["$templateCache",function(e){e.put("../templates/color-selector.html",'<ul class="pwColorSelector"><li ng-repeat="color in colorList track by $index" class="pwColor" ng-class="{\'active\': (selectedColor === color)}" ng-style="{\'background-color\':color}" ng-click="setColor(color)"></li></ul>')}])}(),angular.module("pw.canvas-painter").directive("pwCanvas",function(){return{restrict:"AE",scope:{options:"=",version:"="},templateUrl:"../templates/canvas.html",link:function(t,n){var o=!!("ontouchstart"in e),a=o?"touchstart":"mousedown",i=o?"touchmove":"mousemove",r=o?"touchend":"mouseup",c=t.options;if(c.canvasId=c.customCanvasId||"pwCanvasMain",c.tmpCanvasId=c.customCanvasId?c.canvasId+"Tmp":"pwCanvasTmp",c.width=c.width||400,c.height=c.height||300,c.backgroundColor=c.backgroundColor||"#fff",c.color=c.color||"#000",c.undoEnabled=c.undoEnabled||!1,c.opacity=c.opacity||.9,c.lineWidth=c.lineWidth||1,c.undo=c.undo||!1,c.imageSrc=c.imageSrc||!1,c.imageSrc){var l=new Image;l.onload=function(){p.drawImage(this,0,0)},l.src=c.imageSrc}if(c.undo){var s=[];t.$watch(function(){return s.length},function(e){t.version=e}),t.$watch("version",function(e){return 0>e?(t.version=0,void 0):e>=s.length?(t.version=s.length,void 0):(b(e),void 0)})}var u=document.createElement("canvas");u.id=c.canvasId;var d=document.createElement("canvas");d.id=c.tmpCanvasId,angular.element(d).css({position:"absolute",top:0,left:0}),n.find("div").append(u),n.find("div").append(d);var p=u.getContext("2d"),h=d.getContext("2d"),v={x:0,y:0},f=[];u.width=d.width=c.width,u.height=d.height=c.height,p.fillStyle=c.backgroundColor,p.fillRect(0,0,u.width,u.height),h.globalAlpha=c.opacity,h.lineJoin=h.lineCap="round",h.lineWidth=10,h.strokeStyle=c.color,t.$watch("options.lineWidth",function(e){"string"==typeof e&&(e=parseInt(e,10)),e&&"number"==typeof e&&(h.lineWidth=c.lineWidth=e)}),t.$watch("options.color",function(e){e&&(h.strokeStyle=h.fillStyle=e)}),t.$watch("options.opacity",function(e){e&&(h.globalAlpha=e)});var m=function(e){var t=0,n=0;do isNaN(e.offsetLeft)||(t+=e.offsetTop,n+=e.offsetLeft),e=e.offsetParent;while(e);return{left:n,top:t}},g=function(e,t){o?(e.x=t.changedTouches[0].pageX-m(t.target).left,e.y=t.changedTouches[0].pageY-m(t.target).top):(e.x=void 0!==t.offsetX?t.offsetX:t.layerX,e.y=void 0!==t.offsetY?t.offsetY:t.layerY)},y=function(e){if(e&&(e.preventDefault(),g(v,e)),f.push({x:v.x,y:v.y}),3===f.length){var t=f[0];return h.beginPath(),h.arc(t.x,t.y,h.lineWidth/2,0,2*Math.PI,!0),h.fill(),h.closePath(),void 0}h.clearRect(0,0,d.width,d.height),h.beginPath(),h.moveTo(f[0].x,f[0].y);for(var n=1;n<f.length-2;n++){var o=(f[n].x+f[n+1].x)/2,a=(f[n].y+f[n+1].y)/2;h.quadraticCurveTo(f[n].x,f[n].y,o,a)}h.quadraticCurveTo(f[n].x,f[n].y,f[n+1].x,f[n+1].y),h.stroke()},w=function(){c.undo&&t.$apply(function(){s.push(p.getImageData(0,0,d.width,d.height)),angular.isNumber(c.undo)&&c.undo>0&&(s=s.slice(-1*c.undo))}),d.removeEventListener(i,y,!1),p.drawImage(d,0,0),h.clearRect(0,0,d.width,d.height),f=[]},C=function(e){e.preventDefault(),d.addEventListener(i,y,!1),g(v,e),f.push({x:v.x,y:v.y}),f.push({x:v.x,y:v.y}),y()},x=function(){function e(){s=!0}function n(){s=!1}function i(){document.body.removeEventListener("mousedown",e),document.body.removeEventListener("mouseup",n)}function c(e){s&&C(e)}function l(e){s&&w(e)}if(d.addEventListener(a,C,!1),d.addEventListener(r,w,!1),!o){var s;document.body.addEventListener("mousedown",e),document.body.addEventListener("mouseup",n),t.$on("$destroy",i),d.addEventListener("mouseenter",c),d.addEventListener("mouseleave",l)}},b=function(e){s.length>0&&(p.putImageData(s[e],0,0),s=s.slice(0,e))};x()}}}),angular.module("pw.canvas-painter").directive("pwColorSelector",function(){return{restrict:"AE",scope:{colorList:"=pwColorSelector",selectedColor:"=color"},templateUrl:"../templates/color-selector.html",link:function(e){e.setColor=function(t){e.selectedColor=t}}}})}(this);
'use strict';
angular.module('pw.canvas-painter')
.directive('pwCanvas', function () {
return {
restrict: 'AE',
scope: {
options: '=',
version: '='
},
templateUrl: '../templates/canvas.html',
link: function postLink(scope, elm) {
.directive('pwCanvas', function() {
return {
restrict: 'AE',
scope: {
options: '=',
version: '='
},
templateUrl: '../templates/canvas.html',
link: function postLink(scope, elm) {
var isTouch = !!('ontouchstart' in window);
var isTouch = !!('ontouchstart' in window);
var PAINT_START = isTouch ? 'touchstart' : 'mousedown';
var PAINT_MOVE = isTouch ? 'touchmove' : 'mousemove';
var PAINT_END = isTouch ? 'touchend' : 'mouseup';
var PAINT_START = isTouch ? 'touchstart' : 'mousedown';
var PAINT_MOVE = isTouch ? 'touchmove' : 'mousemove';
var PAINT_END = isTouch ? 'touchend' : 'mouseup';
//set default options
var options = scope.options;
options.canvasId = options.customCanvasId || 'pwCanvasMain';
options.tmpCanvasId = options.customCanvasId ? (options.canvasId + 'Tmp') : 'pwCanvasTmp';
options.width = options.width || 400;
options.height = options.height || 300;
options.backgroundColor = options.backgroundColor || '#fff';
options.color = options.color || '#000';
options.undoEnabled = options.undoEnabled || false;
options.opacity = options.opacity || 0.9;
options.lineWidth = options.lineWidth || 1;
options.undo = options.undo || false;
options.imageSrc = options.imageSrc || false;
//set default options
var options = scope.options;
options.canvasId = options.customCanvasId || 'pwCanvasMain';
options.tmpCanvasId = options.customCanvasId ? (options.canvasId + 'Tmp') : 'pwCanvasTmp';
options.width = options.width || 400;
options.height = options.height || 300;
options.backgroundColor = options.backgroundColor || '#fff';
options.color = options.color || '#000';
options.undoEnabled = options.undoEnabled || false;
options.opacity = options.opacity || 0.9;
options.lineWidth = options.lineWidth || 1;
options.undo = options.undo || false;
options.imageSrc = options.imageSrc || false;
// background image
if(options.imageSrc){
var image = new Image();
image.onload = function(){
ctx.drawImage(this, 0, 0);
};
image.src = options.imageSrc;
}
// background image
if (options.imageSrc) {
var image = new Image();
image.onload = function() {
ctx.drawImage(this, 0, 0);
};
image.src = options.imageSrc;
}
//undo
if(options.undo){
var undoCache = [];
scope.$watch(function(){
return undoCache.length;
}, function(newVal){
scope.version = newVal;
});
//undo
if (options.undo) {
var undoCache = [];
scope.$watch(function() {
return undoCache.length;
}, function(newVal) {
scope.version = newVal;
});
scope.$watch('version', function(newVal){
if(newVal < 0){
scope.version = 0;
return;
}
if(newVal >= undoCache.length){
scope.version = undoCache.length;
return;
}
undo(newVal);
});
}
scope.$watch('version', function(newVal) {
if (newVal < 0) {
scope.version = 0;
return;
}
if (newVal >= undoCache.length) {
scope.version = undoCache.length;
return;
}
undo(newVal);
});
}
//create canvas and context
var canvas = document.createElement('canvas');
canvas.id = options.canvasId;
var canvasTmp = document.createElement('canvas');
canvasTmp.id = options.tmpCanvasId;
angular.element(canvasTmp).css({
position: 'absolute',
top: 0,
left: 0
});
elm.find('div').append(canvas);
elm.find('div').append(canvasTmp);
var ctx = canvas.getContext('2d');
var ctxTmp = canvasTmp.getContext('2d');
//create canvas and context
var canvas = document.createElement('canvas');
canvas.id = options.canvasId;
var canvasTmp = document.createElement('canvas');
canvasTmp.id = options.tmpCanvasId;
angular.element(canvasTmp).css({
position: 'absolute',
top: 0,
left: 0
});
elm.find('div').append(canvas);
elm.find('div').append(canvasTmp);
var ctx = canvas.getContext('2d');
var ctxTmp = canvasTmp.getContext('2d');
//inti variables
var point = {x: 0, y: 0};
var ppts = [];
//inti variables
var point = {
x: 0,
y: 0
};
var ppts = [];
//set canvas size
canvas.width = canvasTmp.width = options.width;
canvas.height = canvasTmp.height = options.height;
//set canvas size
canvas.width = canvasTmp.width = options.width;
canvas.height = canvasTmp.height = options.height;
//set context style
ctx.fillStyle = options.backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctxTmp.globalAlpha = options.opacity;
ctxTmp.lineJoin = ctxTmp.lineCap = 'round';
ctxTmp.lineWidth = 10;
ctxTmp.strokeStyle = options.color;
//set context style
ctx.fillStyle = options.backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctxTmp.globalAlpha = options.opacity;
ctxTmp.lineJoin = ctxTmp.lineCap = 'round';
ctxTmp.lineWidth = 10;
ctxTmp.strokeStyle = options.color;
//Watch options
scope.$watch('options.lineWidth', function(newValue){
if(typeof newValue === 'string'){
newValue = parseInt(newValue, 10);
}
if(newValue && typeof newValue === 'number'){
ctxTmp.lineWidth = options.lineWidth = newValue;
}
});
//Watch options
scope.$watch('options.lineWidth', function(newValue) {
if (typeof newValue === 'string') {
newValue = parseInt(newValue, 10);
}
if (newValue && typeof newValue === 'number') {
ctxTmp.lineWidth = options.lineWidth = newValue;
}
});
scope.$watch('options.color', function(newValue){
if(newValue){
//ctx.fillStyle = newValue;
ctxTmp.strokeStyle = ctxTmp.fillStyle = newValue;
}
});
scope.$watch('options.color', function(newValue) {
if (newValue) {
//ctx.fillStyle = newValue;
ctxTmp.strokeStyle = ctxTmp.fillStyle = newValue;
}
});
scope.$watch('options.opacity', function(newValue){
if(newValue){
ctxTmp.globalAlpha = newValue;
}
});
scope.$watch('options.opacity', function(newValue) {
if (newValue) {
ctxTmp.globalAlpha = newValue;
}
});
var getOffset = function(elem) {
var offsetTop = 0;
var offsetLeft = 0;
do {
if (!isNaN(elem.offsetLeft)) {
offsetTop += elem.offsetTop;
offsetLeft += elem.offsetLeft;
}
elem = elem.offsetParent;
} while (elem);
return {
left: offsetLeft,
top: offsetTop
};
};
/* var clearCanvas = function(){
ctx.clearRect(0, 0, canvasTmp.width, canvasTmp.height);
ctxTmp.clearRect(0, 0, canvasTmp.width, canvasTmp.height);
};*/
var setPointFromEvent = function(point, e) {
if (isTouch) {
point.x = e.changedTouches[0].pageX - getOffset(e.target).left;
point.y = e.changedTouches[0].pageY - getOffset(e.target).top;
} else {
point.x = e.offsetX !== undefined ? e.offsetX : e.layerX;
point.y = e.offsetY !== undefined ? e.offsetY : e.layerY;
}
};
var getOffset = function( elem ) {
var offsetTop = 0;
var offsetLeft = 0;
do {
if ( !isNaN( elem.offsetLeft ) )
{
offsetTop += elem.offsetTop;
offsetLeft += elem.offsetLeft;
}
elem = elem.offsetParent;
} while( elem );
return {
left:offsetLeft,
top: offsetTop
};
};
var setPointFromEvent = function(point, e) {
if(isTouch){
point.x = e.changedTouches[0].pageX - getOffset(e.target).left;
point.y = e.changedTouches[0].pageY - getOffset(e.target).top;
} else {
point.x = e.offsetX !== undefined ? e.offsetX : e.layerX;
point.y = e.offsetY !== undefined ? e.offsetY : e.layerY;
}
};
var paint = function(e) {
if (e) {
e.preventDefault();
setPointFromEvent(point, e);
}
// Saving all the points in an array
ppts.push({
x: point.x,
y: point.y
});
var paint = function (e){
if(e){
e.preventDefault();
setPointFromEvent(point, e);
}
if (ppts.length === 3) {
var b = ppts[0];
ctxTmp.beginPath();
ctxTmp.arc(b.x, b.y, ctxTmp.lineWidth / 2, 0, Math.PI * 2, !0);
ctxTmp.fill();
ctxTmp.closePath();
return;
}
// Saving all the points in an array
ppts.push({x: point.x, y: point.y});
// Tmp canvas is always cleared up before drawing.
ctxTmp.clearRect(0, 0, canvasTmp.width, canvasTmp.height);
if (ppts.length === 3) {
var b = ppts[0];
ctxTmp.beginPath();
ctxTmp.arc(b.x, b.y, ctxTmp.lineWidth / 2, 0, Math.PI * 2, !0);
ctxTmp.fill();
ctxTmp.closePath();
return;
}
ctxTmp.beginPath();
ctxTmp.moveTo(ppts[0].x, ppts[0].y);
// Tmp canvas is always cleared up before drawing.
ctxTmp.clearRect(0, 0, canvasTmp.width, canvasTmp.height);
for (var i = 1; i < ppts.length - 2; i++) {
var c = (ppts[i].x + ppts[i + 1].x) / 2;
var d = (ppts[i].y + ppts[i + 1].y) / 2;
ctxTmp.quadraticCurveTo(ppts[i].x, ppts[i].y, c, d);
}
ctxTmp.beginPath();
ctxTmp.moveTo(ppts[0].x, ppts[0].y);
// For the last 2 points
ctxTmp.quadraticCurveTo(
ppts[i].x,
ppts[i].y,
ppts[i + 1].x,
ppts[i + 1].y
);
ctxTmp.stroke();
};
for (var i = 1; i < ppts.length - 2; i++) {
var c = (ppts[i].x + ppts[i + 1].x) / 2;
var d = (ppts[i].y + ppts[i + 1].y) / 2;
ctxTmp.quadraticCurveTo(ppts[i].x, ppts[i].y, c, d);
}
var copyTmpImage = function() {
if (options.undo) {
scope.$apply(function() {
undoCache.push(ctx.getImageData(0, 0, canvasTmp.width, canvasTmp.height));
if (angular.isNumber(options.undo) && options.undo > 0) {
undoCache = undoCache.slice(-1 * options.undo);
}
});
}
canvasTmp.removeEventListener(PAINT_MOVE, paint, false);
ctx.drawImage(canvasTmp, 0, 0);
ctxTmp.clearRect(0, 0, canvasTmp.width, canvasTmp.height);
ppts = [];
};
// For the last 2 points
ctxTmp.quadraticCurveTo(
ppts[i].x,
ppts[i].y,
ppts[i + 1].x,
ppts[i + 1].y
);
ctxTmp.stroke();
};
var startTmpImage = function(e) {
e.preventDefault();
canvasTmp.addEventListener(PAINT_MOVE, paint, false);
var copyTmpImage = function(){
if(options.undo){
scope.$apply(function(){
undoCache.push(ctx.getImageData(0, 0, canvasTmp.width, canvasTmp.height));
if(angular.isNumber(options.undo) && options.undo > 0){
undoCache = undoCache.slice(-1 * options.undo);
}
});
}
canvasTmp.removeEventListener(PAINT_MOVE, paint, false);
ctx.drawImage(canvasTmp, 0, 0);
ctxTmp.clearRect(0, 0, canvasTmp.width, canvasTmp.height);
ppts = [];
};
setPointFromEvent(point, e);
ppts.push({
x: point.x,
y: point.y
});
ppts.push({
x: point.x,
y: point.y
});
var startTmpImage = function(e){
e.preventDefault();
canvasTmp.addEventListener(PAINT_MOVE, paint, false);
paint();
};
setPointFromEvent(point, e);
ppts.push({x: point.x, y: point.y});
ppts.push({x: point.x, y: point.y});
var initListeners = function() {
canvasTmp.addEventListener(PAINT_START, startTmpImage, false);
canvasTmp.addEventListener(PAINT_END, copyTmpImage, false);
paint();
};
if (!isTouch) {
var MOUSE_DOWN;
var initListeners = function(){
canvasTmp.addEventListener(PAINT_START, startTmpImage, false);
canvasTmp.addEventListener(PAINT_END, copyTmpImage, false);
document.body.addEventListener('mousedown', mousedown);
document.body.addEventListener('mouseup', mouseup);
if(!isTouch){
canvasTmp.addEventListener('mouseenter', function(e){
// If the mouse is down when it enters the canvas, start a path
if(e.which === 1){
startTmpImage(e);
}
}, false);
canvasTmp.addEventListener('mouseleave', function(e){
// If the mouse is down when it leaves the canvas, end the path
if(e.which === 1){
copyTmpImage(e);
}
}, false);
}
};
initListeners();
scope.$on('$destroy', removeEventListeners);
canvasTmp.addEventListener('mouseenter', mouseenter);
canvasTmp.addEventListener('mouseleave', mouseleave);
}
function mousedown() {
MOUSE_DOWN = true;
}
var undo = function(version){
if(undoCache.length > 0){
ctx.putImageData(undoCache[version], 0, 0);
undoCache = undoCache.slice(0,version);
}
};
function mouseup() {
MOUSE_DOWN = false;
}
}
};
});
function removeEventListeners() {
document.body.removeEventListener('mousedown', mousedown);
document.body.removeEventListener('mouseup', mouseup);
}
function mouseenter(e) {
// If the mouse is down when it enters the canvas, start a path
if (MOUSE_DOWN) {
startTmpImage(e);
}
}
function mouseleave(e) {
// If the mouse is down when it leaves the canvas, end the path
if (MOUSE_DOWN) {
copyTmpImage(e);
}
}
};
var undo = function(version) {
if (undoCache.length > 0) {
ctx.putImageData(undoCache[version], 0, 0);
undoCache = undoCache.slice(0, version);
}
};
initListeners();
}
};
});
'use strict';
angular.module('pw.canvas-painter')
.directive('pwColorSelector', function () {
return {
restrict: 'AE',
scope: {
colorList: '=pwColorSelector',
selectedColor: '=color'
},
templateUrl: '../templates/color-selector.html',
link: function(scope){
scope.setColor = function(col){
scope.selectedColor = col;
};
}
};
});
.directive('pwColorSelector', function () {
return {
restrict: 'AE',
scope: {
colorList: '=pwColorSelector',
selectedColor: '=color'
},
templateUrl: '../templates/color-selector.html',
link: function(scope){
scope.setColor = function(col){
scope.selectedColor = col;
};
}
};
});
{
"name": "angular-canvas-painter",
"version": "0.5.2",
"version": "0.5.3",
"description": "Angular.js directive to paint on a canvas on desktop or touch devices",

@@ -5,0 +5,0 @@ "main": "dist/angular-canvas-painter.min.js",

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc