diff --git a/css/main.less b/css/main.less
index 15b4769..a6fcb61 100644
--- a/css/main.less
+++ b/css/main.less
@@ -10,8 +10,15 @@ html, body {
outline: none;
}
+div#container {
+ position: absolute;
+}
+
canvas {
border: 1px solid gray;
+ position: absolute;
+ top: 0;
+ left: 0;
}
header {
diff --git a/img/icons/1.png b/img/icons/1.png
new file mode 100644
index 0000000..9ece556
Binary files /dev/null and b/img/icons/1.png differ
diff --git a/img/icons/demo1.png b/img/icons/demo1.png
new file mode 100644
index 0000000..7d6998d
Binary files /dev/null and b/img/icons/demo1.png differ
diff --git a/index.html b/index.html
index 3689c33..df69f90 100644
--- a/index.html
+++ b/index.html
@@ -14,7 +14,10 @@
-
+
+
+
+
diff --git a/js/functions.js b/js/functions.js
index f227afe..de4ea5a 100644
--- a/js/functions.js
+++ b/js/functions.js
@@ -6,11 +6,8 @@ function sizeAndPos() {
var data = c.getImageData(0,0, $c.width(), $c.height());
var w = $(window).width(),
h = $(window).height();
- $c.css({'margin-left': w * .05,
- 'margin-top': h * .05
- })
- $c.attr('width', w * .9);
- $c.attr('height',h * .9 - 50);
+ $c.attr('width', w);
+ $c.attr('height',h - 50);
c.clearRect(0,0, $c.width(), $c.height());
c.putImageData(data, 0, 0);
}
@@ -28,8 +25,10 @@ function threshold(x1, y1, x2, y2, threshold) {
return false;
}
-function line(x1, y1, x2, y2, opts) {
+function line(x1, y1, x2, y2, opts, overlay) {
opts = opts || {};
+ var c = window.c;
+ if( overlay ) var c = window.o;
c.beginPath();
c.lineCap = opts.lineCap || settings.lineCap;
c.lineJoin = opts.lineJoin || settings.lineJoin;
@@ -40,13 +39,47 @@ function line(x1, y1, x2, y2, opts) {
c.stroke();
}
+function erase(x1, y1, x2, y2, overlay) {
+ var c = window.c;
+ if( overlay ) var c = window.o;
+ c.clearRect(x1, y1, x2 - x1, y2 - y1);
+}
+
+function undo() {
+ var history = window.points.history;
+ if( history.last > 1 ) {
+ var step = history[history.last-1];
+ c.putImageData(step.data, 0, 0);
+ window.points = step.points.slice(0);
+ window.points.history = history;
+ window.points.history.last = history.last-1;
+ } else {
+ c.clearRect(0,0, $c.width(), $c.height());
+ window.points = [];
+ window.points.history = history;
+ window.points.history.last = 0;
+ }
+
+}
+
+function redo() {
+ var history = window.points.history;
+ if( history.last < history.length-1 ) {
+ var step = history[history.last+1];
+ c.putImageData(step.data, 0, 0);
+ window.points = step.points.slice(0);
+ window.points.history = history;
+ window.points.history.last = history.last+1;
+ }
+}
+
/*** END ***/
function startPoint(x, y) {
- // If not previous point exists, make the first one.
- if( !points.length ) points.push({x: x, y: y, type: settings.type, start: {x: x, y: y}});
+ // If no previous point exists, make the first one.
+ if( !points.length ) points.push({x: x, y: y, type: '', start: {x: x, y: y}});
var old = points[points.length-1],
start = old.start,
@@ -56,10 +89,12 @@ function startPoint(x, y) {
start : old.start || {x: x, y: y},
type : settings.type
}
- // Just draws a circle
- line(x,y,x,y);
+ if( old.type !== 'line' && current.type == 'line' ) {
+ line(x,y,x,y, {lineWidth: 5, strokeStyle: 'red'}, true);
+ }
if( old.type == 'line' ) {
+ if( points[points.indexOf(old)-1].type !== 'line' ) erase(old.x-5, old.y-5, old.x+5, old.y+5, true);
line(old.x, old.y, x, y);
}
@@ -70,6 +105,10 @@ function startPoint(x, y) {
return;
}
+ if(current.type == 'ribbon') {
+ settings.ribbonTimes = 1;
+ }
+
points.push(current);
}
@@ -101,7 +140,7 @@ function drawPoint(x,y) {
points.push(current);
for( var i = 0, len = points.length-1; i < len; i++ ) {
- if( threshold(points[i].x, points[i].y, current.x, current.y, 40)) {
+ if(threshold(points[i].x, points[i].y, current.x, current.y, 40)) {
var x = points[i].x - current.x,
y = points[i].y - current.y;
@@ -110,7 +149,26 @@ function drawPoint(x,y) {
}
break;
}
+ case 'fur': {
+ line(capture.x, capture.y, x, y);
+ var current = {
+ x : x,
+ y : y,
+ start : capture.start,
+ type : capture.type
+ }
+ points.push(current);
+
+ for( var i = 0, len = points.length-1; i < len; i++ ) {
+ if(threshold(points[i].x, points[i].y, current.x, current.y, 40)) {
+ var x = points[i].x - current.x,
+ y = points[i].y - current.y;
+ var l = settings.furLength || 0.2;
+ line(points[i].x + x*l, points[i].y + y*l, current.x - x*l, current.y - y*l, {strokeStyle: 'rgba(0,0,0,0.4)', lineWidth: settings.lineWidth/2})
+ }
+ }
+ break;
+ }
}
}
-
diff --git a/js/main.js b/js/main.js
index 44cd40a..7bcf841 100644
--- a/js/main.js
+++ b/js/main.js
@@ -1,47 +1,50 @@
"use strict";
$(document).ready(function() {
- window.c = $('canvas')[0].getContext('2d');
+ window.c = $('canvas')[0].getContext('2d');
+ window.o = $('canvas')[1].getContext('2d');
window.settings = {
lineWidth : 0.2,
strokeStyle : 'black',
type: 'sketch',
lineCap: 'round',
- lineJoin: 'round'
+ lineJoin: 'round',
+ ribbonEnd: 50,
+ ribbonTurn : 0
};
window.points = [];
window.$c = $('canvas');
+ window.points.history = [{ data: c.createImageData($c.width(), $c.height()), points: []}];
sizeAndPos();
$(window).resize(sizeAndPos);
- $c.bind('mousedown', function(e) {
+ $c.last().bind('mousedown touchstart', function(e) {
e.preventDefault();
+ if( e.changedTouches ) e = e.changedTouches[0];
var xy = relative(e.pageX, e.pageY);
startPoint(xy.x, xy.y);
window.active = true;
- }).bind('mousemove', function(e) {
+ }).bind('mousemove touchmove', function(e) {
e.preventDefault();
if (!window.active || settings.type == 'line') return;
+ if( e.changedTouches ) e = e.changedTouches[0];
var xy = relative(e.pageX, e.pageY);
drawPoint(xy.x, xy.y);
}).bind('mouseup touchend', function(e) {
e.preventDefault();
window.active = false;
- }).bind('touchstart', function(e) {
- e.preventDefault();
- var touch = e.changedTouches[0];
- var xy = relative(touch.pageX, touch.pageY);
- startPoint(xy.x, xy.y);
- window.active = true;
- }).bind('touchmove', function(e) {
- e.preventDefault();
- if(!window.active || settings.type =='line') return;
- var touch = e.changedTouches[0];
- var xy = relative(touch.pageX, touch.pageY);
- drawPoint(xy.x, xy.y);
- window.active = true;
+
+ if(window.points.history.last < window.points.history.length-1) {
+ window.points.history.splice(window.points.history.last+1);
+ }
+
+ window.points.history.push({
+ data: c.getImageData(0, 0, $c.width(), $c.height()),
+ points: window.points.slice(0)
+ })
+ window.points.history.last = window.points.history.length-1;
})
})
diff --git a/manifest.webapp b/manifest.webapp
new file mode 100644
index 0000000..ea81b9b
--- /dev/null
+++ b/manifest.webapp
@@ -0,0 +1,26 @@
+{
+ "name": "Sketchy",
+ "description": "Free Sketch/Paint app",
+ "version": 1,
+ "launch_path": "/index.html",
+ "icons": {
+ "16": "/images/logo16.png",
+ "32": "/images/logo32.png",
+ "48": "/images/logo48.png",
+ "60": "/images/logo60.png",
+ "64": "/images/logo64.png",
+ "90": "/images/logo90.png",
+ "120": "/images/logo120.png",
+ "128": "/images/logo128.png"
+ },
+ "developer": {
+ "name": "Mahdi Dibaiee",
+ "url": "https://twitter.com/mdibaiee"
+ },
+ "locales": {
+ "fa": {
+ "name": "Sketchy",
+ "description": "برنامهی رایگان طراحی/نقاشی"
+ }
+ }
+}