open2chOekakiEX
by
xnimasu
2014-08-17 [2014/08/17 15:19:12]
おーぷん2ちゃんお絵かき機能拡張ブックマークレット
@@ -18,6 +18,7 @@
Ver2.4.0 2014/04/02 文字入力でフォントの直接指定&改行入力&縦書出力に対応
Ver3.0.0 2014/04/05 お絵かき再生機能追加
Ver3.1.0 2014/04/06 お絵かき再生機能のエクスポート方式をテキストから画像埋め込みに変更
+Ver3.1.1 2014/04/09
*/
drawRedo = [];
canvas = $('#sketch').sketch();
@@ -114,7 +115,7 @@
var exp = document.createElement('input');
exp.setAttribute('id', 'exportButton');
exp.setAttribute('type', 'button');
-exp.setAttribute('value', 'エクスポート!');
+exp.setAttribute('value', 'エクスポート');
var imp = document.createElement('input');
imp.setAttribute('id', 'importButton');
@@ -170,7 +171,8 @@
y: y,
tool: canvas.tool,
fillColor: fillColor,
- targetColor: targetColor
+ targetColor: targetColor,
+ fill:null
});
canvas.redraw();
@@ -325,19 +327,27 @@
}
},
draw: function(action){
- var fillColor = action.fillColor;
- fillCanvas = canvas.context.getImageData(0, 0, canvas.el.width, canvas.el.height);
- var targetColor = action.targetColor;
- seeds = [{'x':action.x, 'y':action.y}];
-
- //var start = new Date();
- while(seeds.length > 0){
- var seed = seeds.shift();
- paint(seed.x, seed.y, fillColor, targetColor);
+ if(action.fill){
+ fillCanvas = action.fill;
+ }else{
+ var fillColor = action.fillColor;
+ fillCanvas = canvas.context.getImageData(0, 0, canvas.el.width, canvas.el.height);
+ var targetColor = action.targetColor;
+ seeds = [{
+ 'x':Number(action.x),
+ 'y':Number(action.y)
+ }];
+
+ //var start = new Date();
+ while(seeds.length > 0){
+ var seed = seeds.shift();
+ paint(seed.x, seed.y, fillColor, targetColor);
+ }
+ //var end = new Date();
+ //console.log(end - start + 'msec');
+
+ action.fill = fillCanvas;
}
- //var end = new Date();
- //console.log(end - start + 'msec');
-
return canvas.context.putImageData(fillCanvas, 0, 0);
}
}
@@ -436,29 +446,53 @@
function actionToString(){
var actionString = '';
+ var actDel = '!';
+ var propDel = '~';
+ var tools = {
+ marker: 'm',
+ eraser: 'e',
+ moji: 's',
+ fill: 'f'
+ };
jQuery.each(canvas.actions, function(i, action){
- if(action.tool == 'marker'){
- var actionX = Math.floor(action.events[0].x);
- var actionY = Math.floor(action.events[0].y);
- var beforeX = actionX;
- var beforeY = actionY;
- actionString += ' ' + lpad(actionX, 3, '0') + '' + lpad(actionY, 3, '0') + '' + lpad(action.size, 3, '0') + action.color.replace(/ /g, '') + '' + '~';
- jQuery.each(action.events, function(j, event){
- actionX = Math.floor(event.x);
- actionY = Math.floor(event.y);
- actionString += String.fromCharCode((actionX - beforeX + 64), (actionY - beforeY + 64));
- beforeX = actionX;
- beforeY = actionY;
- });
- }
+ if(tools[action.tool]){
+
+ actionString += actDel + tools[action.tool];
+
+ switch(action.tool){
+ case 'marker':
+ case 'eraser':
+ var actionX = Math.floor(action.events[0].x);
+ var actionY = Math.floor(action.events[0].y);
+ var beforeX = actionX;
+ var beforeY = actionY;
+ actionString += lpad(actionX, 3, '0') + lpad(actionY, 3, '0') + lpad(action.size, 3, '0') + action.color.replace(/ /g, '') + propDel;
+
+ jQuery.each(action.events, function(j, event){
+ actionX = Math.floor(event.x);
+ actionY = Math.floor(event.y);
+ actionString += String.fromCharCode((actionX - beforeX + 64), (actionY - beforeY + 64));
+ beforeX = actionX;
+ beforeY = actionY;
+ });
+ break;
+ case 'moji':
+ actionString += lpad(action.x, 3, '0') + lpad(action.y, 3, '0') + action.mode + propDel + action.color + propDel + action.font + propDel + action.text;
+ break;
+ case 'fill':
+ actionString += lpad(action.x, 3, '0') + lpad(action.y, 3, '0') + propDel + action.fillColor + propDel + action.targetColor;
+ break;
+ }
+ }
});
actionString = actionString.substr(1);
return actionString;
}
function actionStringToColor(actionString){
- //console.log('ExportString'+actionString);
+ console.log('ExportString'+actionString);
+ //var undefCharCode = 35;
var ch = canvas.el.height;
var m = -10;
var w = 1;
@@ -472,9 +506,9 @@
var c1 = actionString.charCodeAt(i*3);
var c2 = actionString.charCodeAt(i*3 + 1);
var c3 = actionString.charCodeAt(i*3 + 2);
- if(!c1){c1 = 33;console.log('NaN')}
- if(!c2){c2 = 33;console.log('NaN')}
- if(!c3){c3 = 33;console.log('NaN')}
+ if(!c1){c1 = 35;}
+ if(!c2){c2 = 35;}
+ if(!c3){c3 = 35;}
var color = (c1 << 16) + (c2 << 8) + c3;
//console.log('x>' + (i+2)%canvas.el.width + ' y>' + (Math.floor((i+2)/canvas.el.width) + h));
fillN(((i+1)*w)%(canvas.el.width+m)+1, Math.floor(((i+1)*w)/(canvas.el.width+m))*h, w, h, color);
@@ -504,20 +538,14 @@
function colorToActionString(){
fillCanvas = canvas.context.getImageData(0, 0, canvas.el.width, canvas.el.height);
var actionString = '';
-
+ var undefCharCode = 35;
var ch = 1;
var m = -10;
var w = 1;
var h = 1;
- //while(ch < canvas.el.height){
- var c = getRGB(1, 0);
- // h++;
- if(c!=0x000000){return;}
- //}
+ var c = getRGB(1, 0);
+ if(c!=0x000000){return;}
- //if(h <= 0){console.log('not found');return;}
- //console.log('importStart H->' + h);
-
var i = 0;
while(i < canvas.el.width * canvas.el.height / 4){
var color = getRGB(((i+1)*w)%(canvas.el.width+m)+1, (Math.floor(((i+1)*h)/(canvas.el.width+m)))*h);
@@ -531,8 +559,8 @@
actionString += String.fromCharCode(c2);
actionString += String.fromCharCode(c3);
}
- //console.log('Import String' + actionString.replace(/\!/g,''));
- return actionString.replace(/\!/g,'');
+ console.log('ImportString' + actionString.replace(new RegExp(String.fromCharCode(undefCharCode), 'g'), ''));
+ return actionString.replace(new RegExp(String.fromCharCode(undefCharCode), 'g'), '');
}
function stringToAction(actionString){
@@ -541,61 +569,109 @@
canvas.clear();
- var splitActions = actionString.split(' ');
+ var actionDelimiter = '!';
+ var propDelimiter = '~';
+ var splitActions = actionString.split(actionDelimiter);
var actions =[];
+ var tools = {
+ m: 'marker',
+ e: 'eraser',
+ s: 'moji',
+ f: 'fill'
+ };
+
jQuery.each(splitActions, function(i, actionsLine){
- var splitAction = actionsLine.split('~');
+ var splitAction = actionsLine.split(propDelimiter);
var actionLine = splitAction[0];
- var bX = actionLine.substr(0, 3);
- var bY = actionLine.substr(3, 3);
- var size = actionLine.substr(6, 3);
- var color = actionLine.substr(9);
- var action = {
- tool: 'marker',
- size: parseFloat(size),
- color: color,
- events: []
- }
+ var tool = tools[actionLine.substr(0, 1)];
+
+ switch(tool){
+ case 'marker':
+ case 'eraser':
+ var bX = actionLine.substr(1, 3);
+ var bY = actionLine.substr(4, 3);
+ var size = actionLine.substr(7, 3);
+ var color = actionLine.substr(10);
+ var action = {
+ tool: tool,
+ size: parseFloat(size),
+ color: color,
+ events: []
+ }
- action.events.push({x: bX, y: bY});
- var eventLine = splitAction[1];
- for(var i = 1; i <= eventLine.length/2; i++){
- action.events.push({
- x: Number(action.events[i-1].x) + Number(eventLine.charCodeAt(i*2) - 64),
- y: Number(action.events[i-1].y) + Number(eventLine.charCodeAt(i*2+1) - 64)});
- }
- actions.push(action);
+ action.events.push({x: bX, y: bY});
+ var eventLine = splitAction[1];
+ for(var i = 1; i <= eventLine.length/2; i++){
+ action.events.push({
+ x: Number(action.events[i-1].x) + Number(eventLine.charCodeAt(i*2) - 64),
+ y: Number(action.events[i-1].y) + Number(eventLine.charCodeAt(i*2+1) - 64)});
+ }
+ break;
+ //case 'moji':
+ // var action = {
+ // tool: tool,
+ // mode: actionLine.substr(1, 1),
+ // color: splitAction[1],
+ // font: splitAction[2],
+ // text: splitAction[3]
+ // };
+ // break;
+ case 'fill':
+ var action = {
+ tool: tool,
+ x: actionLine.substr(1, 3),
+ y: actionLine.substr(4, 3),
+ fillColor: splitAction[1],
+ targetColor: splitAction[2]
+ };
+ break;
+ }
+ actions.push(action);
});
return actions;
}
function playback(actions, time){
+ console.log('playback');
+ console.log(actions);
if(actions.length == 0){return;}
- var exportActions = actions;
var painting = false;
var id1 = setInterval(function(){
if(actions[0]){
var action = actions[0];
- var events = action.events;
- var i = 0;
if(!painting){
- var id2 = setInterval(function(){
- painting = true;
- if(i+1 < events.length){
- canvas.context.beginPath();
- canvas.context.moveTo(events[i].x, events[i].y);
- canvas.context.lineJoin = 'round';
- canvas.context.lineCap = 'round';
- canvas.context.lineTo(events[i+1].x, events[i+1].y);
- canvas.context.strokeStyle = action.color;
- canvas.context.lineWidth = action.size;
- canvas.context.stroke();i++;
- }else{
- clearInterval(id2);
- painting = false;
+ switch(action.tool){
+ case 'marker':
+ case 'eraser':
+ var i = 0;
+ var events = action.events;
+ var id2 = setInterval(function(){
+ painting = true;
+ if(events && i+1 < events.length){
+ canvas.context.beginPath();
+ canvas.context.moveTo(events[i].x, events[i].y);
+ canvas.context.lineJoin = 'round';
+ canvas.context.lineCap = 'round';
+ canvas.context.lineTo(events[i+1].x, events[i+1].y);
+ canvas.context.strokeStyle = action.color;
+ canvas.context.lineWidth = action.size;
+ canvas.context.stroke();i++;
+ }else{
+ clearInterval(id2);
+ painting = false;
+ canvas.actions.push(actions.shift());
+ canvas.redraw();
+ }
+ },time);
+ break;
+ case 'moji':
+ case 'fill':
+ painting = true;
canvas.actions.push(actions.shift());
- }
- },time);
+ canvas.redraw();
+ painting = false;
+ break;
+ }
}
}else{
clearInterval(id1);
@@ -622,33 +698,3 @@
keydownEvent(e, 39, drawRedo, canvas.actions);
});
-canvas.startPainting = function(){
- orgActions = canvas.actions;
- if(!orgActions){
- orgActions = [];
- }
- canvas.actions = [];
- beforeBaseImage = canvas.baseImageURL;
- var src = canvas.el.toDataURL('imgae/png');
- canvas.setBaseImageURL(src);
- canvas.painting = true;
- return canvas.action = {
- tool: canvas.tool,
- color: canvas.color,
- size: parseFloat(canvas.size),
- events: []
- };
-};
-
-canvas.stopPainting = function() {
- if (canvas.action && canvas.painting) {
- orgActions.push(canvas.action);
- canvas.setBaseImageURL(beforeBaseImage);
- canvas.actions = orgActions;
- }
- canvas.painting = false;
- canvas.action = null;
- return setTimeout(function(){canvas.redraw();},10);
-};
-
-
/*
* @title open2chOekakiEX
* @description おーぷん2ちゃんお絵かき機能拡張ブックマークレット
* @private
*/
/*
【更新履歴】
Ver1.0.0 2014/03/29 文字入力機能追加
Ver1.1.0 2014/03/29 お絵かき機能ツールメニュー内に文字入力機能を追加 文字サイズ指定追加
Ver1.2.0 2014/03/30 フォント指定、修飾指定追加
Ver1.3.0 2014/03/30 線描画と文字入力のUNDO/REDO機能追加 イタリックが効かないバグ修正
Ver2.0.0 2014/03/31 塗りつぶし機能追加
Ver2.1.0 2014/03/31 塗りつぶし機能にUNDO/REDO機能追加
Ver2.1.1 2014/03/31 IE、Chromeで塗りつぶしが効かないバグ修正
Ver2.2.0 2014/04/01 背景色以外の色も塗りつぶせるように修正
Ver2.3.0 2014/04/01 透明度を指定して塗りつぶせるように修正
Ver2.4.0 2014/04/02 文字入力でフォントの直接指定&改行入力&縦書出力に対応
Ver3.0.0 2014/04/05 お絵かき再生機能追加
Ver3.1.0 2014/04/06 お絵かき再生機能のエクスポート方式をテキストから画像埋め込みに変更
Ver3.1.1 2014/04/09
*/
drawRedo = [];
canvas = $('#sketch').sketch();
var fillInput = document.createElement('input');
fillInput.setAttribute('id', 'fill');
fillInput.setAttribute('type', 'radio');
fillInput.setAttribute('name', 'pmode');
var fillImg = document.createElement('img');
fillImg.setAttribute('src', 'http://image.open2ch.net/image/oekaki/nuri.png');
var fillLabel = document.createElement('label');
fillLabel.appendChild(fillImg);
var textInput = document.createElement('input');
textInput.setAttribute('id', 'moji');
textInput.setAttribute('type', 'radio');
textInput.setAttribute('name', 'pmode');
var textLabel = document.createElement('label');
textLabel.setAttribute('for', 'moji');
var b = document.createElement('b');
var textNode = document.createTextNode('[A]:');
b.appendChild(textNode);
textLabel.appendChild(b);
var size = [10,12,14,16,18,20,24,28,32,36,40,48,56,64,72,80,90,100];
var mojiSelect = document.createElement('select');
mojiSelect.setAttribute('id', 'mojiSize');
for(var i = 0; i < size.length; i++){
var option = document.createElement('option');
if(i == 5){
option.setAttribute('selected','selected');
}
option.value = size[i];
var text = document.createTextNode(size[i]);
option.appendChild(text);
mojiSelect.appendChild(option);
}
var fontSelect = document.createElement('select');
fontSelect.setAttribute('id', 'mojiFont');
var font = ['ゴシック','明朝','筆記体','装飾','等幅'];
for(var i = 0; i < font.length; i++){
var option = document.createElement('option');
option.value = i;
var text = document.createTextNode(font[i]);
option.appendChild(text);
fontSelect.appendChild(option);
}
var boldCheck = document.createElement('input');
boldCheck.setAttribute('id', 'mojiBold');
boldCheck.setAttribute('type', 'checkbox');
boldCheck.setAttribute('value', 'bold');
var b = document.createElement('b');
var textNode = document.createTextNode(' B:');
b.appendChild(textNode);
var italicCheck = document.createElement('input');
italicCheck.setAttribute('id', 'mojiItalic');
italicCheck.setAttribute('type', 'checkbox');
italicCheck.setAttribute('value', 'italic');
var i = document.createElement('i');
var textNode = document.createTextNode(' I:');
i.appendChild(textNode);
var br = document.createElement('br');
$('#backButton').before(fillInput);
$('#backButton').before(fillLabel);
$('#backButton').before(textInput);
$('#backButton').before(textLabel);
$('#backButton').before(mojiSelect);
$('#backButton').before(fontSelect);
$('#backButton').before(b);
$('#backButton').before(boldCheck);
$('#backButton').before(i);
$('#backButton').before(italicCheck);
$('#backButton').before(br);
var mojiA = document.createElement('a');
mojiA.setAttribute('data-tool','moji');
mojiA.setAttribute('href', '#sketch');
var fillA = document.createElement('a');
fillA.setAttribute('data-tool','fill');
fillA.setAttribute('href', '#sketch');
$('.tools').after(fillA);
$('.tools').after(mojiA);
$("#moji").click(function(){$("[data-tool=moji]").click()});
$("#fill").click(function(){$("[data-tool=fill]").click()});
var exp = document.createElement('input');
exp.setAttribute('id', 'exportButton');
exp.setAttribute('type', 'button');
exp.setAttribute('value', 'エクスポート');
var imp = document.createElement('input');
imp.setAttribute('id', 'importButton');
imp.setAttribute('type', 'button');
imp.setAttribute('value', 'インポート');
$('#saveButton').after(imp);
$('#saveButton').after(exp);
$('#importButton').click(function(){
playback(stringToAction(colorToActionString()), 10);
});
$('#exportButton').click(function(){
actionStringToColor(actionToString());
});
var show = $('#_canvas').next().children();
show.html("ctrl+←:UNDO<br/>ctrl+→:REDO<br/>" + show.html());
function fill(e){
fillCanvas = canvas.context.getImageData(0, 0, canvas.el.width, canvas.el.height);
var pageX = e.pageX;
var pageY = e.pageY;
var offsetX = $('#sketch').offset().left;
var offsetY = $('#sketch').offset().top;
var x = Math.floor(pageX - offsetX);
var y = Math.floor(pageY - offsetY);
var fillRGB = canvas.color.match(/(\d|\.)+/g);
if(fillRGB[3] == undefined){
var alpha = 255;
}else{
var alpha = alphaToInt(fillRGB[3]);
}
var fillColor = ((Number(fillRGB[0]) << 24) + (Number(fillRGB[1]) << 16) + (Number(fillRGB[2]) << 8) + alpha)>>>0;
//console.log('fillColor>' + fillColor.toString(2));
//console.log('fillR>' + fillRGB[0] + ' fillG>' + fillRGB[1] + ' fillB>' + fillRGB[2] + ' fillA' + alpha);
//console.log('fillRbit>' + ((fillColor & 0xFF000000) >>> 24));
//console.log('fillGbit>' + ((fillColor & 0xFF0000) >> 16));
//console.log('fillBbit>' + ((fillColor & 0xFF00) >> 8));
//console.log('fillAbit>' + (fillColor & 0xFF));
var targetColor = getRGBA(x, y);
//console.log('targetRbit>' + ((targetColor & 0xFF000000) >>> 24));
//console.log('targetGbit>' + ((targetColor & 0xFF0000) >> 16));
//console.log('targetBbit>' + ((targetColor & 0xFF00) >> 8));
//console.log('targetAbit>' + (targetColor & 0xFF));
canvas.actions.push({
x: x,
y: y,
tool: canvas.tool,
fillColor: fillColor,
targetColor: targetColor,
fill:null
});
canvas.redraw();
}
function paint(x, y, fillColor, targetColor){
var color = getRGBA(x, y);
if(color == fillColor){
return;
}
fillRGBA(x, y, fillColor);
var rightX = x + 1;
while(rightX < fillCanvas.width){
var color = getRGBA(rightX, y);
if(color == targetColor){
fillRGBA(rightX, y, fillColor);
}else{
break;
}
rightX++;
}
var leftX = x -1;
while(leftX >= 0){
var color = getRGBA(leftX, y);
if(color == targetColor){
fillRGBA(leftX, y, fillColor);
}else{
break;
}
leftX--;
}
if(y -1 >= 0){
scanSeed(leftX, rightX, y-1, targetColor);
}
if(y + 1 < fillCanvas.width){
scanSeed(leftX, rightX, y+1, targetColor);
}
}
function scanSeed(leftX, rightX, y, targetColor){
var seed = false;
for(var x = leftX + 1; x < rightX; x++){
var color = getRGBA(x, y);
if(color == targetColor){
seed = true;
}else if(seed){
seeds.push({"x":x - 1, "y":y});
seed = false;
}
}
if(seed){
seeds.push({"x":rightX - 1, "y":y});
}
}
function fillRGBA(x, y, color) {
var img = fillCanvas.data;
var w = fillCanvas.width;
var h = fillCanvas.height;
var p = ((w * y) + x) * 4;
//console.log('beforeR>' + ((color & 0xFF000000) >>> 24));
//console.log('beforeG>' + ((color & 0xFF0000) >> 16));
//console.log('beforeB>' + ((color & 0xFF00) >> 8));
//console.log('beforeA>' + ((color & 0xFF)));
img[p] = (color & 0xFF000000) >>> 24;
img[p+1] = (color & 0xFF0000) >> 16;
img[p+2] = (color & 0xFF00) >> 8;
img[p+3] = color & 0xFF;
//console.log('afterR>' + img[p]);
//console.log('afterG>' + img[p+1]);
//console.log('afterB>' + img[p+2]);
//console.log('afterA>' + img[p+3]);
}
function fillRGB(x, y, color) {
//console.log('x:' + x + ' y:' + y);
var img = fillCanvas.data;
var w = fillCanvas.width;
var h = fillCanvas.height;
var p = ((w * y) + x) * 4;
//console.log('beforeR>' + img[p]);
//console.log('beforeG>' + img[p+1]);
//console.log('beforeB>' + img[p+2]);
//console.log('beforeA>' + img[p+3]);
img[p] = (color & 0xFF0000) >> 16;
img[p+1] = (color & 0xFF00) >> 8;
img[p+2] = color & 0xFF;
img[p+3] = 0xFF;
//console.log('afterR>' + img[p]);
//console.log('afterG>' + img[p+1]);
//console.log('afterB>' + img[p+2]);
//console.log('afterA>' + img[p+3]);
}
function getRGBA(x, y){
var img = fillCanvas.data;
var w = fillCanvas.width;
var h = fillCanvas.height;
var p = ((w * y) + x) * 4;
//console.log('getR>' + img[p]);
//console.log('getG>' + img[p+1]);
//console.log('getB>' + img[p+2]);
//console.log('getA>' + img[p+3]);
//console.log('putR>' + ((img[p] << 24)>>>0));
//console.log('putG>' + (img[p+1] << 16));
//console.log('putB>' + (img[p+2] << 8));
//console.log('putA>' + (img[p+3]));
//console.log(((Number(img[p]) << 24) + (Number(img[p+1]) << 16) + (Number(img[p+2]) << 8) + img[p+3])>>>0);
return ((img[p] << 24) + (img[p+1] << 16) + (img[p+2] << 8) + img[p+3])>>>0;
}
function getRGB(x, y){
//console.log('x:' + x + ' y:' + y);
var img = fillCanvas.data;
var w = fillCanvas.width;
var h = fillCanvas.height;
var p = ((w * y) + x) * 4;
return ((img[p] << 16) + (img[p+1] << 8) + (img[p+2]));
}
function getRGBAString(color){
return 'rgba('
+ (color & 0xFF000000) >>> 24 + ', '
+ (color & 0xFF0000) >> 16 + ', '
+ (color & 0xFF00) >> 8 + ', '
+ (color & 0xFF) + ')';
}
function getRGBString(color){
return 'rgb('
+ ((color & 0xFF0000) >> 16) + ', '
+ ((color & 0xFF00) >> 8) + ', '
+ (color & 0xFF) + ')';
}
function alphaToInt(floatAlpha){
return Math.floor(Number(floatAlpha * 255));
}
function alphaToFloat(intAlpha){
return Math.floor(intAlpha / 255 * 100) * 100;
}
$.sketch.tools.fill= {
onEvent: function(e) {
switch (e.type) {
case 'mousedown':
case 'touchstart':
fill(e);
break;
}
},
draw: function(action){
if(action.fill){
fillCanvas = action.fill;
}else{
var fillColor = action.fillColor;
fillCanvas = canvas.context.getImageData(0, 0, canvas.el.width, canvas.el.height);
var targetColor = action.targetColor;
seeds = [{
'x':Number(action.x),
'y':Number(action.y)
}];
//var start = new Date();
while(seeds.length > 0){
var seed = seeds.shift();
paint(seed.x, seed.y, fillColor, targetColor);
}
//var end = new Date();
//console.log(end - start + 'msec');
action.fill = fillCanvas;
}
return canvas.context.putImageData(fillCanvas, 0, 0);
}
}
function drawText(e){
var pageX = e.pageX;
var pageY = e.pageY;
var offsetX = $('#sketch').offset().left;
var offsetY = $('#sketch').offset().top;
var x = Math.floor(pageX - offsetX);
var y = Math.floor(pageY - offsetY);
var context = canvas.context;
var text = window.prompt("文字を入力。");
if(!text){
text= '';
}
var str = text.match(/^(kyaha!|\:v)(.*)/i);
var mode = '';
if(str != null){
var mode = str[1];
var text = str[2];
}
str = text.match(/^(?:usa|\[)(.*)(?:min|\])(.*)/i);
var mojiFont;
if(str != null && str[1] != null){
mojiFont = str[1];
text = str[2];
}else{
var fontFamily = ['sans-serif','serif','cursive','fantasy','monospace'];
mojiFont = fontFamily[$('#mojiFont').val()];
}
text = text.replace(/nana|\\n/g, "\n");
var mojiSize = $('#mojiSize').val();
if($('#mojiBold:checked').val()){
var mojiBold = $('#mojiBold:checked').val() + ' ';
}else{
var mojiBold = ' ';
}
if($('#mojiItalic:checked').val()){
var mojiItalic = $('#mojiItalic:checked').val() + ' ';
}else{
var mojiItalic = ' ';
}
canvas.actions.push({
x: x,
y: y,
tool: canvas.tool,
color: canvas.color,
font: mojiBold + mojiItalic + mojiSize + 'px ' + mojiFont,
mode: mode,
text: text
});
canvas.redraw();
}
$.sketch.tools.moji = {
onEvent: function(e) {
switch (e.type) {
case 'mousedown':
case 'touchstart':
drawText(e);
break;
}
},
draw: function(action){
var context = canvas.context;
context.fillStyle = action.color;
context.font = action.font;
context.baseline = 'top';
return fillText(context, action.mode, action.text, action.x, action.y);
}
}
function fillText(context, mode, text, x, y){
var lines = text.split('\n');
var h = context.measureText("あ").width;
jQuery.each(lines, function(i, line) {
if(mode == ''){
context.textAlign = 'left'
context.fillText(this, x, y+h*i);
}else{
jQuery.each(line, function(j, char){
context.textAlign = 'center';
context.fillText(char, x - h*i, y+h*j);
});
}
});
}
function actionToString(){
var actionString = '';
var actDel = '!';
var propDel = '~';
var tools = {
marker: 'm',
eraser: 'e',
moji: 's',
fill: 'f'
};
jQuery.each(canvas.actions, function(i, action){
if(tools[action.tool]){
actionString += actDel + tools[action.tool];
switch(action.tool){
case 'marker':
case 'eraser':
var actionX = Math.floor(action.events[0].x);
var actionY = Math.floor(action.events[0].y);
var beforeX = actionX;
var beforeY = actionY;
actionString += lpad(actionX, 3, '0') + lpad(actionY, 3, '0') + lpad(action.size, 3, '0') + action.color.replace(/ /g, '') + propDel;
jQuery.each(action.events, function(j, event){
actionX = Math.floor(event.x);
actionY = Math.floor(event.y);
actionString += String.fromCharCode((actionX - beforeX + 64), (actionY - beforeY + 64));
beforeX = actionX;
beforeY = actionY;
});
break;
case 'moji':
actionString += lpad(action.x, 3, '0') + lpad(action.y, 3, '0') + action.mode + propDel + action.color + propDel + action.font + propDel + action.text;
break;
case 'fill':
actionString += lpad(action.x, 3, '0') + lpad(action.y, 3, '0') + propDel + action.fillColor + propDel + action.targetColor;
break;
}
}
});
actionString = actionString.substr(1);
return actionString;
}
function actionStringToColor(actionString){
console.log('ExportString'+actionString);
//var undefCharCode = 35;
var ch = canvas.el.height;
var m = -10;
var w = 1;
var h = 1;
//canvas.el.height += Math.floor((actionString.length+3)/(canvas.el.width+m)/n)+10;
fillCanvas = canvas.context.getImageData(0, 0, canvas.el.width, canvas.el.height);
fillN(1, 0, w, h, 0x000000);
for(var i = 0; i < actionString.length/3; i++){
var c1 = actionString.charCodeAt(i*3);
var c2 = actionString.charCodeAt(i*3 + 1);
var c3 = actionString.charCodeAt(i*3 + 2);
if(!c1){c1 = 35;}
if(!c2){c2 = 35;}
if(!c3){c3 = 35;}
var color = (c1 << 16) + (c2 << 8) + c3;
//console.log('x>' + (i+2)%canvas.el.width + ' y>' + (Math.floor((i+2)/canvas.el.width) + h));
fillN(((i+1)*w)%(canvas.el.width+m)+1, Math.floor(((i+1)*w)/(canvas.el.width+m))*h, w, h, color);
}
fillN(((i+1)*w)%(canvas.el.width+m)+1, Math.floor(((i+1)*w)/(canvas.el.width+m))*h, w, h, 0x000000);
orgActions = canvas.actions;
canvas.actions = [''];
var beforeBaseImage = canvas.baseImageURL;
canvas.redraw();
canvas.context.putImageData(fillCanvas, 0, 0);
var src = canvas.el.toDataURL('imgae/png');
canvas.setBaseImageURL(src);
canvas.actions = orgActions;
canvas.redraw();
}
function fillN(x, y, w, h, color){
for(var i = 0; i < w; i++){
for(var j = 0; j < h; j++){
fillRGB(x + i, y + j, color);
}
}
}
function colorToActionString(){
fillCanvas = canvas.context.getImageData(0, 0, canvas.el.width, canvas.el.height);
var actionString = '';
var undefCharCode = 35;
var ch = 1;
var m = -10;
var w = 1;
var h = 1;
var c = getRGB(1, 0);
if(c!=0x000000){return;}
var i = 0;
while(i < canvas.el.width * canvas.el.height / 4){
var color = getRGB(((i+1)*w)%(canvas.el.width+m)+1, (Math.floor(((i+1)*h)/(canvas.el.width+m)))*h);
if(color==0x000000){break;}
c1 = (color&0xFF0000)>>16;
c2 = (color&0xFF00)>>8;
c3 = (color&0xFF);
i++;
actionString += String.fromCharCode(c1);
actionString += String.fromCharCode(c2);
actionString += String.fromCharCode(c3);
}
console.log('ImportString' + actionString.replace(new RegExp(String.fromCharCode(undefCharCode), 'g'), ''));
return actionString.replace(new RegExp(String.fromCharCode(undefCharCode), 'g'), '');
}
function stringToAction(actionString){
if(!actionString){alert('描画情報が見つかりませんでした。');return [];}
if(!confirm('お絵かきを再生します。\n※再生を開始すると、あなたの描いた絵の情報はクリアされます')){return [];}
canvas.clear();
var actionDelimiter = '!';
var propDelimiter = '~';
var splitActions = actionString.split(actionDelimiter);
var actions =[];
var tools = {
m: 'marker',
e: 'eraser',
s: 'moji',
f: 'fill'
};
jQuery.each(splitActions, function(i, actionsLine){
var splitAction = actionsLine.split(propDelimiter);
var actionLine = splitAction[0];
var tool = tools[actionLine.substr(0, 1)];
switch(tool){
case 'marker':
case 'eraser':
var bX = actionLine.substr(1, 3);
var bY = actionLine.substr(4, 3);
var size = actionLine.substr(7, 3);
var color = actionLine.substr(10);
var action = {
tool: tool,
size: parseFloat(size),
color: color,
events: []
}
action.events.push({x: bX, y: bY});
var eventLine = splitAction[1];
for(var i = 1; i <= eventLine.length/2; i++){
action.events.push({
x: Number(action.events[i-1].x) + Number(eventLine.charCodeAt(i*2) - 64),
y: Number(action.events[i-1].y) + Number(eventLine.charCodeAt(i*2+1) - 64)});
}
break;
//case 'moji':
// var action = {
// tool: tool,
// mode: actionLine.substr(1, 1),
// color: splitAction[1],
// font: splitAction[2],
// text: splitAction[3]
// };
// break;
case 'fill':
var action = {
tool: tool,
x: actionLine.substr(1, 3),
y: actionLine.substr(4, 3),
fillColor: splitAction[1],
targetColor: splitAction[2]
};
break;
}
actions.push(action);
});
return actions;
}
function playback(actions, time){
console.log('playback');
console.log(actions);
if(actions.length == 0){return;}
var painting = false;
var id1 = setInterval(function(){
if(actions[0]){
var action = actions[0];
if(!painting){
switch(action.tool){
case 'marker':
case 'eraser':
var i = 0;
var events = action.events;
var id2 = setInterval(function(){
painting = true;
if(events && i+1 < events.length){
canvas.context.beginPath();
canvas.context.moveTo(events[i].x, events[i].y);
canvas.context.lineJoin = 'round';
canvas.context.lineCap = 'round';
canvas.context.lineTo(events[i+1].x, events[i+1].y);
canvas.context.strokeStyle = action.color;
canvas.context.lineWidth = action.size;
canvas.context.stroke();i++;
}else{
clearInterval(id2);
painting = false;
canvas.actions.push(actions.shift());
canvas.redraw();
}
},time);
break;
case 'moji':
case 'fill':
painting = true;
canvas.actions.push(actions.shift());
canvas.redraw();
painting = false;
break;
}
}
}else{
clearInterval(id1);
}
},time*4);
}
function lpad(string, length, char){
var padding;
for(var i = 1; i <= length; i++){
padding += char;
}
return (padding + string).slice(-length);
}
function keydownEvent(e, keyNum, popList, pushList){
if(e.which === keyNum && e.ctrlKey && popList.length > 0){
pushList.push(popList.pop());
canvas.redraw();
}
}
$(document).keydown(function(e){
keydownEvent(e, 37, canvas.actions, drawRedo);
keydownEvent(e, 39, drawRedo, canvas.actions);
});
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。