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": "برنامه‌ی رایگان طراحی/نقاشی" + } + } +}