Файл: js/al/graffiti.js
Строк: 670
// Developed by Oleg Berman
// http://vk.com/olegberman
var Graffiti = {
init: function() {
var useragent = navigator.userAgent.toLowerCase();
if(/android|iphone|ipod|ipad|opera mini|opera mobi/i.test(useragent)) {
}
this.W = 586;
this.H = 293;
this.factor = 1;
this.brush = {
size: 0,
opacity: 0,
color: "51, 102, 153"
};
this.resizing = false;
this.resDif = 0;
this.resW = 586;
this.resH = 293;
this.fsEnabled = false;
this.resizer = ge("graffiti_resizer");
this.histHelpCanv = ge("graffiti_hist_helper");
this.histHelpCtx = this.histHelpCanv.getContext("2d");
this.canvWrapper = ge("graffiti_aligner");
this.mainCanv = ge("graffiti_common");
this.mainCtx = this.mainCanv.getContext("2d");
this.overlayCanv = ge("graffiti_overlay");
this.overlayCtx = this.overlayCanv.getContext("2d");
this.helpCanv = ge("graffiti_helper");
this.helpCtx = this.helpCanv.getContext("2d");
this.controlsCanv = ge("graffiti_controls");
this.controlsCtx = this.controlsCanv.getContext("2d");
this.grWrapper = ge("graffiti_wrapper");
this.cpWrapper = ge("graffiti_cpwrap");
this.cpCanv = ge("graffiti_cpicker");
this.rzLink = ge("graffiti_resize_link");
this.cpCtx = this.cpCanv.getContext("2d");
this.addSlider("size", this.controlsCtx, 267, 31, 20);
this.addSlider("opacity", this.controlsCtx, 483, 31, 80);
this.redrawColorPickerButton(this.controlsCtx, 147, 30, "51, 102, 153", false);
this.addText(this.controlsCtx, cur.lang['graffiti_flash_color'], 100, 35.5);
this.addText(this.controlsCtx, cur.lang['graffiti_flash_opacity'], 390, 35.5);
this.addText(this.controlsCtx, cur.lang['graffiti_flash_thickness'], 206, 35.5);
this.drawColorPicker(this.cpCtx);
this.attachEvents();
this.canvWrapper.style.width = this.W + "px";
this.canvWrapper.style.height = this.H + "px";
},
mouse: {
pressed: false,
x:[], y:[]
},
destroy: function() {
this.detachEvents();
Graffiti.hstorage = [];
Graffiti.gstorage = [];
Graffiti.checkPoint = "";
},
events: {
controls: function(e) {
Graffiti.handleControlsEvents(e);
return cancelEvent(e);
},
drawing: function(e) {
Graffiti.handleDrawingEvents(e);
return cancelEvent(e);
},
all: function(e) {
Graffiti.handleDrawingEvents(e);
Graffiti.handleControlsEvents(e);
Graffiti.handleResize(e);
return cancelEvent(e);
},
color: function(e) {
Graffiti.handleColorPickerEvents(e);
return cancelEvent(e);
},
controlsF: function(e) {
Graffiti.handleControlsEvents(e);
return false;
},
keyboard: function(e) {
Graffiti.keyboardEvents(e);
return cancelEvent(e);
},
cancel: function(e) {
return cancelEvent(e);
},
resize: function(e) {
Graffiti.handleResize(e);
return cancelEvent(e);
}
},
attachEvents: function() {
var evs = Graffiti.events;
addEvent(Graffiti.controlsCanv, "mousedown click" , evs.controls);
addEvent(window, "mousemove mouseup", evs.all);
addEvent(Graffiti.overlayCanv, "mousedown click", evs.drawing);
addEvent(Graffiti.cpCanv, "mousemove click", evs.color);
addEvent(Graffiti.controlsCanv, "DOMMouseScroll mousewheel", evs.controlsF);
addEvent(document, "keydown keyup", evs.keyboard);
addEvent(document, "contextmenu", evs.cancel);
addEvent(document.body, "selectstart", evs.cancel);
addEvent(Graffiti.resizer, "mousedown", evs.resize);
},
detachEvents: function() {
var evs = Graffiti.events;
removeEvent(Graffiti.controlsCanv, "mousedown click" , evs.controls);
removeEvent(window, "mousemove mouseup", evs.all);
removeEvent(Graffiti.overlayCanv, "mousedown click", evs.drawing);
removeEvent(Graffiti.cpCanv, "mousemove click", evs.color);
removeEvent(Graffiti.controlsCanv, "DOMMouseScroll mousewheel", evs.controlsF);
removeEvent(document, "keydown keyup", evs.keyboard);
removeEvent(document.body, "selectstart", evs.cancel);
removeEvent(Graffiti.resizer, "mousedown", evs.resize);
removeEvent(document, "contextmenu", evs.cancel);
},
handleResize: function(e) {
if (e.button == 2) {
return;
}
switch(e.type) {
case "mousedown":
document.body.style.cursor = "s-resize";
Graffiti.controlsCanv.style.cursor = "s-resize";
var mouse = Graffiti.getMouseXY(e, window);
Graffiti.resDif = mouse.y;
Graffiti.resizing = true;
Graffiti.mainCtx.clearRect(0, 0, Graffiti.W, Graffiti.H);
break;
case "mousemove":
if(Graffiti.resizing) {
var mouse = Graffiti.getMouseXY(e, window);
var height = parseInt(Graffiti.canvWrapper.style.height);
var width = parseInt(Graffiti.canvWrapper.style.width);
var newHeight = height + mouse.y - Graffiti.resDif;
if(newHeight > 586) newHeight = 586;
if(newHeight < 293) newHeight = 293;
var newWidth = newHeight / Graffiti.H * Graffiti.W;
Graffiti.resW = newWidth;
Graffiti.resH = newHeight;
Graffiti.canvWrapper.style.width = newWidth + "px";
Graffiti.canvWrapper.style.height = newHeight + "px";
if (Graffiti.onResize) {
Graffiti.onResize(newWidth, newHeight);
}
Graffiti.resDif = mouse.y;
}
break;
case "mouseup":
if(Graffiti.resizing) {
Graffiti.resizing = false;
Graffiti.resDif = 0;
Graffiti.controlsCanv.style.cursor = "default";
document.body.style.cursor = "default";
Graffiti.factor = Graffiti.resH / 293;
Graffiti.W = Graffiti.resW;
Graffiti.H = Graffiti.resH;
Graffiti.resizeCanvases(Graffiti.resW, Graffiti.resH);
Graffiti.copyImage(Graffiti.mainCtx);
}
break;
}
},
copyImage: function(ctx, callback) {
if (Graffiti.checkPoint != '') {
var img = vkImage();
img.src = Graffiti.checkPoint;
img.onload = function() {
ctx.drawImage(img, 0, 0, Graffiti.W, Graffiti.H);
Graffiti.propDraw(ctx, Graffiti.hstorage, 0, Graffiti.hstorage.length);
if (callback) {
callback();
}
}
} else {
Graffiti.propDraw(ctx, Graffiti.hstorage, 0, Graffiti.hstorage.length);
if (callback) {
callback();
}
}
},
keyboardBlocked: false,
shiftPressed: false,
keyboardEvents: function(e) {
switch(e.type) {
case "keydown":
if(e.shiftKey || e.keyCode == 16) {
Graffiti.drawPath = true;
return;
}
switch(e.keyCode) {
case 90:
if(!e.ctrlKey) return;
if(Graffiti.keyboardBlocked) return;
Graffiti.keyboardBlocked = true;
Graffiti.backHistory();
break;
case 70:
if(!e.ctrlKey) return;
Graffiti.fullScreen();
break;
}
break;
case "keyup":
if(e.shiftKey || e.keyCode == 16) {
Graffiti.stopDrawPathLine();
return;
}
if(e.keyCode == 90) {
Graffiti.keyboardBlocked = false;
}
break;
}
},
handleControlsEvents: function(e) {
switch(e.type) {
case "mousedown":
var mouse = Graffiti.getMouseXY(e, Graffiti.controlsCanv);
var sl = Graffiti.sliders;
for(var i=0; i < sl.length; i++) {
if(mouse.x >= sl[i].x && mouse.x <= sl[i].x+100) {
if(mouse.y >= sl[i].y-10.5 && mouse.y <= sl[i].y+6) {
if(mouse.x > sl[i].x+95) mouse.x -=4;
Graffiti.redrawSlider(sl[i].id, Graffiti.controlsCtx, {x:sl[i].x, y:sl[i].y}, mouse.x);
Graffiti.sliders[i].holder = mouse.x;
Graffiti.aboveSlider.status = true;
Graffiti.aboveSlider.index = i;
}
}
}
break;
case "mousemove":
if(!Graffiti.mouse.pressed && !Graffiti.resizing) {
var mouse = Graffiti.getMouseXY(e, Graffiti.controlsCanv);
if(Graffiti.aboveSlider.status) {
var cs = Graffiti.sliders[Graffiti.aboveSlider.index];
if(mouse.x > cs.x && mouse.x < cs.x + 95) {
Graffiti.redrawSlider(cs.id, Graffiti.controlsCtx, {x:cs.x, y:cs.y}, mouse.x);
Graffiti.sliders[Graffiti.aboveSlider.index].holder = mouse.x;
} else {
if(mouse.x < cs.x) {
Graffiti.redrawSlider(cs.id, Graffiti.controlsCtx, {x:cs.x, y:cs.y}, cs.x);
Graffiti.sliders[Graffiti.aboveSlider.index].holder = cs.x;
}
if(mouse.x > cs.x+95) {
Graffiti.redrawSlider(cs.id, Graffiti.controlsCtx, {x:cs.x, y:cs.y}, cs.x+95);
Graffiti.sliders[Graffiti.aboveSlider.index].holder = cs.x+95;
}
}
} else {
var xy = Graffiti.cpbXY;
if(mouse.x >= xy.x-8 && mouse.x <= xy.x + 23) {
if(mouse.y >= xy.y-5 && mouse.y <= xy.y + 25) {
Graffiti.controlsCanv.style.cursor = "pointer";
Graffiti.redrawColorPickerButton(Graffiti.controlsCtx, Graffiti.gpXY.x,
Graffiti.gpXY.y, Graffiti.brush.color, true);
} else {
Graffiti.controlsCanv.style.cursor = "default";
Graffiti.redrawColorPickerButton(Graffiti.controlsCtx, Graffiti.gpXY.x,
Graffiti.gpXY.y, Graffiti.brush.color, false);
}
} else {
Graffiti.controlsCanv.style.cursor = "default";
Graffiti.redrawColorPickerButton(Graffiti.controlsCtx, Graffiti.gpXY.x,
Graffiti.gpXY.y, Graffiti.brush.color, false);
}
}
}
break;
case "click":
var xy = Graffiti.cpbXY;
var mouse = Graffiti.getMouseXY(e, Graffiti.controlsCanv);
if(mouse.x >= xy.x-8 && mouse.x <= xy.x + 23) {
if(mouse.y >= xy.y-5 && mouse.y <= xy.y + 25) {
if(!Graffiti.cpActive) {
Graffiti.cpActive = true;
Graffiti.cpWrapper.style.display = "block";
animate(Graffiti.cpWrapper, {opacity: 1, top: -250}, 200);
} else {
Graffiti.cpActive = false;
animate(Graffiti.cpWrapper, {opacity: 0, top: -210}, 200, function() {
Graffiti.cpWrapper.style.display = "none";
});
}
}
}
break;
case "mouseup":
if(Graffiti.aboveSlider.status) {
Graffiti.aboveSlider.status = false;
}
break;
case "DOMMouseScroll":
Graffiti.handleWheelAboveSlider(e);
break;
case "mousewheel":
Graffiti.handleWheelAboveSlider(e);
break;
default:
throw new Error(e.type);
break;
}
},
sliders: [], aboveSlider: { status:false, index:0 },
addSlider: function(id, ctx, x, y, holder) {
this.redrawSlider(id, ctx, {x:x, y:y}, x+holder);
this.drawAboveSliderLines(ctx, x, y);
this.sliders.push({id:id, x:x, y:y, holder:x+holder});
},
redrawSlider: function(id, ctx, sliderXY, holder) {
var oldX = sliderXY.x;
var oldY = sliderXY.y;
var newX = holder;
ctx.clearRect(oldX-3.5, oldY-3, 108, 12);
this.drawSliderLine(ctx, oldX, oldY);
this.drawSliderHolder(ctx, newX-3, oldY);
this.slideEventHandler(id, sliderXY, holder);
},
drawSliderLine: function(ctx, x, y) {
ctx.lineJoin = "miter";
ctx.lineCap = "square";
ctx.strokeStyle = "#BFBFBF";
ctx.fillStyle = "#E4E4E4";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.fillRect(x+0.5, y+0.5, 100, 4);
ctx.strokeRect(x+0.5, y+0.5, 100, 4);
ctx.closePath();
},
drawSliderHolder: function(ctx, x, y) {
ctx.lineJoin = "miter";
ctx.lineCap = "square";
ctx.strokeStyle = "#ABB8C7";
ctx.fillStyle = "#DAE1E8";
ctx.beginPath();
ctx.fillRect(x+0.5, y-2.5, 7, 11);
ctx.strokeRect(x+0.5, y-2.5, 7, 11);
ctx.closePath();
},
drawAboveSliderLines: function(ctx, x, y) {
ctx.strokeStyle = "#BFBFBF";
ctx.lineWidth = 1;
var tempX = x+10.5;
var tempY = y-4;
for(var i=0; i<9; i++) {
ctx.beginPath();
ctx.moveTo(tempX, tempY-6);
ctx.lineTo(tempX, tempY);
tempX += 10;
ctx.stroke();
ctx.closePath();
}
},
handleWheelAboveSlider: function(e) {
var delta = 0;
var dif = 0;
if(e.wheelDelta) {
delta = e.wheelDelta / 120;
} else if(e.detail) {
delta = -e.detail/3;
}
if(delta) {
delta = delta * 10;
dif = delta;
var mouse = Graffiti.getMouseXY(e, Graffiti.controlsCanv);
var sl = Graffiti.sliders;
for(var i=0; i < sl.length; i++) {
if(mouse.x >= sl[i].x && mouse.x <= sl[i].x+100) {
if(mouse.y >= sl[i].y-10.5 && mouse.y <= sl[i].y+6) {
if((sl[i].holder + delta) < sl[i].x) {
dif = sl[i].x - sl[i].holder;
}
if ((sl[i].holder + delta) > sl[i].x + 95) {
dif = sl[i].x+95 - sl[i].holder;
}
if(dif == 0) return;
Graffiti.redrawSlider(sl[i].id, Graffiti.controlsCtx, { x: sl[i].x, y: sl[i].y }, sl[i].holder+dif);
Graffiti.sliders[i].holder = sl[i].holder+dif;
}
}
}
}
},
slideEventHandler: function(id, sliderXY, holder) {
var _curpos = holder-sliderXY.x;
switch(id) {
case "size":
var _s = _curpos;
if(_s < 1) _s = 1;
Graffiti.brush.size = ((_s/95*100)/100).toFixed(2) * 64;
Graffiti.updateSample();
break;
case "opacity":
var _op = (Math.max(Math.min((_curpos/95*100)/100, 1), 0)).toFixed(2);
if( _op < 0.01 ) _op = 0.01;
Graffiti.brush.opacity = _op;
Graffiti.updateSample();
break;
default:
throw new Error("Slider " + id + " is not exist");
break;
}
},
redrawColorPickerButton: function(ctx, x, y, color, mouseover) {
Graffiti.gpXY.x = x;
Graffiti.gpXY.y = y;
ctx.clearRect(x-3, y-10, 20, 27);
ctx.lineWidth = 1;
ctx.fillStyle = "rgb("+color+")";
ctx.beginPath();
ctx.fillRect(x, y-1, 13, 13);
ctx.closePath();
var _x = x-1;
var fs;
if(!mouseover) {
fs = "rgb(218, 225, 232)";
} else {
fs = "rgb(255, 255, 255)";
}
ctx.strokeStyle = "rgb(171, 184, 199)";
ctx.fillStyle = fs;
ctx.lineCap = "square";
ctx.lineJoin = "miter";
ctx.beginPath();
ctx.moveTo(_x, y-3.5);
ctx.lineTo(_x+15, y-3.5);
ctx.lineTo(_x+7.5, y-8.5);
ctx.fill();
ctx.closePath();
ctx.stroke();
Graffiti.cpbXY.x = x-1;
Graffiti.cpbXY.y = y-9;
},
updateSample: function() {
var size = Graffiti.brush.size;
var opacity = Graffiti.brush.opacity;
var ctx = Graffiti.controlsCtx;
ctx.clearRect(0, 0, 66, 66);
ctx.strokeStyle = "rgba("+Graffiti.brush.color+", "+opacity+")";
ctx.lineWidth = size;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.beginPath();
ctx.moveTo(63.5/2, (63.5/2)+2);
ctx.lineTo((63.5/2) + 0.51, (63.5/2)+2);
ctx.stroke();
ctx.closePath();
},
labels: [],
addText: function(ctx, str, x, y) {
ctx.fillStyle = "#000000";
ctx.strokeStyle = "#000000";
ctx.font = "11px Tahoma, Arial, Verdana, Sans-Serif, Lucida Sans";
ctx.beginPath();
ctx.fillText(str, Math.floor(x+0.5), Math.floor(y+0.5));
ctx.closePath();
},
hstorage: [],
gstorage: [],
checkPoint: "",
saveBuffer: 100,
pushHistory: function(c) {
Graffiti.gstorage.push(c);
Graffiti.hstorage.push(c);
if(Graffiti.hstorage.length != Graffiti.saveBuffer * 2) return;
Graffiti.histHelpCtx.clearRect(0, 0, 1172, 586);
if (Graffiti.checkPoint != '') {
var img = vkImage();
img.src = Graffiti.checkPoint;
img.onload = function() {
Graffiti.histHelpCtx.drawImage(img, 0, 0, 1172, 586);
histdraw();
}
} else {
histdraw();
}
function histdraw() {
var m = Graffiti.hstorage;
var _x = [];
var _y = [];
var _s;
var fact;
for(var i=0; i<Graffiti.saveBuffer; i++) {
fact = m[i].factor;
for(var j=0; j<m[i].mouse.x.length; j++) {
_x.push(m[i].mouse.x[j] / fact * 2);
_y.push(m[i].mouse.y[j] / fact * 2);
}
_s = m[i].size / fact * 2;
Graffiti.draw(Graffiti.histHelpCtx, {mouse : {x:_x, y: _y}, size: _s, color: m[i].color, opacity: m[i].opacity});
_x = [];
_y = [];
}
Graffiti.checkPoint = Graffiti.histHelpCanv.toDataURL();
var img = vkImage();
img.src = Graffiti.checkPoint;
img.onload = function() {
Graffiti.mainCtx.clearRect(0, 0, Graffiti.W, Graffiti.H);
Graffiti.mainCtx.drawImage(img, 0, 0, Graffiti.W, Graffiti.H);
Graffiti.propDraw(Graffiti.mainCtx, Graffiti.hstorage, Graffiti.saveBuffer, Graffiti.hstorage.length);
Graffiti.hstorage.splice(0, Graffiti.saveBuffer);
}
}
},
backBlocked: false,
backQueue: 0,
globalBlock: false,
backHistory: function() {
if(Graffiti.globalBlock) return;
if(this.hstorage.length == 0) {
Graffiti.backQueue = 0;
if(this.checkPoint == "") {
return false;
} else {
Graffiti.hstorage = [];
Graffiti.checkPoint = "";
fadeOut(Graffiti.mainCanv, 200, function() {
Graffiti.mainCtx.clearRect(0, 0, Graffiti.W, Graffiti.H);
Graffiti.mainCanv.style.display = "block";
});
}
} else {
if(Graffiti.backBlocked) {
Graffiti.backQueue++;
return;
}
Graffiti.backBlocked = true;
var m = Graffiti.hstorage;
if(Graffiti.checkPoint != '') {
var img = vkImage();
img.src = Graffiti.checkPoint;
img.onload = function() {
Graffiti.helpCanv.style.backgroundColor = "#FFFFFF";
Graffiti.mainCtx.clearRect(0, 0, Graffiti.W, Graffiti.H);
Graffiti.mainCtx.drawImage(img, 0, 0, Graffiti.W, Graffiti.H);
Graffiti.helpCtx.drawImage(img, 0, 0, Graffiti.W, Graffiti.H);
rd();
}
} else {
Graffiti.helpCanv.style.backgroundColor = "#FFFFFF";
Graffiti.mainCtx.clearRect(0, 0, Graffiti.W, Graffiti.H);
rd();
}
}
function rd() {
Graffiti.propDraw(Graffiti.helpCtx, Graffiti.hstorage, 0, Graffiti.hstorage.length);
Graffiti.propDraw(Graffiti.mainCtx, Graffiti.hstorage, 0, Graffiti.hstorage.length-1);
fadeOut(Graffiti.helpCanv, 200, function() {
Graffiti.helpCtx.clearRect(0, 0, Graffiti.W, Graffiti.H);
Graffiti.helpCanv.style.backgroundColor = "";
Graffiti.helpCanv.style.display = "block";
Graffiti.backBlocked = false;
if(Graffiti.backQueue > 0) {
for(var i=0; i<Graffiti.backQueue; i++) {
Graffiti.backHistory();
Graffiti.backQueue--;
}
}
});
Graffiti.hstorage.pop();
Graffiti.gstorage.pop();
}
},
flushHistory: function() {
fadeOut(Graffiti.mainCanv, 200, function() {
Graffiti.mainCtx.clearRect(0, 0, Graffiti.W, Graffiti.H);
Graffiti.mainCanv.style.display = "block";
Graffiti.checkPoint = "";
Graffiti.hstorage = [];
Graffiti.gstorage = [];
});
},
draw: function(ctx, hist) {
var mouse, color, size, opacity;
if(hist) {
mouse = hist.mouse;
color = hist.color;
opacity = hist.opacity;
size = hist.size;
} else {
mouse = Graffiti.mouse;
color = Graffiti.brush.color;
size = Graffiti.brush.size * Graffiti.factor;
opacity = Graffiti.brush.opacity;
}
ctx.strokeStyle = "rgba("+color+", "+opacity+")";
ctx.lineWidth = size;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.beginPath();
if(mouse.x.length < 2) {
ctx.moveTo(mouse.x[0], mouse.y[0]);
ctx.lineTo(mouse.x[0] + 0.51, mouse.y[0]);
ctx.stroke();
ctx.closePath();
return;
}
ctx.beginPath();
ctx.moveTo(mouse.x[0], mouse.y[0]);
ctx.lineTo((mouse.x[0] + mouse.x[1]) * 0.5, (mouse.y[0] + mouse.y[1]) * 0.5);
var i = 0;
while(++i < (mouse.x.length -1)) {
var abs1 = Math.abs(mouse.x[i-1] - mouse.x[i]) + Math.abs(mouse.y[i-1] - mouse.y[i])
+ Math.abs(mouse.x[i] - mouse.x[i+1]) + Math.abs(mouse.y[i] - mouse.y[i+1]);
var abs2 = Math.abs(mouse.x[i-1] - mouse.x[i+1]) + Math.abs(mouse.y[i-1] - mouse.y[i+1]);
if(abs1 > 10 && abs2 > abs1 * 0.8) {
ctx.quadraticCurveTo(mouse.x[i], mouse.y[i], (mouse.x[i] + mouse.x[i+1]) * 0.5, (mouse.y[i] + mouse.y[i+1]) * 0.5);
continue;
}
ctx.lineTo(mouse.x[i], mouse.y[i]);
ctx.lineTo((mouse.x[i] + mouse.x[i+1]) * 0.5, (mouse.y[i] + mouse.y[i+1]) * 0.5);
}
ctx.lineTo(mouse.x[mouse.x.length-1], mouse.y[mouse.y.length-1]);
ctx.moveTo(mouse.x[mouse.x.length-1], mouse.y[mouse.y.length-1]);
ctx.stroke();
ctx.closePath();
},
propDraw: function(ctx, storage, from, to) {
var m = storage;
var _x = [];
var _y = [];
var _s;
var fact;
for(var i=from; i<to; i++) {
fact = m[i].factor;
for(var j=0; j<m[i].mouse.x.length; j++) {
_x.push(m[i].mouse.x[j] / fact * Graffiti.factor);
_y.push(m[i].mouse.y[j] / fact * Graffiti.factor);
}
_s = m[i].size / fact * Graffiti.factor
Graffiti.draw(ctx, {mouse : {x:_x, y: _y}, size: _s, color: m[i].color, opacity: m[i].opacity});
_x = [];
_y = [];
}
},
drawPath: false,
handleDrawingEvents: function(e) {
var mouse = Graffiti.getMouseXY(e, Graffiti.overlayCanv);
if (!e.which && e.button) {
if (e.button & 1) e.which = 1
else if (e.button & 4) e.which = 2
else if (e.button & 2) e.which = 3
}
switch(e.type) {
case "mousedown":
if(e.which == 1) {
if(!Graffiti.drawPath) {
Graffiti.mouse.pressed = true;
Graffiti.mouse.x = [mouse.x];
Graffiti.mouse.y = [mouse.y];
Graffiti.draw(Graffiti.overlayCtx);
}
}
if(e.which == 3) {
Graffiti.drawPath = true;
}
break;
case "click":
if(e.which == 1) {
if(Graffiti.drawPath) {
Graffiti.overlayCtx.clearRect(0, 0, Graffiti.W, Graffiti.H);
Graffiti.mouse.x.push(mouse.x);
Graffiti.mouse.y.push(mouse.y);
Graffiti.draw(Graffiti.overlayCtx);
}
}
break;
case "mousemove":
if(Graffiti.mouse.pressed) {
var _m = Graffiti.mouse;
if(_m.x == mouse.x && _m.y == mouse.y) {
return;
} else {
Graffiti.overlayCtx.clearRect(0, 0, Graffiti.W, Graffiti.H);
}
Graffiti.mouse.x.push(mouse.x);
Graffiti.mouse.y.push(mouse.y);
Graffiti.draw(Graffiti.overlayCtx);
}
break;
case "mouseup":
if(e.which == 1) {
if(Graffiti.mouse.pressed) {
Graffiti.mouse.pressed = false;
Graffiti.overlayCtx.clearRect(0, 0, Graffiti.W, Graffiti.H);
Graffiti.draw(Graffiti.mainCtx);
Graffiti.pushHistory({mouse : {x: Graffiti.mouse.x, y: Graffiti.mouse.y},
color: Graffiti.brush.color, size: Graffiti.brush.size * Graffiti.factor, opacity: Graffiti.brush.opacity, factor: Graffiti.factor});
Graffiti.mouse.x = [];
Graffiti.mouse.y = [];
}
}
if(e.which == 3) {
Graffiti.stopDrawPathLine();
}
break;
}
},
stopDrawPathLine: function() {
Graffiti.drawPath = false;
Graffiti.overlayCtx.clearRect(0, 0, Graffiti.W, Graffiti.H);
Graffiti.draw(Graffiti.mainCtx);
Graffiti.pushHistory({mouse : {x: Graffiti.mouse.x, y: Graffiti.mouse.y},
color: Graffiti.brush.color, size: Graffiti.brush.size * Graffiti.factor, opacity: Graffiti.brush.opacity, factor: Graffiti.factor});
Graffiti.mouse.x = [];
Graffiti.mouse.y = [];
},
handleColorPickerEvents: function(e) {
switch(e.type) {
case "mousemove":
var mouse = Graffiti.getMouseXY(e, Graffiti.cpCanv);
var cellX = Math.floor((mouse.x)/14);
var cellY = Math.floor((mouse.y)/14);
if(cellY > 11) return;
if(cellX > 17) return;
var ctx = Graffiti.cpCtx;
ctx.lineWidth = 1;
ctx.lineJoin = "miter";
ctx.lineCap = "butt";
var lc = Graffiti.cpLastCell;
if(lc.length > 0) {
ctx.strokeStyle = "rgba(0,0,0,1)";
ctx.beginPath();
ctx.strokeRect((lc[0].x * 14)+0.5, (lc[0].y * 14)+0.5, 14, 14);
ctx.closePath();
Graffiti.cpLastCell = [];
}
ctx.strokeStyle = "rgb(255,255,255)";
ctx.beginPath();
ctx.strokeRect((cellX * 14)+0.5, (cellY * 14)+0.5, 14, 14);
ctx.closePath();
Graffiti.cpLastCell.push({x : cellX, y : cellY});
Graffiti.cpActiveCell.cellX = cellX;
Graffiti.cpActiveCell.cellY = cellY;
break;
case "click":
var ctx = Graffiti.cpCtx;
var ac = Graffiti.cpActiveCell;
var pixelX = (ac.cellX * 14) + 7;
var pixelY = (ac.cellY * 14) + 7;
var _ = ctx.getImageData(pixelX, pixelY, 1, 1).data;
var color = [].slice.call(_, 0, 3).join();
Graffiti.brush.color = color;
Graffiti.redrawColorPickerButton(Graffiti.controlsCtx, Graffiti.gpXY.x, Graffiti.gpXY.y, color, false);
Graffiti.updateSample();
Graffiti.cpActive = false;
animate(Graffiti.cpWrapper, {opacity: 0, top: -210}, 200, function() {
Graffiti.cpWrapper.style.display = "none";
});
break;
default:
throw new Error(e.type);
break;
}
},
cpbXY: {}, gpXY: {},
cpActive:false,
drawColorPicker: function(ctx) {
var cs = 14;
var colors = [];
ctx.lineWidth = 1;
for(var r=0; r<6; r++) {
for(var g=0; g<6; g++) {
for(var b=0; b<6; b++) {
colors[r*36+g*6+b] = "rgb("+(r/5*255)+","+(g/5*255)+","+(b/5*255)+")";
}
}
}
for(var j=0; j<12; j++) {
for(var i=0; i<18; i++) {
var _r = Math.floor(i / 6) + 3 * Math.floor(j / 6);
var _g = i % 6;
var _b = j % 6;
var _n = _r * 36 + _g * 6 + _b;
ctx.fillStyle = colors[_n];
ctx.strokeStyle = "rgb(0, 0, 0)";
var _x = Math.floor(i*14)+0.5;
var _y = Math.floor(j*14)+0.5;
ctx.fillRect(_x, _y, _x+cs, _x+cs);
ctx.strokeRect(_x, _y, _y+cs, _y+cs);
}
}
ctx.strokeStyle = "rgb(0, 0, 0)";
ctx.beginPath();
ctx.moveTo(252.5, 0);
ctx.lineTo(252.5, 168.5);
ctx.moveTo(252.5, 168.5);
ctx.lineTo(0, 168.5);
ctx.closePath();
ctx.stroke();
},
cpActiveCell: {cellX: 0, cellY: 0},
cpLastCell: [],
blockResize: false,
fsEnabled: false,
fullScreen: function() {
if (Graffiti.mouse.pressed) return;
if (Graffiti.blockResize) return;
if (!this.fsEnabled) {
this.fsEnabled = true;
Graffiti.blockResize = true;
setStyle(Graffiti.canvWrapper, {marginTop: -185, marginLeft: 18});
addClass(Graffiti.grWrapper, 'graffiti_fullscreen');
Graffiti.boxPos = getXY(curBox().bodyNode, true);
setStyle(Graffiti.grWrapper, {
top: Graffiti.boxPos[1],
left: Graffiti.boxPos[0],
height: Graffiti.H + 141,
width: Graffiti.W + 45
});
var width = Math.min(window.innerWidth - 40, 586 * 2);
var height = Math.min(intval((293 / 586) * width), window.innerHeight - 120);
width = height * (586 / 293);
Graffiti.W = width;
Graffiti.H = height;
Graffiti.factor = Graffiti.H / 293;
hide(Graffiti.mainCanv);
animate(Graffiti.grWrapper, {
top: 0,
left: 0,
height: window.innerHeight,
width: bodyNode.scrollWidth
}, 200);
animate(Graffiti.canvWrapper, {
width: Graffiti.W,
height: Graffiti.H,
marginTop: -Math.floor((Graffiti.H + 75) / 2),
marginLeft: ((window.innerWidth - Graffiti.W) / 2)
}, 200, function() {
show(Graffiti.mainCanv);
Graffiti.resizeCanvases(Graffiti.W, Graffiti.H)
Graffiti.copyImage(Graffiti.mainCtx);
Graffiti.blockResize = false;
Graffiti.rzLink.innerHTML = cur.lang['graffiti_normal_size'];
setStyle(Graffiti.grWrapper, {height: '100%', width: '100%'});
});
} else {
this.fsEnabled = false;
Graffiti.blockResize = true;
Graffiti.W = Graffiti.resW || 586;
Graffiti.H = Graffiti.resH || 293;
Graffiti.factor = Graffiti.H / 293;
hide(Graffiti.mainCanv);
animate(Graffiti.grWrapper, {
top: Graffiti.boxPos[1],
left: Graffiti.boxPos[0],
height: Graffiti.H + 140,
width: Graffiti.W + 45
}, 200);
animate(Graffiti.canvWrapper, {
width: Graffiti.W,
height: Graffiti.H,
marginTop: -185,
marginLeft: 22
}, 200, function() {
show(Graffiti.mainCanv);
Graffiti.resizeCanvases(Graffiti.W, Graffiti.H)
Graffiti.copyImage(Graffiti.mainCtx);
Graffiti.blockResize = false;
Graffiti.rzLink.innerHTML = cur.lang['graffiti_full_screen'];
removeClass(Graffiti.grWrapper, 'graffiti_fullscreen');
setStyle(Graffiti.grWrapper, {height: 'auto', width: '100%'});
setStyle(Graffiti.canvWrapper, {margin: '0 auto'});
});
}
},
resizeCanvases: function(w, h) {
Graffiti.mainCanv.width = w;
Graffiti.mainCanv.height = h;
Graffiti.overlayCanv.width = w;
Graffiti.overlayCanv.height = h;
Graffiti.helpCanv.width = w;
Graffiti.helpCanv.height = h;
Graffiti.helpCanv.style.top = (-1 * (h*2)).toFixed()+"px";
Graffiti.overlayCanv.style.top = (-1 * (h))+"px";
},
exportBlocked: false,
exportSVG: function(needStr) {
if (Graffiti.exportBlocked) return;
Graffiti.exportBlocked = true;
var svg = '<?xml version="1.0" standalone="yes"?>';
svg += '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';
svg += '<svg width="1172px" height="586px" viewBox="0 0 1172 586" xmlns="http://www.w3.org/2000/svg" version="1.1">';
if (Graffiti.gstorage.length != 0) {
for (var i=0; i<Graffiti.gstorage.length; i++) {
svg += Graffiti.drawSVG(Graffiti.gstorage[i]);
}
}
svg += "</svg>";
Graffiti.exportBlocked = false;
if (needStr) {
return svg;
} else {
var savewindow = window.open("data:image/svg+xml,"+encodeURIComponent(svg));
window.focus();
}
},
drawSVG: function(params) {
var str = '<path d="';
var color, size, opacity;
var mouse = { x: [], y: [] };
var fact = params.factor;
for(var i=0; i<params.mouse.x.length; i++) {
mouse.x.push(params.mouse.x[i] / fact * 2);
mouse.y.push(params.mouse.y[i] / fact * 2);
}
color = params.color;
opacity = params.opacity;
size = params.size / fact * 2;
if(mouse.x.length < 2) {
str += "M"+mouse.x[0] + ","+mouse.y[0]+" ";
str += "L"+(mouse.x[0] + 0.51) + "," + mouse.y[0] + " ";
str += '" fill="none" stroke="rgb('+color+')" stroke-opacity="'+opacity+'" stroke-width="'+size+'" stroke-linecap="round" stroke-linejoin="round" />';
return str;
}
str += "M"+mouse.x[0]+","+mouse.y[0]+" ";
str += "L"+((mouse.x[0] + mouse.x[1]) * 0.5)+","+((mouse.y[0] + mouse.y[1]) * 0.5)+" ";
var i = 0;
while(++i < (mouse.x.length -1)) {
var abs1 = Math.abs(mouse.x[i-1] - mouse.x[i]) + Math.abs(mouse.y[i-1] - mouse.y[i])
+ Math.abs(mouse.x[i] - mouse.x[i+1]) + Math.abs(mouse.y[i] - mouse.y[i+1]);
var abs2 = Math.abs(mouse.x[i-1] - mouse.x[i+1]) + Math.abs(mouse.y[i-1] - mouse.y[i+1]);
if(abs1 > 10 && abs2 > abs1 * 0.8) {
str += "Q" + mouse.x[i] + "," + mouse.y[i] +" "+ ((mouse.x[i] + mouse.x[i+1]) * 0.5)+","+((mouse.y[i] + mouse.y[i+1]) * 0.5)+" ";
continue;
}
str += "L"+mouse.x[i]+","+mouse.y[i]+" ";
str += "L"+((mouse.x[i] + mouse.x[i+1]) * 0.5)+","+((mouse.y[i] + mouse.y[i+1]) * 0.5)+" ";
}
str += "L" + mouse.x[mouse.x.length-1] + "," + mouse.y[mouse.y.length-1] + " ";
str += '" fill="none" stroke="rgb('+color+')" stroke-opacity="'+opacity+'" stroke-width="'+size+'" stroke-linecap="round" stroke-linejoin="round" />';
return str;
},
getMouseXY: function(e, obj) {
var cursor = {};
var objpos = getXY(obj);
cursor.x = e.pageX - objpos[0];
cursor.y = e.pageY - objpos[1];
/*if (browser.opera && (obj == Graffiti.controlsCanv)) {
cursor.y += scrollGetY();
}*/
return cursor;
},
isChanged: function() {
return (Graffiti.hstorage.length || Graffiti.checkPoint);
},
getImage: function(callback) {
var b = {w: Graffiti.W, h: Graffiti.H, f: Graffiti.factor};
/*Graffiti.factor = 1;
Graffiti.W = 586;
Graffiti.H = 293;*/
Graffiti.factor = 1280/586;
Graffiti.W = 1280;
Graffiti.H = 640;
var saveCanv = ce('canvas', {width: Graffiti.W, height: Graffiti.H});
var ctx = saveCanv.getContext('2d');
Graffiti.copyImage(ctx, function() {
Graffiti.factor = b.f;
Graffiti.W = b.w;
Graffiti.H = b.h;
callback(saveCanv.toDataURL());
});
}
}
try{stManager.done('graffiti.js');}catch(e){}