非公開 open2chOekakiEX

    @@ -4,60 +4,27 @@ * @require https://googledrive.com/host/0B1BW1N6rqpWFNjdEazFaNm1XSjA/jquery-ui-1.10.4.custom.min.js * @require https://googledrive.com/host/0B1BW1N6rqpWFR2NCRFFUbmJzN0U/jquery-ui-1.10.4.custom.min.css * @require https://googledrive.com/host/0B1BW1N6rqpWFNjdEazFaNm1XSjA/spline.js + * @require https://googledrive.com/host/0B1BW1N6rqpWFNjdEazFaNm1XSjA/replay.js + * @require https://googledrive.com/host/0B1BW1N6rqpWFNjdEazFaNm1XSjA/version.js + * @require https://googledrive.com/host/0B1BW1N6rqpWFNjdEazFaNm1XSjA/manual.js * @private */ - //【更新履歴】 -var VERSION= 'Ver8.1.0'; -var VERSION_INFO = { -'Ver1.0.0': {Date:'2014/03/29', Info:'文字入力機能追加'}, -'Ver1.1.0': {Date:'2014/03/29', Info:'お絵かき機能ツールメニュー内に文字入力機能を追加 文字サイズ指定追加'}, -'Ver1.2.0': {Date:'2014/03/30', Info:'フォント指定、修飾指定追加'}, -'Ver1.3.0': {Date:'2014/03/30', Info:'線描画と文字入力のUNDO/REDO機能追加 イタリックが効かないバグ修正'}, -'Ver2.0.0': {Date:'2014/03/31', Info:'塗りつぶし機能追加'}, -'Ver2.1.0': {Date:'2014/03/31', Info:'塗りつぶし機能にUNDO/REDO機能追加'}, -'Ver2.1.1': {Date:'2014/03/31', Info:'IE、Chromeで塗りつぶしが効かないバグ修正'}, -'Ver2.2.0': {Date:'2014/04/01', Info:'背景色以外の色も塗りつぶせるように修正'}, -'Ver2.3.0': {Date:'2014/04/01', Info:'透明度を指定して塗りつぶせるように修正'}, -'Ver2.4.0': {Date:'2014/04/02', Info:'文字入力でフォントの直接指定&改行入力&縦書出力に対応'}, -'Ver3.0.0': {Date:'2014/04/05', Info:'お絵かき再生機能追加'}, -'Ver3.1.0': {Date:'2014/04/06', Info:'お絵かき再生機能のエクスポート方式をテキストから画像埋め込みに変更'}, -'Ver3.2.0': {Date:'2014/04/10', Info:'お絵かき再生機能で塗りつぶしと消しゴムが再生できるように修正 線を引くときにちらつくバグを修正'}, -'Ver4.0.0': {Date:'2014/04/19', Info:'レイヤ機能追加'}, -'Ver4.1.0': {Date:'2014/04/20', Info:'レイヤの表示/非表示切替機能追加 最前面のレイヤしか投稿できないバグ修正 レイヤの移動に関するバグ修正 コラボするとレイヤの重なりがおかしくなるバグ修正'}, -'Ver4.1.1': {Date:'2014/04/24', Info:'IE10未満で起動できないバグを修正'}, -'Ver4.1.2': {Date:'2014/04/28', Info:'IEでプレビューが正常に表示できないバグを修正'}, -'Ver4.2.0': {Date:'2014/04/29', Info:'レイヤ機能をデフォルトではオフに変更 レイヤ機能オン時の性能向上'}, -'Ver4.2.1': {Date:'2014/04/29', Info:'絵が投稿できないバグを修正'}, -'Ver4.3.0': {Date:'2014/04/29', Info:'線の太さ、文字の大きさを追加'}, -'Ver5.0.0': {Date:'2014/05/01', Info:'図形描画機能追加 レイヤ機能をデフォルトでオンに変更 「進」ボタン追加'}, -'Ver5.1.0': {Date:'2014/05/03', Info:'文字入力後に文字位置を移動できる機能を追加 マニュアル表示追加'}, -'Ver5.1.1': {Date:'2014/05/03', Info:'一部文字が投稿できないバグを修正'}, -'Ver5.2.0': {Date:'2014/05/05', Info:'文字入力後に文字を回転できる機能を追加 IEで文字のフォント直接指定が機能していなかったバグを修正'}, -'Ver5.3.0': {Date:'2014/05/06', Info:'お絵かき中にページ遷移しようとすると確認ダイアログが出る機能を追加'}, -'Ver5.4.0': {Date:'2014/05/07', Info:'お絵かき投稿前に絵の内容を確認できる機能を追加'}, -'Ver6.0.0': {Date:'2014/05/10', Info:'選択範囲の切り取り&コピー機能を追加 文字や図形のみの絵が投稿できないバグを修正'}, -'Ver6.0.1': {Date:'2014/05/17', Info:'キャンバスのサイズ変更に対応 範囲選択時に表示する枠の線幅を修正 塗り潰し後に性能劣化するバグ修正'}, -'Ver7.0.0': {Date:'2014/05/25', Info:'手ブレ補正機能(α版)公開'}, -'Ver7.1.0': {Date:'2014/05/26', Info:'手ブレ補正機能(β版)公開 新着お知らせ機能追加'}, -'Ver7.2.0': {Date:'2014/05/27', Info:'UI変更'}, -'Ver7.3.0': {Date:'2014/05/28', Info:'手ブレ補正機能正式版公開 文字入力でフォント指定が効かないバグを修正'}, -'Ver8.0.0': {Date:'2014/06/01', Info:'拡大・縮小機能追加'}, -'Ver8.1.0': {Date:'2014/06/02', Info:'Chrome以外のブラウザでの消しゴム機能対応(仮)'} -}; +var VERSION= 'Ver9.0.0'; var PREVIEW_SIZE = 0.2; var MARGIN = 0; var settings = { - version: localStorage.getItem('version') || 'Ver0.0.0', + version: localStorage.getItem('version') || 'Ver0.0.0', checkVersion: localStorage.getItem('checkVersion') || 1, - saveType: localStorage.getItem('saveType') || 1, - saveCycle: localStorage.getItem('saveCycle') || 5, - saveMaxAge: localStorage.getItem('saveMaxAge') || 1 + saveType: localStorage.getItem('saveType') || 1, + saveCycle: localStorage.getItem('saveCycle') || 10, + saveMaxAge: localStorage.getItem('saveMaxAge') || 2, + layerOn: localStorage.getItem('layerOn') || 1 } -//var savedImages = loadSavedImages(); +var savedImages; var canvas = $('#sketch').sketch(); var drawRedo = []; @@ -70,63 +37,19 @@ var scaleH; var degree; -var layerOnFlag = true; -//var layerOnFlag = false; - var icons = { - rotateIcon: 'rotate2.png', - curveIcon: 'curve.png', - mojiIcon: 'moji.png', - figureIcon: 'figure.png', - selectionIcon: 'selection.png', - saveIcon: 'save.png', - settingsIcon: 'settings.png', + rotateIcon: 'rotate2.png', + curveIcon: 'curve.png', + mojiIcon: 'moji.png', + figureIcon: 'figure.png', + selectionIcon: 'selection.png', + saveIcon: 'save.png', + settingsIcon: 'settings.png', rotateRightIcon: 'rotateRight.png', - rotateLeftIcon: 'rotateLeft.png' + rotateLeftIcon: 'rotateLeft.png', + reloadIcon: 'reload.png' }; - -var manual = "\ -<FONT size=+1><B>【主な機能】</B></FONT><BR><BR>\ -・<B>線描画機能</B><BR>\ -  - 選べる線の太さを拡張<BR>\ -<BR>\ -・<B>手ぶれ補正機能</B><BR>\ -  - 描いた線を滑らかに補正<BR>\ -<BR>\ -・<B>文字入力機能</B><BR>\ -  - ツールメニューの[A]を選択して、文字を書きたい場所をクリック<BR>\ -  - 色、サイズ、フォント、装飾をツールメニューから選択可能<BR>\ -  - 先頭に『!』と入力すると縦書で出力(フォント指定よりも前に入力)<BR>\ -  - 先頭に『[フォント名]』と入力すると指定したフォントで文字を出力<BR>\ -  - 文字列中に『\\n』を入れるとそこで改行<BR>\ - - 他の操作を行うまで文字の移動、回転が可能<BR>\ -<BR>\ -・<B>塗りつぶし機能</B><BR>\ -  - ツールメニューのバケツマークを選択して、塗りつぶしたい箇所をクリック<BR>\ -  - 色、透明度を選択可能<BR>\ -  <BR>\ -・<B>図形描画機能</B><BR>\ -  - ツールメニューの「図形」プルダウンから図形を選択して、図形を描きたい範囲を選択<BR>\ -  - 直線、四角形、円を描画可能<BR>\ -<BR>\ -・<B>範囲選択機能</B><BR>\ -  - ツールメニューの「選択」プルダウンから選択後の動作を選択して、範囲を選択<BR>\ -  - 選択範囲に枠が表示されるのでドラッグ&ドロップで移動<BR>\ -<BR>\ -・<B>お絵かき再生機能(現在停止中)</B><BR>\ -  <S>- 絵を描いた後「出力」ボタンを押すと絵の情報が画像内に埋め込まれる</S><BR>\ -  <S>- 情報が埋め込まれた絵をコラボして「再生」ボタンを押すと再生</S><BR>\ -  <BR>\ -・<B>レイヤ機能</B><BR>\ -  - キャンバス下の「機能ON」をクリックすることでレイヤ機能が有効化<BR>\ -  - 「追加」をクリックでレイヤを追加<BR>\ -  - プレビューをクリックでレイヤの選択<BR>\ -  - 「表示」をクリックで選択したレイヤの表示/非表示切替<BR>\ -  - 「←」「→」で選択したレイヤの位置(前面、背面)を入れ替え<BR>\ -<BR>\ -・<B>ショートカットキー</B><BR>\ -  - [ctrl + ←]:UNDO <BR>\ -  - [ctrl + →]:REDO"; +loadIcon(icons); var browser = checkBrowser(); checkNewVersion(); @@ -135,14 +58,20 @@ initManual(); setCanvasScale(); +var drawTimer = ''; +var saveTimer = ''; +startAutoSave(); -function checkNewVersion(){ - if(!settings.checkVersion) return; -console.log(settings.version); - if(settings.version != VERSION){ - localStorage.setItem('version', VERSION); - alert(VERSION + ' ' + VERSION_INFO[VERSION].Date + ' ' + VERSION_INFO[VERSION].Info); +function startAutoSave(){ + clearInterval(saveTimer); + + if(settings.saveCycle=='任意'){ + autoSave = false; + saveTimer = ''; + }else{ + autoSave = true; + saveTimer = setInterval(saveImage, settings.saveCycle * 60 * 1000); } } @@ -150,95 +79,129 @@ var ua = window.navigator.userAgent.toLowerCase(); var ver = window.navigator.appVersion.toLowerCase(); var name = ''; - - if (ua.indexOf('msie') != -1){ - if (ver.indexOf('6.') != -1){ - name = 'ie6'; - }else if (ver.indexOf('7.') != -1){ - name = 'ie7'; - }else if (ver.indexOf('8.') != -1){ - name = 'ie8'; - }else if (ver.indexOf('9.') != -1){ - name = 'ie9'; - }else if (ver.indexOf('10.') != -1){ - name = 'ie10'; - }else{ - name = 'ie'; - } - }else if(ua.indexOf('trident/7') != -1){ - name = 'ie11'; - }else if (ua.indexOf('chrome') != -1){ - name = 'chrome'; - }else if (ua.indexOf('safari') != -1){ - name = 'safari'; - }else if (ua.indexOf('opera') != -1){ - name = 'opera'; - }else if (ua.indexOf('firefox') != -1){ - name = 'firefox'; + if(ua.indexOf('msie') != -1){ + if (ver.indexOf('6.') != -1) {name = 'ie6';} + else if(ver.indexOf('7.') != -1) {name = 'ie7';} + else if(ver.indexOf('8.') != -1) {name = 'ie8';} + else if(ver.indexOf('9.') != -1) {name = 'ie9';} + else if(ver.indexOf('10.') != -1) {name = 'ie10';} + else {name = 'ie';} + }else if(ua.indexOf('trident/7') != -1){name = 'ie11';} + else if(ua.indexOf('chrome') != -1) {name = 'chrome';} + else if(ua.indexOf('safari') != -1) {name = 'safari';} + else if(ua.indexOf('opera') != -1) {name = 'opera';} + else if(ua.indexOf('firefox') != -1) {name = 'firefox'; } return name; } +function checkNewVersion(){ + if(settings.checkVersion && settings.version != VERSION){ + localStorage.setItem('version', VERSION); + alert(VERSION + ' ' + VERSION_INFO[VERSION].Date + ' ' + VERSION_INFO[VERSION].Info); + } +} + function saveSettings(){ -console.log('saveStart'); for(var key in settings){ -console.log(key + ':' + settings[key]); localStorage.setItem(key, settings[key]); } -console.log('saveEnd'); + startAutoSave(); } -/* + + $('#saveButton').unbind(); $('#saveButton').click(function(){ -console.log('click'); - saveImage($('#layerCanvas1')[0].toDataURL()); + saveImage('manual'); + loadSavedImages(); }); -*/ -function saveImage(src){ + +function saveImage(type){ console.log('saveImageStart'); - var saveNum = localStorage.getItem('saveNum') + 1 || 1 - if(saveNum > settings.saveMaxAge){ - saveNum = 1; - } + if(!autoSave && !type) return; + + var saveNum = parseInt(localStorage.getItem('saveNum')) + 1 || 1; + if(saveNum > settings.saveMaxAge) saveNum = 1; var date = new Date(); var name = [ date.getFullYear(), ('0' + (date.getMonth() + 1)).slice(-2), - ('0' + date.getDate()).slice(-2), - ('0' + date.getHours()).slice(-2) + - ('0' + date.getMinutes()).slice(-2) + - ('0' + date.getSeconds()).slice(-2) - ].join( '-' ) + '.png'; + ('0' + date.getDate()).slice(-2) + ].join( '-' ) + ' ' + + ('0' + date.getHours()).slice(-2) + ':' + + ('0' + date.getMinutes()).slice(-2) + ':' + + ('0' + date.getSeconds()).slice(-2); + + var mergeCanvas = $('<canvas>').attr({ + width: realW, + height: realH + }); + var ctx = mergeCanvas[0].getContext('2d'); + + var saveImages = []; + $('canvas[id^=preview]').each(function(i){ + saveImages.push({ + name: name + '_layer' + (i+1), + src: $(this)[0].toDataURL() + }); - var saveImage = { + ctx.drawImage($(this)[0], 0, 0); + }); + saveImages.unshift({ name: name, - src: src - } + src: mergeCanvas[0].toDataURL() + }); + localStorage.setItem('saveNum', saveNum); - localStorage.setItem('savedImage' + saveNum, JSON.stringify(saveImage)); + localStorage.setItem('savedImage' + saveNum, JSON.stringify(saveImages)); console.log('saveImageEnd'); -loadSavedImage(saveNum); } - -function loadSavedImage(num){ - var loadImage = JSON.parse(localStorage.getItem('savedImage' + num)); - - var img = $('<img>', { - id: 'savedImage' + loadImage.age, - src: loadImage.src - }).appendTo($('#oekakiCanvas')); - var a = $('<a>', { - id: 'downloadLink' + loadImage.age, - download: loadImage.name, - href: loadImage.src, - text: loadImage.name - }).appendTo($('#oekakiCanvas')); +function loadSavedImages(){ +console.log('loadImageStart'); + var loadImages = []; + + for(var i = 1; i <= settings.saveMaxAge; i++){ + var s = localStorage.getItem('savedImage' + i); + var loadImage = JSON.parse(s); + if(!loadImage) break; + loadImages.push(loadImage); + } + if(!loadImages.length > 0) return; + + for(var i in loadImages){ + var m = parseInt(i) + 1; + var tabName = loadImages[i][0].name.replace(/\_.*/, ''); + var loadImage = loadImages[i]; + $('#savedImage_' + m).remove(); + $('#savedImageTabList').append( + $('<li>', {id: 'savedImage_' + m}).append($('<a>', {href: '#tab-saved-image-' + m, text: tabName.slice(0, 16)})) + ); + + $('#tab-saved-image-' + m).remove(); + $('#savedImageTab').append($('<div>', {id: 'tab-saved-image-' + m})); + for(var j in loadImage){ + var a = $('<a>', { + id: 'downloadLink_' + loadImage[j].name, + download: loadImage[j].name + '.png', + href: loadImage[j].src, + }).append( + $('<img>', { + id: 'savedImage_' + loadImage[j].name, + src: loadImage[j].src, + title: loadImage[j].name, + style: ' border: solid ' + ((j==0)?'3pt #F00':'1pt') + ';' + + ' width: ' + ((j==0)?realW-30:realW/3-10) + ';' + + ' background-image: url(http://open2ch.net/image/oekaki/background.png)' + })); + ($('#tab-saved-image-' + m)).append(a); + } + } + $('#savedImageTab').tabs('refresh'); +console.log('loadImageEnd'); } - - var correctionLv = 8; var interval = 40; var interpolate = 4; @@ -249,30 +212,16 @@ var menu = $('<div>', {id: 'menu'}).append( $('<ul>').append( - $('<li>').append( - $('<a>', {href: '#tab-kaku'}).append($('label[for=kaku]')) - ), - $('<li>').append( - $('<a>', {href: '#tab-curve'}) - ), - $('<li>').append( - $('<a>', {href: '#tab-kesu'}).append($('label[for=kesu]')) - ), - $('<li>').append( - $('<a>', {href: '#tab-spoit'}).append($('label[for=spoit]')) - ), - $('<li>').append( - $('<a>', {href: '#tab-fill'}) - ), - $('<li>').append( - $('<a>', {href: '#tab-moji'}) - ), - $('<li>').append( - $('<a>', {href: '#tab-figure'}) - ), - $('<li>').append( - $('<a>', {href: '#tab-selection'}) - ) + $('<li>').append($('<a>', {href: '#tab-kaku'}).append($('label[for=kaku]'))), + $('<li>').append($('<a>', {href: '#tab-curve'})), + $('<li>').append($('<a>', {href: '#tab-kesu'}).append($('label[for=kesu]'))), + $('<li>').append($('<a>', {href: '#tab-spoit'}).append($('label[for=spoit]'))), + $('<li>').append($('<a>', {href: '#tab-fill'})), + $('<li>').append($('<a>', {href: '#tab-moji'})), + $('<li>').append($('<a>', {href: '#tab-figure'})), + $('<li>').append($('<a>', {href: '#tab-selection'})), + $('<li>').append($('<a>', {href: '#tab-save'})) +// $('<li>').append($('<a>', {href: '#tab-settings'})) ), $('<div>', {id: 'tab-kaku'}), $('<div>', {id: 'tab-curve'}), @@ -281,7 +230,9 @@ $('<div>', {id: 'tab-fill'}), $('<div>', {id: 'tab-moji'}), $('<div>', {id: 'tab-figure'}), - $('<div>', {id: 'tab-selection'}) + $('<div>', {id: 'tab-slection'}), + $('<div>', {id: 'tab-save'}) +// $('<div>', {id: 'tab-settings'}) ).tabs(); $('#upImage').after(menu); @@ -291,9 +242,6 @@ function makeMenuElement(){ $('#_canvas').attr('style', 'position: relative'); - loadIcon(icons); - - var scaleSize = [50, 75, 100, 125, 150, 200, 250, 300, 400, 500]; var scaleSelect = $('<select>', { id: 'canvasScale', @@ -308,18 +256,14 @@ } $('#canvasSize').after(scaleSelect).after($('<b>').text('x')); - var penType = ['ブラシ','鉛筆']; - var penSelect = $('<select>', { - id: 'penType' - }); + var penSelect = $('<select>', {id: 'penType'}); for(var i in penType){ $('<option>', { value: i, text: penType[i], }).appendTo(penSelect); } - var penSize = [0.5, 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72, 80, 100]; var penSizeSelect = $('#psize'); penSizeSelect.children().remove(); @@ -331,11 +275,8 @@ }).appendTo(penSizeSelect); } - var curveImg = $('#curveIcon'); curveImg[0].style.display = ''; - $('a[href=#tab-curve]').append(curveImg); - var corrections = [2, 4, 8, 16, 32, 64]; var correctionLvText = $('<b>', {text: '補正レベル'}); var correctionSelect = $('<select>', { @@ -349,7 +290,6 @@ selected: (i==2)?true:false }).appendTo(correctionSelect); } - var intervals = [5, 10, 20, 40, 80, 120, 160]; var intervalText = $('<b>', {text: ' 粒度'}); var intervalSelect = $('<select>', { @@ -363,7 +303,6 @@ selected: (i==3)?true:false }).appendTo(intervalSelect); } - var interpolates = [2, 4, 8, 12, 16]; var interpolateText = $('<b>', {text: ' なめらかさ'}); var interpolateSelect = $('<select>', { @@ -377,7 +316,6 @@ selected: (i==1)?true:false }).appendTo(interpolateSelect); } - var controllPointText = $('<b>', {text: ' 制御点表示:'}); var controllPointCheck = $('<input>', { id: 'controllPoint', @@ -385,18 +323,13 @@ checked: showPointFlag, click: function(){showPointFlag = $(this)[0].checked} }); - var curveOption = $('<div>', {id: 'curveOption'}) - .append(correctionLvText) - .append(correctionSelect) - .append(intervalText) - .append(intervalSelect) - .append(interpolateText) - .append(interpolateSelect) - .append(controllPointText) - .append(controllPointCheck); + .append(correctionLvText) .append(correctionSelect) + .append(intervalText) .append(intervalSelect) + .append(interpolateText) .append(interpolateSelect) + .append(controllPointText).append(controllPointCheck); $('#tab-curve').append(curveOption); - + $('a[href=#tab-curve]').append(curveImg); var fillImg = $('<img>', { id: 'fillImg', @@ -404,16 +337,11 @@ }); $('a[href=#tab-fill]').append(fillImg); - var mojiImg = $('#mojiIcon'); mojiImg[0].style.display = ''; - $('a[href=#tab-moji]').append(mojiImg); - var mojiSize = [4, 8, 10, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72, 80, 100]; var mojiSizeText = $('<b>', {text: '文字サイズ:'}); - var mojiSizeSelect = $('<select>', { - id: 'mojiSize' - }); + var mojiSizeSelect = $('<select>', {id: 'mojiSize'}); for(var i in mojiSize){ $('<option>', { value: mojiSize[i], @@ -421,40 +349,34 @@ selected: (i==7)?true:false }).appendTo(mojiSizeSelect); } - var fontType = ['ゴシック','明朝','筆記体','装飾','等幅']; var fontTypeText = $('<b>', {text: ' フォント:'}); - var fontTypeSelect = $('<select>', { - id: 'mojiFont' - }); + var fontTypeSelect = $('<select>', {id: 'mojiFont'}); for(var i in fontType){ $('<option>', { value: i, text: fontType[i], }).appendTo(fontTypeSelect); } - var boldText = $('<b>', {text: ' B:'}); var boldCheck = $('<input>', { id: 'mojiBold', type: 'checkbox', value: 'bold' }); - var italicText = $('<i>', {text: ' I:'}); var italicCheck = $('<input>', { id: 'mojiItalic', type: 'checkbox', value: 'italic' }); - var mojiOption = $('<div>', {id: 'mojiOption'}) .append(mojiSizeText).append(mojiSizeSelect) .append(fontTypeText).append(fontTypeSelect) - .append(boldText).append(boldCheck) - .append(italicText).append(italicCheck); + .append(boldText) .append(boldCheck) + .append(italicText) .append(italicCheck); $('#tab-moji').append(mojiOption); - + $('a[href=#tab-moji]').append(mojiImg); var figureImg = $('#figureIcon'); figureImg[0].style.display = ''; @@ -462,30 +384,22 @@ var figureType = ['-','□','■','○','●']; var figureTypeText = $('<b>', {text: '図形:'}); - var figureTypeSelect = $('<select>', { - id: 'figureType' - }); + var figureTypeSelect = $('<select>', {id: 'figureType'}); for(var i in figureType){ $('<option>', { value: i, text: figureType[i], }).appendTo(figureTypeSelect); } - var figureOption = $('<div>', {id: 'figureOption'}) .append(figureTypeText).append(figureTypeSelect); $('#tab-figure').append(figureOption); - var selectionImg = $('#selectionIcon'); selectionImg[0].style.display = ''; - $('a[href=#tab-selection]').append(selectionImg); - var selectionTypeText = $('<b>', {text: '動作'}); var selectionType = ['切り取り','コピー']; - var selectionTypeSelect = $('<select>', { - id: 'selectionType' - }); + var selectionTypeSelect = $('<select>', {id: 'selectionType'}); for(var i in selectionType){ $('<option>', { value: i, @@ -495,7 +409,89 @@ var selectionOption = $('<div>', {id: 'selectionOption'}) .append(selectionTypeText).append(selectionTypeSelect); $('#tab-selection').append(selectionOption); + $('a[href=#tab-selection]').append(selectionImg); + var saveImg = $('#saveIcon'); + saveImg[0].style.display = ''; + var saveMaxAgeText = $('<b>', {text: '保存数:'}); + var saveMaxAge = [1, 2, 3]; + var saveMaxAgeSelect = $('<select>', { + id: 'saveMaxAge', + change: function(){ + settings.saveMaxAge = $(this).val(); + saveSettings(); + } + }); + for(var i in saveMaxAge){ + $('<option>', { + value: saveMaxAge[i], + text: saveMaxAge[i], + selected: (saveMaxAge[i]==settings.saveMaxAge)?true:false, + }).appendTo(saveMaxAgeSelect); + } + var saveCycleText = $('<b>', {text: ' 間隔:'}); + var saveCycle = ['任意', '1', '3', '5', '10', '15', '20', '30']; + var saveCycleSelect = $('<select>', { + id: 'saveCycle', + change: function(){ + settings.saveCycle = $(this).val(); + saveSettings(); + } + }); + for(var i in saveCycle){ + $('<option>', { + value: saveCycle[i], + text: saveCycle[i] + ((i==0)? '':'分'), + selected: (saveCycle[i]==settings.saveCycle)?true:false, + }).appendTo(saveCycleSelect); + } + var saveOption = $('<div>', {id: 'saveOption'}) + .append(saveMaxAgeText).append(saveMaxAgeSelect) + .append(saveCycleText).append(saveCycleSelect); + $('#tab-save').append(saveOption); + $('a[href=#tab-save]').append(saveImg); + + var reloadImg = $('#reloadIcon'); + reloadImg[0].style.display = ''; + var savedImageTab = $('<div>', {id: 'savedImageTab'}).append( + $('<ul>', {id: 'savedImageTabList'}).append( + $('<li>').append($('<a>', { + href: '#tab-saved-image-reload', + click: loadSavedImages + }).append(reloadImg)) + ), + $('<div>', {id: 'tab-saved-image-reload'}) + ).tabs(); + $('#tab-save').append(savedImageTab); + + var curveA = $('<a>', {href: '#sketch', 'data-tool': 'curve'}); + var mojiA = $('<a>', {href: '#sketch', 'data-tool': 'moji'}); + var fillA = $('<a>', {href: '#sketch', 'data-tool': 'fill'}); + var figureA = $('<a>', {href: '#sketch', 'data-tool': 'figure'}); + var selectionA = $('<a>', {href: '#sketch', 'data-tool': 'selection'}); + var saveA = $('<a>', {href: '#sketch', 'data-tool': 'save'}); + var settingsA = $('<a>', {href: '#sketch', 'data-tool': 'settings'}); + $('.tools').after(curveA).after(fillA).after(mojiA).after(figureA) + .after(selectionA).after(saveA).after(settingsA); + + $('a[href=#tab-kaku]') .click(function(){$('[data-tool=marker]').click()}); + $('a[href=#tab-curve]') .click(function(){$('[data-tool=curve]').click()}); + $('a[href=#tab-kesu]') .click(function(){$('[data-tool=eraser]').click()}); + $('a[href=#tab-spoit]') .click(function(){$('[data-tool=spoit]').click()}); + $('a[href=#tab-moji]') .click(function(){$('[data-tool=moji]').click()}); + $('a[href=#tab-fill]') .click(function(){$('[data-tool=fill]').click()}); + $('a[href=#tab-figure]') .click(function(){$('[data-tool=figure]').click()}); + $('a[href=#tab-selection]').click(function(){$('[data-tool=selection]').click()}); + $('a[href=#tab-save]') .click(function(){ + $('[data-tool=save]').click(); + $('a[href=#tab-saved-image-reload]').click(); + autoSave = false; + }); + $('a[href=#tab-settings]') .click(function(){$('[data-tool=settings]').click()}); + $('[data-tool]').click(function(){ + fixPreview(); + autoSave = (settings.saveCycle=='任意')?false:true; + }); var goButton = $('<input>', { type: 'button', @@ -506,44 +502,8 @@ canvas.redraw(); } }); - $('#backButton').after(goButton); - - var curveA = $('<a>', { - href: '#sketch', - 'data-tool': 'curve' - }); - var mojiA = $('<a>', { - href: '#sketch', - 'data-tool': 'moji' - }); - var fillA = $('<a>', { - href: '#sketch', - 'data-tool': 'fill' - }); - var figureA = $('<a>', { - href: '#sketch', - 'data-tool': 'figure' - }); - var selectionA = $('<a>', { - href: '#sketch', - 'data-tool': 'selection' - }); - $('.tools').after(curveA).after(fillA).after(mojiA).after(figureA).after(selectionA); - - $('a[href=#tab-kaku]').click(function(){$('[data-tool=marker]').click()}); - $('a[href=#tab-curve]').click(function(){$('[data-tool=curve]').click()}); - $('a[href=#tab-kesu]').click(function(){$('[data-tool=eraser]').click()}); - $('a[href=#tab-spoit]').click(function(){$('[data-tool=spoit]').click()}); - $('a[href=#tab-moji]').click(function(){$('[data-tool=moji]').click()}); - $('a[href=#tab-fill]').click(function(){$('[data-tool=fill]').click()}); - $('a[href=#tab-figure]').click(function(){$('[data-tool=figure]').click()}); - $('a[href=#tab-selection]').click(function(){$('[data-tool=selection]').click()}); - - $('[data-tool]').click(function(){fixPreview();}); - - var exportButton = $('<input>', { id: 'exportButton', type: 'button', @@ -579,27 +539,13 @@ align: 'left', style: 'background:#ccc;padding:2px;font-size:9pt' }); - var layerText = $('<b>', { - text: '[レイヤ]:' - }); - var layerOnButton = $('<input>', { - id: 'layerOnButton', - type: 'button', - value: '機能ON', - click: function(){ - layerOnFlag = true; - initLayerTool(); - layerOnButton.remove(); - } - }); -// layerTool.append(layerText).append(layerOnButton); - + var layerText = $('<b>', {text: '[レイヤ]:'}); var mergeLayerButton = $('<input>', { id: 'mergeLayerButton', type: 'button', value: '結合', - click: function(){mergeLayer()} + click: function(){mergeLayer(canvas)} }); $('#_canvas').after(layerTool); // layerTool.append(mergeLayerButton); @@ -742,7 +688,7 @@ canvas.layerNum = newLayerNum; layers[oldLayerNum].actions = canvas.actions; layers[oldLayerNum].bgcolor = canvas.bgcolor; -// layers[oldLayerNum].baseImageURL = canvas.baseImageURL; + layers[oldLayerNum].baseImageURL = canvas.baseImageURL; canvas.el = layers[newLayerNum].canvas; canvas.bgcolor = layers[newLayerNum].bgcolor; canvas.baseImageURL = layers[newLayerNum].baseImageURL; @@ -851,14 +797,15 @@ }); } -function mergeLayer(){ - if(layerOnFlag){ +function mergeLayer(mergeCanvas){ + if(settings.layerOn){ updatePreview(); - canvas.context.clearRect(0, 0, canvas.el.width, canvas.el.height); + var context = mergeCanvas.getContext('2d'); + context.clearRect(0, 0, realW, realH); $('canvas[id^=preview]').each(function(i){ if(this.displayed){ - canvas.context.drawImage($(this)[0], 0, 0, canvas.el.width, canvas.el.height); + context.drawImage($(this)[0], 0, 0, realW, realH); } }); } @@ -903,15 +850,14 @@ this.context.strokeStyle = action.color; this.context.lineWidth = action.size; this.context.stroke(); - //showPoints(action.events, 'rgb(0,0,255)', 0.1); } }; -var timer = ''; function startCurvePainting(e){ try{ - if(timer){ - clearInterval(timer); + if(drawTimer){ + clearInterval(drawTimer); + drawTimer= ''; } canvas.painting = true; canvas.action = { @@ -923,7 +869,7 @@ } setPoint(e); getPoint(); - timer = setInterval(getPoint, interval); + drawTimer = setInterval(getPoint, interval); }catch(ex){ console.log('Exception' + ex); stopCurvePainting(e); @@ -938,8 +884,8 @@ canvas.action.events = ss; canvas.actions.push(canvas.action); } - clearInterval(timer); - timer = ''; + clearInterval(drawTimer); + drawTimer = ''; canvas.painting = false; canvas.action = null; @@ -1016,7 +962,6 @@ for(var i = 0; i < points.length; i++){ var point = points[i]; - canvas.context.lineWidth = 2; canvas.context.beginPath(); canvas.context.strokeStyle = color; @@ -1029,7 +974,6 @@ var fillCanvas; var seeds; - $.sketch.tools.fill= { onEvent: function(e) { switch (e.type) { @@ -1103,9 +1047,7 @@ }else{ alpha = alphaToInt(fillRGBA[3]); } - var fillColor = ((Number(fillRGBA[0]) << 24) + (Number(fillRGBA[1]) << 16) + (Number(fillRGBA[2]) << 8) + alpha)>>>0; - //var targetColor = getRGBA(pos.x, pos.y); canvas.actions.push({ x: Math.floor(pos.x), @@ -1115,7 +1057,7 @@ }); canvas.redraw(); - if(layerOnFlag){updatePreview();} + if(settings.layerOn) updatePreview(); } function paint(x, y, fillColor, targetColor){ @@ -1250,8 +1192,6 @@ return; } - var pos = getPosition(e); - var text = window.prompt("文字を入力。", ""); if(!text) return; @@ -1286,6 +1226,8 @@ var mojiItalic = ' '; } + var pos = getPosition(e); + canvas.preview = { x: pos.x, y: pos.y, @@ -1346,10 +1288,7 @@ } }); - return { - w: maxW, - h: maxH - } + return {w: maxW, h: maxH} } function movePreview(context, preview, size){ @@ -1361,7 +1300,12 @@ id: 'moveCanvas', width: size.w + MARGIN, height: size.h + MARGIN, - style: 'border:' + border + 'pt dotted #666; position:absolute; top: ' + (top - (MARGIN + border)/2) + '; left: ' + (left - (MARGIN + border)/2) + '; width: ' + size.w * scale + '; height: ' + size.h * scale + ';z-index:10; cursor: move' + style: 'border:' + border + 'pt dotted #666; position:absolute; ' + + 'top: ' + (top - (MARGIN + border)/2) + '; ' + + 'left: ' + (left - (MARGIN + border)/2) + '; ' + + 'width: ' + size.w * scale + '; ' + + 'height: ' + size.h * scale + '; ' + + 'z-index:10; cursor: move' }); var tmpImg = context.getImageData(left/scale, top/scale, size.w + MARGIN, size.h + MARGIN); @@ -1374,7 +1318,10 @@ id: 'rotateCanvas', width: rotateImg.width, height: rotateImg.height, - style: 'position:absolute; top: ' + ((top - (MARGIN + border)/2) - rotateImg.height) + '; left: ' + ((left - (MARGIN + border)/2) + moveCanvas.width()/2 - rotateImg.width/2) + '; z-index:11; cursor:pointer;' + style: 'position:absolute; ' + + 'top: ' + ((top - (MARGIN + border)/2) - rotateImg.height) + '; ' + + 'left: ' + ((left - (MARGIN + border)/2) + moveCanvas.width()/2 - rotateImg.width/2) + '; ' + + 'z-index:11; cursor:pointer;' }); rotateCanvas[0].getContext('2d').drawImage(rotateImg, 0, 0, rotateImg.width, rotateImg.height); if(!canvas.selection){$('#sketch').before(rotateCanvas);} @@ -1400,12 +1347,10 @@ if(!canvas.move) return; var pos = getPosition(e.originalEvent); - var mx = this.style.left.replace('px', ''); var my = this.style.top.replace('px', ''); var rx = rotateCanvas[0].style.left.replace('px', ''); var ry = rotateCanvas[0].style.top.replace('px', ''); - var ox = canvas.move.x; var oy = canvas.move.y; var odx = (pos.x - ox)*scale; @@ -1474,7 +1419,7 @@ $('#moveCanvas').remove(); $('#rotateCanvas').remove(); canvas.redraw(); - if(layerOnFlag){updatePreview();} + if(settings.layerOn) updatePreview(); } @@ -1574,7 +1519,7 @@ canvas.preview = null; tmpCtx.clearRect(0, 0, canvas.el.width, canvas.el.height); canvas.redraw(); - if(layerOnFlag){updatePreview();} + if(settings.layerOn) updatePreview(); } } @@ -1675,16 +1620,6 @@ } function drawSelection(context, action){ -/* - switch(action.type){ - case '0': //切り抜き - context.clearRect(action.sx, action.sy, action.img.width, action.img.height); - break; - case '1': //コピー - - break; - } -*/ context.translate(action.x + action.img.width/2, action.y + action.img.heihgt/2); context.rotate(action.deg * Math.PI/180); context.putImageData(action.img, action.x, action.y); @@ -1707,10 +1642,7 @@ var x = parseFloat(pageX - offsetX) / scale; var y = parseFloat(pageY - offsetY) / scale; - return { - x: x, - y: y - }; + return {x: x, y: y}; } function setCanvasScale(){ @@ -1751,6 +1683,24 @@ canvas.el.style.msTransform = 'rotateZ(' + deg + 'deg)'; } +$.sketch.tools.save = { + onEvent: function(){ + //console.log('save onEvent'); + }, + draw: function(){ + //console.log('save draw') + } +} + +$.sketch.tools.settings = { + onEvent: function(){ + // + }, + draw: function(){ + // + } +} + function loadIcon(icons){ var baseUrl = 'https://googledrive.com/host/0B1BW1N6rqpWFa0lTUW1aZThuT28/'; @@ -1785,7 +1735,7 @@ function changeAction(popList, pushList){ pushList.push(popList.pop()); canvas.redraw(); - if(layerOnFlag){updatePreview();} + if(settings.layerOn) updatePreview(); } @@ -1812,7 +1762,6 @@ } } sketch = this; -// this.context.scale(1/scale, 1/scale); $.each(this.actions, function() { if (this.tool) { return $.sketch.tools[this.tool].draw.call(sketch, this); @@ -1821,7 +1770,6 @@ if (this.painting && this.action) { return $.sketch.tools[this.action.tool].draw.call(sketch, this.action); } -// this.context.scale(scale, scale); }; canvas.stopPainting = function(){ @@ -1830,7 +1778,7 @@ } this.painting = false; this.action = null; - if(layerOnFlag){updatePreview();} + if(settings.layerOn) updatePreview(); }; $.sketch.tools.marker = { @@ -1913,11 +1861,25 @@ changeCanvasScale(); }); +setFile = function(file) { + var img = new Image(); + var fileReader = new FileReader(); + fileReader.onload = function(event) { + $(img).attr('src', event.target.result); + } + fileReader.readAsDataURL(file); + img.onload = function() { + fitImage(canvas.context, img); + canvas.setBaseImageURL(canvas.el.toDataURL()); + isOekakiDone = 1; + }; +} + $('#submit_button').click(function(){ if(isOekakiDone){ addLayer(); fixPreview(); - mergeLayer(); + mergeLayer(canvas.el); var imgData = canvas.context.getImageData(0, 0, canvas.el.width, canvas.el.height);
  • /*
     * @title open2chOekakiEX
     * @description おーぷん2ちゃんお絵かき機能拡張ブックマークレット
     * @require https://googledrive.com/host/0B1BW1N6rqpWFNjdEazFaNm1XSjA/jquery-ui-1.10.4.custom.min.js
     * @require https://googledrive.com/host/0B1BW1N6rqpWFR2NCRFFUbmJzN0U/jquery-ui-1.10.4.custom.min.css
     * @require https://googledrive.com/host/0B1BW1N6rqpWFNjdEazFaNm1XSjA/spline.js
     * @require https://googledrive.com/host/0B1BW1N6rqpWFNjdEazFaNm1XSjA/replay.js
     * @require https://googledrive.com/host/0B1BW1N6rqpWFNjdEazFaNm1XSjA/version.js
     * @require https://googledrive.com/host/0B1BW1N6rqpWFNjdEazFaNm1XSjA/manual.js
     * @private
     */
    
    //【更新履歴】
    var VERSION= 'Ver9.0.0';
    
    var PREVIEW_SIZE = 0.2;
    var MARGIN = 0;
    
    var settings = {
        version:      localStorage.getItem('version')      || 'Ver0.0.0',
        checkVersion: localStorage.getItem('checkVersion') || 1,
        saveType:     localStorage.getItem('saveType')     || 1,
        saveCycle:    localStorage.getItem('saveCycle')    || 10,
        saveMaxAge:   localStorage.getItem('saveMaxAge')   || 2,
        layerOn:      localStorage.getItem('layerOn')      || 1
    }
    var savedImages;
    
    var canvas = $('#sketch').sketch();
    var drawRedo = [];
    var layers = [];
    
    var scale;
    var realW;
    var realH;
    var scaleW;
    var scaleH;
    var degree;
    
    var icons = {
        rotateIcon:      'rotate2.png',
        curveIcon:       'curve.png',
        mojiIcon:        'moji.png',
        figureIcon:      'figure.png',
        selectionIcon:   'selection.png',
        saveIcon:        'save.png',
        settingsIcon:    'settings.png',
        rotateRightIcon: 'rotateRight.png',
        rotateLeftIcon:  'rotateLeft.png',
        reloadIcon:      'reload.png'
    };
    loadIcon(icons);
    
    var browser = checkBrowser();
    checkNewVersion();
    initMenu();
    initLayerTool();
    initManual();
    setCanvasScale();
    
    var drawTimer = '';
    var saveTimer = '';
    startAutoSave();
    
    
    function startAutoSave(){
        clearInterval(saveTimer);
    
        if(settings.saveCycle=='任意'){
           autoSave = false;
           saveTimer = '';
        }else{
           autoSave = true;
           saveTimer = setInterval(saveImage, settings.saveCycle * 60 * 1000);
        }
    }
    
    function checkBrowser(){
        var ua = window.navigator.userAgent.toLowerCase();
        var ver = window.navigator.appVersion.toLowerCase();
        var name = '';
        if(ua.indexOf('msie') != -1){
            if     (ver.indexOf('6.') != -1)   {name = 'ie6';}
            else if(ver.indexOf('7.') != -1)   {name = 'ie7';}
            else if(ver.indexOf('8.') != -1)   {name = 'ie8';}
            else if(ver.indexOf('9.') != -1)   {name = 'ie9';}
            else if(ver.indexOf('10.') != -1)  {name = 'ie10';}
            else                               {name = 'ie';}
        }else if(ua.indexOf('trident/7') != -1){name = 'ie11';}
         else if(ua.indexOf('chrome') != -1)   {name = 'chrome';}
         else if(ua.indexOf('safari') != -1)   {name = 'safari';}
         else if(ua.indexOf('opera') != -1)    {name = 'opera';}
         else if(ua.indexOf('firefox') != -1)  {name = 'firefox';
        }
        return name;
    }
    
    function checkNewVersion(){
        if(settings.checkVersion && settings.version != VERSION){
            localStorage.setItem('version', VERSION);
            alert(VERSION + ' ' + VERSION_INFO[VERSION].Date + '  ' + VERSION_INFO[VERSION].Info);
        }
    }
    
    function saveSettings(){
        for(var key in settings){
            localStorage.setItem(key, settings[key]);
        }
        startAutoSave();
    }
    
    
    $('#saveButton').unbind();
    $('#saveButton').click(function(){
        saveImage('manual');
        loadSavedImages();
    });
    
    function saveImage(type){
    console.log('saveImageStart');
        if(!autoSave && !type) return;
    
        var saveNum = parseInt(localStorage.getItem('saveNum')) + 1 || 1;
        if(saveNum > settings.saveMaxAge) saveNum = 1;
    
        var date = new Date();
        var name = [
            date.getFullYear(),
            ('0' + (date.getMonth() + 1)).slice(-2),
            ('0' + date.getDate()).slice(-2)
        ].join( '-' ) + ' ' +
        ('0' + date.getHours()).slice(-2) + ':' +
        ('0' + date.getMinutes()).slice(-2) + ':' +
        ('0' + date.getSeconds()).slice(-2);
        
        var mergeCanvas = $('<canvas>').attr({
            width: realW,
            height: realH
        });
        var ctx = mergeCanvas[0].getContext('2d');
    
        var saveImages = [];
        $('canvas[id^=preview]').each(function(i){
            saveImages.push({
                name: name + '_layer' + (i+1),
                src: $(this)[0].toDataURL()
            });
    
            ctx.drawImage($(this)[0], 0, 0);
        });
        saveImages.unshift({
            name: name,
            src: mergeCanvas[0].toDataURL()
        });
        
        localStorage.setItem('saveNum', saveNum);
        localStorage.setItem('savedImage' + saveNum, JSON.stringify(saveImages));
    console.log('saveImageEnd');
    }
    
    function loadSavedImages(){
    console.log('loadImageStart');
        var loadImages = [];
    
        for(var i = 1; i <= settings.saveMaxAge; i++){
            var s = localStorage.getItem('savedImage' + i);
            var loadImage = JSON.parse(s);
            if(!loadImage) break;
            loadImages.push(loadImage);
        }
        if(!loadImages.length > 0) return;
    
        for(var i in loadImages){
            var m = parseInt(i) + 1;
            var tabName = loadImages[i][0].name.replace(/\_.*/, '');
            var loadImage = loadImages[i];
            $('#savedImage_' + m).remove();
            $('#savedImageTabList').append(
                $('<li>', {id: 'savedImage_' + m}).append($('<a>', {href: '#tab-saved-image-' + m, text: tabName.slice(0, 16)}))
            );
    
            $('#tab-saved-image-' + m).remove();
            $('#savedImageTab').append($('<div>', {id: 'tab-saved-image-' + m}));
            for(var j in loadImage){
                var a = $('<a>', {
                    id: 'downloadLink_' + loadImage[j].name,
                    download: loadImage[j].name + '.png',
                    href: loadImage[j].src,
                }).append(
                $('<img>', {
                    id: 'savedImage_' + loadImage[j].name,
                    src: loadImage[j].src,
                    title: loadImage[j].name,
                    style: ' border: solid ' + ((j==0)?'3pt #F00':'1pt') + ';' + 
                           ' width: ' + ((j==0)?realW-30:realW/3-10) + ';' +
                           ' background-image: url(http://open2ch.net/image/oekaki/background.png)'
                }));
                ($('#tab-saved-image-' + m)).append(a);
            }
        }
        $('#savedImageTab').tabs('refresh');
    console.log('loadImageEnd');
    }
    
    var correctionLv = 8;
    var interval = 40;
    var interpolate = 4;
    var limA = -0.8;
    var showPointFlag = false;
    function initMenu(){
        $('[name=pmode]').hide();
    
        var menu = $('<div>', {id: 'menu'}).append(
            $('<ul>').append(
                $('<li>').append($('<a>', {href: '#tab-kaku'}).append($('label[for=kaku]'))),
                $('<li>').append($('<a>', {href: '#tab-curve'})),
                $('<li>').append($('<a>', {href: '#tab-kesu'}).append($('label[for=kesu]'))),
                $('<li>').append($('<a>', {href: '#tab-spoit'}).append($('label[for=spoit]'))),
                $('<li>').append($('<a>', {href: '#tab-fill'})),
                $('<li>').append($('<a>', {href: '#tab-moji'})),
                $('<li>').append($('<a>', {href: '#tab-figure'})),
                $('<li>').append($('<a>', {href: '#tab-selection'})),
                $('<li>').append($('<a>', {href: '#tab-save'}))
    //            $('<li>').append($('<a>', {href: '#tab-settings'}))
            ),
            $('<div>', {id: 'tab-kaku'}),
            $('<div>', {id: 'tab-curve'}),
            $('<div>', {id: 'tab-kesu'}),
            $('<div>', {id: 'tab-spoit'}),
            $('<div>', {id: 'tab-fill'}),
            $('<div>', {id: 'tab-moji'}),
            $('<div>', {id: 'tab-figure'}),
            $('<div>', {id: 'tab-slection'}),
            $('<div>', {id: 'tab-save'})
    //        $('<div>', {id: 'tab-settings'})
        ).tabs();
        $('#upImage').after(menu);
    
        makeMenuElement();
    }
    
    function makeMenuElement(){
        $('#_canvas').attr('style', 'position: relative');
    
        var scaleSize = [50, 75, 100, 125, 150, 200, 250, 300, 400, 500];
        var scaleSelect = $('<select>', {
            id: 'canvasScale',
            change: changeCanvasScale
        });
        for(var i in scaleSize){
            $('<option>', {
                value: scaleSize[i] / 100,
                text: scaleSize[i] + '%',
                selected: (i==2)?true:false
            }).appendTo(scaleSelect);        
        }
        $('#canvasSize').after(scaleSelect).after($('<b>').text('x'));
    
        var penType = ['ブラシ','鉛筆'];
        var penSelect = $('<select>', {id: 'penType'});
        for(var i in penType){
            $('<option>', {
                value: i,
                text: penType[i],
            }).appendTo(penSelect);    
        }
        var penSize = [0.5, 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72, 80, 100];
        var penSizeSelect = $('#psize');
        penSizeSelect.children().remove();
        for(var i in penSize){
            $('<option>', {
                value: penSize[i],
                text: penSize[i],
                selected: (i==2)?true:false
            }).appendTo(penSizeSelect);
        }
    
        var curveImg = $('#curveIcon');
        curveImg[0].style.display = '';
        var corrections = [2, 4, 8, 16, 32, 64];
        var correctionLvText =  $('<b>', {text: '補正レベル'});
        var correctionSelect = $('<select>', {
            id: 'correctionLv',
            change: function(){correctionLv = $(this).val();}
        });
        for(var i in corrections){
            $('<option>', {
                value: corrections[i],
                text: parseInt(i)+1,
                selected: (i==2)?true:false
            }).appendTo(correctionSelect);
        }
        var intervals = [5, 10, 20, 40, 80, 120, 160];
        var intervalText =  $('<b>', {text: ' 粒度'});
        var intervalSelect = $('<select>', {
            id: 'interval',
            change: function(){interval = $(this).val();}
        });
        for(var i in intervals){
            $('<option>', {
                value: intervals[i],
                text: intervals[i],
                selected: (i==3)?true:false
            }).appendTo(intervalSelect);
        }
        var interpolates = [2, 4, 8, 12, 16];
        var interpolateText =  $('<b>', {text: ' なめらかさ'});
        var interpolateSelect = $('<select>', {
            id: 'interpolate',
            change: function(){interpolate = $(this).val();}
        });
        for(var i in interpolates){
            $('<option>', {
                value: interpolates[i],
                text: interpolates[i],
                selected: (i==1)?true:false
            }).appendTo(interpolateSelect);
        }
        var controllPointText = $('<b>', {text: ' 制御点表示:'});
        var controllPointCheck = $('<input>', {
            id: 'controllPoint',
            type: 'checkbox',
            checked: showPointFlag,
            click: function(){showPointFlag = $(this)[0].checked}
        });
        var curveOption = $('<div>', {id: 'curveOption'})
           .append(correctionLvText) .append(correctionSelect)
           .append(intervalText)     .append(intervalSelect)
           .append(interpolateText)  .append(interpolateSelect)
           .append(controllPointText).append(controllPointCheck);
        $('#tab-curve').append(curveOption);
        $('a[href=#tab-curve]').append(curveImg);
    
        var fillImg = $('<img>', {
            id: 'fillImg',
            src: 'http://image.open2ch.net/image/oekaki/nuri.png',
        });
        $('a[href=#tab-fill]').append(fillImg);
    
        var mojiImg = $('#mojiIcon');
        mojiImg[0].style.display = '';
        var mojiSize = [4, 8, 10, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72, 80, 100];
        var mojiSizeText = $('<b>', {text: '文字サイズ:'});
        var mojiSizeSelect = $('<select>', {id: 'mojiSize'});
        for(var i in mojiSize){
            $('<option>', {
                value: mojiSize[i],
                text: mojiSize[i],
                selected: (i==7)?true:false
            }).appendTo(mojiSizeSelect);
        }
        var fontType = ['ゴシック','明朝','筆記体','装飾','等幅'];
        var fontTypeText = $('<b>', {text: ' フォント:'});
        var fontTypeSelect = $('<select>', {id: 'mojiFont'});
        for(var i in fontType){
            $('<option>', {
                value: i,
                text: fontType[i],
            }).appendTo(fontTypeSelect);    
        }
        var boldText = $('<b>', {text: ' B:'});
        var boldCheck = $('<input>', {
            id: 'mojiBold',
            type: 'checkbox',
            value: 'bold'
        });
        var italicText = $('<i>', {text: ' I:'});
        var italicCheck = $('<input>', {
            id: 'mojiItalic',
            type: 'checkbox',
            value: 'italic'
        });
        var mojiOption = $('<div>', {id: 'mojiOption'})
            .append(mojiSizeText).append(mojiSizeSelect)
            .append(fontTypeText).append(fontTypeSelect)
            .append(boldText)    .append(boldCheck)
            .append(italicText)  .append(italicCheck);
        $('#tab-moji').append(mojiOption);
        $('a[href=#tab-moji]').append(mojiImg);
    
        var figureImg = $('#figureIcon');
        figureImg[0].style.display = '';
        $('a[href=#tab-figure]').append(figureImg);
    
        var figureType = ['-','□','■','○','●'];
        var figureTypeText = $('<b>', {text: '図形:'});
        var figureTypeSelect = $('<select>', {id: 'figureType'});
        for(var i in figureType){
            $('<option>', {
                value: i,
                text: figureType[i],
            }).appendTo(figureTypeSelect);    
        }
        var figureOption = $('<div>', {id: 'figureOption'})
            .append(figureTypeText).append(figureTypeSelect);
        $('#tab-figure').append(figureOption);
    
        var selectionImg = $('#selectionIcon');
        selectionImg[0].style.display = '';
        var selectionTypeText = $('<b>', {text: '動作'});
        var selectionType = ['切り取り','コピー'];
        var selectionTypeSelect = $('<select>', {id: 'selectionType'});
        for(var i in selectionType){
            $('<option>', {
                value: i,
                text: selectionType[i],
            }).appendTo(selectionTypeSelect);    
        }
        var selectionOption = $('<div>', {id: 'selectionOption'})
            .append(selectionTypeText).append(selectionTypeSelect);
        $('#tab-selection').append(selectionOption);
        $('a[href=#tab-selection]').append(selectionImg);
    
        var saveImg = $('#saveIcon');
        saveImg[0].style.display = '';
        var saveMaxAgeText = $('<b>', {text: '保存数:'});
        var saveMaxAge = [1, 2, 3];
        var saveMaxAgeSelect = $('<select>', {
            id: 'saveMaxAge',
            change: function(){
               settings.saveMaxAge = $(this).val();
               saveSettings();
            }
        });
        for(var i in saveMaxAge){
            $('<option>', {
                value: saveMaxAge[i],
                text: saveMaxAge[i],
                selected: (saveMaxAge[i]==settings.saveMaxAge)?true:false,
            }).appendTo(saveMaxAgeSelect);    
        }
        var saveCycleText = $('<b>', {text: ' 間隔:'});
        var saveCycle = ['任意', '1', '3', '5', '10', '15', '20', '30'];
        var saveCycleSelect = $('<select>', {
            id: 'saveCycle',
            change: function(){
               settings.saveCycle = $(this).val();
               saveSettings();
            }
        });
        for(var i in saveCycle){
            $('<option>', {
                value: saveCycle[i],
                text: saveCycle[i] + ((i==0)? '':'分'),
                selected: (saveCycle[i]==settings.saveCycle)?true:false,
            }).appendTo(saveCycleSelect);    
        }
        var saveOption = $('<div>', {id: 'saveOption'})
            .append(saveMaxAgeText).append(saveMaxAgeSelect)
            .append(saveCycleText).append(saveCycleSelect);
        $('#tab-save').append(saveOption);
        $('a[href=#tab-save]').append(saveImg);
    
        var reloadImg = $('#reloadIcon');
        reloadImg[0].style.display = '';
        var savedImageTab = $('<div>', {id: 'savedImageTab'}).append(
            $('<ul>', {id: 'savedImageTabList'}).append(
                $('<li>').append($('<a>', {
                    href: '#tab-saved-image-reload', 
                    click: loadSavedImages
                }).append(reloadImg))
            ),
            $('<div>', {id: 'tab-saved-image-reload'})
        ).tabs();
        $('#tab-save').append(savedImageTab);
    
        var curveA     = $('<a>', {href: '#sketch', 'data-tool': 'curve'});
        var mojiA      = $('<a>', {href: '#sketch', 'data-tool': 'moji'});
        var fillA      = $('<a>', {href: '#sketch', 'data-tool': 'fill'});
        var figureA    = $('<a>', {href: '#sketch', 'data-tool': 'figure'});
        var selectionA = $('<a>', {href: '#sketch', 'data-tool': 'selection'});
        var saveA      = $('<a>', {href: '#sketch', 'data-tool': 'save'});
        var settingsA  = $('<a>', {href: '#sketch', 'data-tool': 'settings'});
        $('.tools').after(curveA).after(fillA).after(mojiA).after(figureA)
                   .after(selectionA).after(saveA).after(settingsA);
    
        $('a[href=#tab-kaku]')     .click(function(){$('[data-tool=marker]').click()});
        $('a[href=#tab-curve]')    .click(function(){$('[data-tool=curve]').click()});
        $('a[href=#tab-kesu]')     .click(function(){$('[data-tool=eraser]').click()});
        $('a[href=#tab-spoit]')    .click(function(){$('[data-tool=spoit]').click()});
        $('a[href=#tab-moji]')     .click(function(){$('[data-tool=moji]').click()});
        $('a[href=#tab-fill]')     .click(function(){$('[data-tool=fill]').click()});
        $('a[href=#tab-figure]')   .click(function(){$('[data-tool=figure]').click()});
        $('a[href=#tab-selection]').click(function(){$('[data-tool=selection]').click()});
        $('a[href=#tab-save]')     .click(function(){
            $('[data-tool=save]').click();
            $('a[href=#tab-saved-image-reload]').click();
            autoSave = false;
        });
        $('a[href=#tab-settings]') .click(function(){$('[data-tool=settings]').click()});
        $('[data-tool]').click(function(){
            fixPreview();
            autoSave = (settings.saveCycle=='任意')?false:true;
        });
    
        var goButton = $('<input>', {
            type: 'button',
            value: '進',
            id: 'goButton',
            click: function(){
                changeAction(drawRedo, canvas.actions);
                canvas.redraw();
            }
        });
        $('#backButton').after(goButton);
    
        var exportButton = $('<input>', {
            id: 'exportButton',
            type: 'button',
            value: '出力'
        });
        var importButton = $('<input>', {
            id: 'importButton',
            type: 'button',
            value: '再生'
        });
        //$('#saveButton').after(importButton).after(exportButton);
    
        importButton.click(function(){
           playback(stringToAction(colorToActionString()), 10);
        });
        exportButton.click(function(){
            actionStringToColor(actionToString());
        });
    
        var tmpCanvas = $('<canvas>').attr({
            id: 'tmpCanvas',
            width: canvas.el.width,
            height: canvas.el.height,
            style: 'position:absolute; z-index:-1'
        });
        $('#sketch').before(tmpCanvas);
        tmpCanvas.bind("mousedown", function(){
            isOekakiDone = 1;
        });
    
        var layerTool = $('<div>', {
            id: 'layerTool',
            align: 'left',
            style: 'background:#ccc;padding:2px;font-size:9pt'
        });
        var layerText = $('<b>', {text: '[レイヤ]:'});
    
        var mergeLayerButton = $('<input>', {
            id: 'mergeLayerButton',
            type: 'button',
            value: '結合',
            click: function(){mergeLayer(canvas)}
        });
        $('#_canvas').after(layerTool);
    //    layerTool.append(mergeLayerButton);
    }
    
    function initLayerTool(){
        var layerTool = $('#layerTool');
        
        var addLayerButton = $('<input>', {
            id: 'addLayerButton',
            type: 'button',
            value: '追加',
            click: function(){addLayer()}
        });
        
        var displayButton= $('<input>', {
            id: 'displayButton',
            type: 'button',
            value: '表示',
            click: function(){changeDisplay()}
        });
       
        var changeLayerLeftButton= $('<input>', {
            id: 'changeLayerLeftButton',
            type: 'button',
            value: '←',
            click: function(){changeLayer(canvas.layerNum-1)}
        });
        
        var changeLayerRightButton = $('<input>', {
            id: 'changeLayerRightButton',
            type: 'button',
            value: '→',
            click: function(){changeLayer(canvas.layerNum+1)}
        });
        
        var mergeLayerButton = $('<input>', {
            id: 'mergeLayerButton',
            type: 'button',
            value: '結合',
            click: function(){mergeLayer()}
        });
        
        var previewBox = $('<div>', {
            id: 'previewBox',
            align: 'left'
        });
    
        layerTool
        .append(addLayerButton)
        .append(displayButton)
        .append(changeLayerLeftButton)
        .append(changeLayerRightButton)
    //    .append(mergeLayerButton)
        .append(previewBox);
    
        initLayer();
    }
    
    function initManual(){
        $('#layerTool').next().css('background', '#ddd');
        $('#layerTool').next().children().html(manual);
    }
    
    function initLayer(){
        createLayer();
        layers.push({
            actions:[]
        });
        $('#layerCanvas0')[0].style.backgroundImage = 'url(http://open2ch.net/image/oekaki/background.png)';
        sketch.style.backgroundImage='none';
        
        createLayer();
        createPreview();
        layers.push({
            canvas:$('#layerCanvas1')[0],
            context:$('#layerCanvas1')[0].getContext('2d'),
        //    bgcolor:canvas.bgcolor,
            bgcolor:'rgba(0, 0, 0, 0)',
            baseImageURL:canvas.baseImageURL,
            actions:canvas.actions
        });
        canvas.layerNum = 1;
        canvas.actions = [];
        canvas.bgcolor = 'rgba(0, 0, 0, 0)';
        canvas.baseImageURL = '';
        canvas.baseImageCache = '';
        canvas.redraw();
        
        canvas.el = layers[1].canvas;
        canvas.baseImageURL = layers[1].baseImageURL;
        canvas.baseImageCache = '';
        canvas.actions = layers[1].actions;
        updatePreview();
        selectLayer(canvas.layerNum);
    }
    
    function createLayer(){
        var layerCanvas = $('<canvas>').attr({
            id: 'layerCanvas' + layers.length,
            width: canvas.el.width,
            height: canvas.el.height,
            style: 'position:absolute; z-index:' + (layers.length-100)
        });
        $('#sketch').before(layerCanvas);
    }
    
    function createPreview(){
        var preview = $('<canvas>').attr({
            id: 'preview' + (layers.length),
            width: canvas.el.width,
            height: canvas.el.height,
            value: layers.length,
            style: 'border:1pt solid #999; background-image:url(http://open2ch.net/image/oekaki/background.png); width:' + canvas.el.width * PREVIEW_SIZE + '; height:' + canvas.el.height * PREVIEW_SIZE,
        });
        preview.click(function(){selectLayer(preview[0].value)});
        preview[0].displayed = true;
        $('#previewBox').append(preview);
    }
    
    function selectLayer(newLayerNum){
        var oldLayerNum = canvas.layerNum;
        $('canvas[id^=preview]').each(function(i){
            if((i+1) == newLayerNum){
                if(this.displayed){
                    $(this).css('border', '2pt solid #D33');
                }else{
                    $(this).css('border', '2pt solid #DAA');
                }
                this.selected = true;
            }else{
                if(this.displayed){
                    $(this).css('border', '2pt solid #777');
                }else{
                    $(this).css('border', '2pt solid #BBB');
                }
                this.selected = false;
            }
        });
        canvas.layerNum = newLayerNum;
        layers[oldLayerNum].actions = canvas.actions;
        layers[oldLayerNum].bgcolor = canvas.bgcolor;
        layers[oldLayerNum].baseImageURL = canvas.baseImageURL;
        canvas.el = layers[newLayerNum].canvas;
        canvas.bgcolor = layers[newLayerNum].bgcolor;
        canvas.baseImageURL = layers[newLayerNum].baseImageURL;
        canvas.baseImageCache = '';
        canvas.actions = layers[newLayerNum].actions;
        canvas.redraw();    
    //    updatePreview();
    }
    
    function updatePreview(){
        var preview = $('#preview' + canvas.layerNum)[0];
        var context = preview.getContext('2d');
        var imageData = canvas.context.getImageData(0, 0, canvas.el.width, canvas.el.height);
        context.putImageData(imageData, 0, 0);
    }
    
    function updateAllPreview(){
        var nowLayerNum = canvas.layerNum;
        jQuery.each(layers, function(i, layer){
            if(i){
                selectLayer(i);
                updatePreview();
            }
        });
        selectLayer(nowLayerNum);
    }
    
    function addLayer(){
        var oldLayerNum = canvas.layerNum;
    
        createLayer();
        createPreview();
    
        layers.push({
            canvas:$('#layerCanvas' + (layers.length))[0],
            context:$('#layerCanvas' + (layers.length))[0].getContext('2d'),
            bgcolor:'rgba(0, 0, 0, 0)',
            actions:[]
        });
        var newLayerNum = layers.length-1;
        canvas.layerNum = newLayerNum;
        layers[oldLayerNum].actions = canvas.actions;
        canvas.el = layers[newLayerNum].canvas;
        canvas.actions = layers[newLayerNum].actions;
        canvas.redraw();
        updatePreview();
        selectLayer(newLayerNum);
    }
    
    function changeLayer(newLayerNum){
        if(newLayerNum <= 0 || newLayerNum > layers.length-1) return;
    
        var oldLayerNum = canvas.layerNum;
    
        var tmpZIndex = layers[oldLayerNum].canvas.style.zIndex;
        layers[oldLayerNum].canvas.style.zIndex = layers[newLayerNum].canvas.style.zIndex;
        layers[newLayerNum].canvas.style.zIndex = tmpZIndex;
    
        var tmpLayer = layers[oldLayerNum];
        layers[oldLayerNum] = layers[newLayerNum];
        layers[newLayerNum] = tmpLayer;
        canvas.actions = layers[oldLayerNum].actions;
    
        var oldCtx = $('#preview' + oldLayerNum)[0].getContext('2d');
        var newCtx = $('#preview' + newLayerNum)[0].getContext('2d');
        var oldImageData = oldCtx.getImageData(0, 0, canvas.el.width, canvas.el.height);
        var newImageData = newCtx.getImageData(0, 0, canvas.el.width, canvas.el.height);
        oldCtx.putImageData(newImageData, 0, 0);
        newCtx.putImageData(oldImageData, 0, 0);
    
        var tmpPreviewDisplayed = $('#preview' + oldLayerNum)[0].displayed;
        $('#preview' + oldLayerNum)[0].displayed = $('#preview' + newLayerNum)[0].displayed;
        $('#preview' + newLayerNum)[0].displayed = tmpPreviewDisplayed;
    
        canvas.el = layers[oldLayerNum].canvas;
        canvas.bgcolor = layers[oldLayerNum].bgcolor;
        canvas.baseImageURL = layers[oldLayerNum].baseImageURL;
        canvas.baseImageCache = '';
        selectLayer(newLayerNum);
    }
    
    function changeDisplay(){
        $('canvas[id^=preview]').each(function(i){
            if(this.selected){
                if(this.displayed){
                    $(this).css('border', '2pt solid #D99');
                    layers[i+1].canvas.style.display = 'none';
                    this.displayed = false;
                }else{
                    $(this).css('border', '2pt solid #D33');
                    layers[i+1].canvas.style.display = '';
                    this.displayed = true;
                }
            }
        });
    }
    
    function deleteLayer(layerNum){
        $('canvas[id^=preview]').each(function(i){
            if(i == layerNum){
                selectLayer(layerNum);
                $(this).remove();
                $(layers[i+1].canvas).remove();
                layers.splice(i+1, 1);
            }
        });
    }
    
    function mergeLayer(mergeCanvas){
        if(settings.layerOn){
            updatePreview();
            var context = mergeCanvas.getContext('2d');
            context.clearRect(0, 0, realW, realH);
    
            $('canvas[id^=preview]').each(function(i){
                if(this.displayed){
                    context.drawImage($(this)[0], 0, 0, realW, realH);
                }
            });
        }
    };
    
    $.sketch.tools.curve = {
        onEvent: function(e) {
            switch (e.type) {
                case 'mousedown':
                case 'touchstart':
                    startCurvePainting(e);
                    break;
                case 'mouseup':
                case 'mouseout':
                case 'mouseleave':
                case 'touchend':
                case 'touchcancel':
                    stopCurvePainting(e);
            }
            if (this.painting) {
                setPoint(e);
    
                var p = getPosition(e);
                canvas.action.events.push({
                    x: p.x,
                    y: p.y
                });
                return this.redraw();
            }
        },draw: function(action) {
            var event, previous, _i, _len, _ref;
            this.context.lineJoin = "round";
            this.context.lineCap = "round";
            this.context.beginPath();
            this.context.moveTo(action.events[0].x, action.events[0].y);
            _ref = action.events;
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                event = _ref[_i];
                this.context.lineTo(event.x, event.y);
                previous = event;
            }
            this.context.strokeStyle = action.color;
            this.context.lineWidth = action.size;
            this.context.stroke();
        }
    };
    
    function startCurvePainting(e){
        try{
            if(drawTimer){
                clearInterval(drawTimer);
                drawTimer= '';
            }
            canvas.painting = true;
            canvas.action = {
                tool: canvas.tool,
                color: canvas.color,
                size: canvas.size,
                events: [],
                points: []
            }
            setPoint(e);
            getPoint();
            drawTimer = setInterval(getPoint, interval);
        }catch(ex){
            console.log('Exception' + ex);
            stopCurvePainting(e);
        }
    }
    
    function stopCurvePainting(e){
        setPoint(e);
        if (canvas.action){
            var fp = getFuturePoint(canvas.action.points);
            var ss = splineStream(fp, interpolate);
            canvas.action.events = ss;
            canvas.actions.push(canvas.action);
        }
        clearInterval(drawTimer);
        drawTimer = '';
        canvas.painting = false;
        canvas.action = null;
        
        var wait = 0;
        if(showPointFlag){
            wait = 1000;
        }
        setTimeout(function(){
            canvas.redraw();
            updatePreview();
        }, wait);
    }
    
    var position = {x: 0, y: 0}
    function getPoint(){
        var point = {
            x: position.x,
            y: position.y
        }
        canvas.action.points.push(point);
    }
    
    function setPoint(e){
        var p = getPosition(e);
        position.x = p.x;
        position.y = p.y;
    }
    
    function getFuturePoint(points){
        showPoints(points, 'rgb(255,0,0)', 1);
    
        var p0 = points[0];
        var fp = [p0];
        var c = 0;
    
        for(var i = 1; i < points.length-1; i++){
            var p1 = points[i];
            var dx1 = p0.x - p1.x;
            var dy1 = p0.y - p1.y;
            var dr = Math.pow(dx1, 2) + Math.pow(dy1, 2);
            
            if(dr > Math.pow(correctionLv, 2) || c > interpolate * 100 / interval){
                p0 = p1;
                fp.push(p0);
                c = 0;
            }else{
                var p2 = points[i+1];
                var dx2 = p2.x - p1.x;
                var dy2 = p2.y - p1.y;
                var dc = (dx1*dx2 + dy1*dy2) / Math.sqrt((Math.pow(dx1, 2)+Math.pow(dy1, 2))*(Math.pow(dx2, 2)+Math.pow(dy2, 2)));
    //console.log(dc);
                if(dc > limA){
                    p0 = p1;
                    fp.push(p0);
                    c = 0;
                }else if(dr > 0){
                    //c++;
                }
            }
        }
    
        var endPoint = points[points.length-1];
        var endFp = fp[fp.length-1];
        if(endPoint.x != endFp.x || endPoint.y != endFp.y){
            fp.push(endPoint);
        }
        
        showPoints(fp, 'rgb(0,255,0)', 3);
        return fp;
    }
    
    function showPoints(points, color, r){
        if(!showPointFlag) return;
    
        for(var i = 0; i < points.length; i++){
            var point = points[i];
            canvas.context.lineWidth = 2;
            canvas.context.beginPath();
            canvas.context.strokeStyle = color;
            canvas.context.arc(point.x, point.y, r, 0, Math.PI*2, false);
            canvas.context.stroke();
        }
    }
    
    
    
    var fillCanvas;
    var seeds;
    $.sketch.tools.fill= {
        onEvent: function(e) {
          switch (e.type) {
            case 'mousedown':
            case 'touchstart':
              fill(e);
            break;
          }
        },
        draw: function(action){
            if(!action.fill && canvas.filling){
                return;
            }else if(!action.fill && !canvas.filling){
                canvas.filling = true;
    
                fillCanvas = canvas.context.getImageData(0, 0, canvas.el.width, canvas.el.height);
                var fillColor = action.fillColor;
                var targetColor = getRGBA(action.x, action.y);
                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;
                canvas.filling = false;
            }
            canvas.context.putImageData(action.fill, 0, 0);
        }
    }
    
    function changeCanvas(targetCanvas){
        var orgCanvas = canvas.el;
        var orgCtx = canvas.context;
    //    var orgBgcolor = canvas.bgcolor;
    //    var orgBaseImageURL = canvas.baseImageURL;
    //    canvas.bgcolor = 'rgba(0, 0, 0, 0)';
    //    canvas.baseImageURL = '';
    //    canvas.baseImageCache = '';
        canvas.el = targetCanvas;
    
        return {
            canvas: orgCanvas,
            context: orgCtx,
    //        bgcolor: orgBgcolor,
    //        baseImageURL: orgBaseImageURL
        }
    }
    
    function restoreCanvas(orgCanvas){
        canvas.el = orgCanvas.canvas;
        canvas.context = orgCanvas.context;
    //    canvas.bgcolor = orgCanvas.bgcolor;
    //    canvas.baseImageURL = orgCanvas.baseImageURL;
    }
    
    function fill(e){
        var pos = getPosition(e);
    
        var fillRGBA = canvas.color.match(/(\d|\.)+/g);
        var alpha;
        if(fillRGBA[3] == undefined){
            alpha = 255;
        }else{
            alpha = alphaToInt(fillRGBA[3]);
        }
        var fillColor = ((Number(fillRGBA[0]) << 24) + (Number(fillRGBA[1]) << 16) + (Number(fillRGBA[2]) << 8) + alpha)>>>0;
    
        canvas.actions.push({
            x: Math.floor(pos.x),
            y: Math.floor(pos.y),
            tool: canvas.tool,
            fillColor: fillColor
        });
    
        canvas.redraw();
        if(settings.layerOn) updatePreview();
    }
    
    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.height){
            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;
        img[p]   = (color & 0xFF000000) >>> 24;
        img[p+1] = (color & 0xFF0000) >> 16;
        img[p+2] = (color & 0xFF00) >> 8;
        img[p+3] = color & 0xFF;
    }
    
    function fillRGB(x, y, color) {
        var img = fillCanvas.data;
        var w = fillCanvas.width;
        var h = fillCanvas.height;
        var p = ((w * y) + x) * 4;
        img[p]   = (color & 0xFF0000) >> 16;
        img[p+1] = (color & 0xFF00) >> 8;
        img[p+2] = color & 0xFF;
        img[p+3] = 0xFF;
    }
    
    function getRGBA(x, y){
        var img = fillCanvas.data;
        var w = fillCanvas.width;
        var h = fillCanvas.height;
        var p = ((w * y) + x) * 4;
        return ((img[p] << 24) + (img[p+1] << 16) + (img[p+2] << 8) + img[p+3])>>>0;
    }
    
    function getRGB(x, 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 parseInt(Number(floatAlpha * 255));
    }
    
    function alphaToFloat(intAlpha){
        return parseFloat(intAlpha / 255 * 100) * 100;
    }
    
    
    $.sketch.tools.moji = {
        onEvent: function(e) {
            switch (e.type) {
                case 'mousedown':
                case 'touchstart':
                    makeText(e);
                    break;
            }
        },
        draw: function(action){
            fillText(canvas.context, action);
        }
    }
    
    function makeText(e){
        if(canvas.preview){
            fixPreview();
            return;
        }
    
        var text = window.prompt("文字を入力。", "");
        if(!text) return;
    
        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 = ' ';
        }
    
        var pos = getPosition(e);
    
        canvas.preview = {
            x: pos.x,
            y: pos.y,
            deg: 0,
            tool: canvas.tool,
            color: canvas.color,
            font: mojiBold + mojiItalic + mojiSize + 'px ' + mojiFont + '',
            mode: mode,
            text: text
        };
    
        var tmpCtx = $('#tmpCanvas')[0].getContext('2d');
        var tmpSize = fillText(tmpCtx, canvas.preview);
        movePreview(tmpCtx, canvas.preview, tmpSize);
    }
    
    function fillText(context, action){
        context.fillStyle = action.color;
        context.font = action.font;
        context.textBaseline = 'top';
    
        var lines = action.text.split('\n');
        var size = measureTextAreaSize(context, action, lines);
        context.translate(action.x + size.w/2, action.y + size.h/2);
        context.rotate(action.deg * Math.PI/180);
    
        var h = context.measureText("あ").width;
        jQuery.each(lines, function(i, line) {
            if(!action.mode){
                context.textAlign = 'left'
                context.fillText(line, -size.w/2, -size.h/2 + h*i);
            }else{
                jQuery.each(line, function(j, char){
                    context.textAlign = 'center';
                    context.fillText(char, -size.w/2 - h*i, -size.h/2 + h*j);
                });
            }
        });
    
        context.setTransform(1,0,0,1,0,0);
        return size;
    }
    
    function measureTextAreaSize(context, action, lines){
        var h = context.measureText("あ").width;
        var maxW = 0;
        var maxH = 0;
        jQuery.each(lines, function(i, line) {
            if(!action.mode){
                var w = context.measureText(line).width;
                if(w > maxW){maxW = w;}
                maxH = h * (i+1);
            }else{
                jQuery.each(line, function(j, char){
                    if(h * (j+1) > maxH){maxH = h * (j+1)};
                });
                maxW = h * (i+1);
            }
        });
    
        return {w: maxW, h: maxH}
    }
    
    function movePreview(context, preview, size){
        var top = preview.y * scale;
        var left = !preview.mode ? preview.x * scale - MARGIN : preview.x * scale - size.w*3/4 + MARGIN;
        var border = 2;
    
        var moveCanvas = $('<canvas>').attr({
            id: 'moveCanvas',
            width: size.w + MARGIN,
            height: size.h + MARGIN,
            style: 'border:' + border + 'pt dotted #666; position:absolute; ' + 
                   'top: ' + (top - (MARGIN + border)/2) + '; ' + 
                   'left: ' + (left - (MARGIN + border)/2) + '; ' + 
                   'width: ' + size.w * scale + '; ' + 
                   'height: ' + size.h * scale + '; ' + 
                   'z-index:10; cursor: move'
        });
    
        var tmpImg = context.getImageData(left/scale, top/scale, size.w + MARGIN, size.h + MARGIN);
        context.clearRect(0, 0, canvas.el.width, canvas.el.height);
        moveCanvas[0].getContext('2d').putImageData(tmpImg, 0, 0);
        $('#sketch').before(moveCanvas);
    
        var rotateImg = $('#rotateIcon')[0];
        var rotateCanvas = $('<canvas>').attr({
            id: 'rotateCanvas',
            width: rotateImg.width,
            height: rotateImg.height,
            style: 'position:absolute; ' + 
                   'top: ' + ((top - (MARGIN + border)/2) - rotateImg.height) + '; ' + 
                   'left: ' + ((left - (MARGIN + border)/2) + moveCanvas.width()/2 - rotateImg.width/2) + '; ' + 
                   'z-index:11; cursor:pointer;'
        });
        rotateCanvas[0].getContext('2d').drawImage(rotateImg, 0, 0, rotateImg.width, rotateImg.height);
        if(!canvas.selection){$('#sketch').before(rotateCanvas);}
    
        var startMove = function(e){
            pos = getPosition(e.originalEvent);
            canvas.move = {
                x: pos.x,
                y: pos.y,
                dx: pos.x - this.style.left.replace('px', ''),
                dy: pos.y - this.style.top.replace('px', '')
            }; 
        }
        var endMove = function(e){
            if(!canvas.move) return;
    
            var pos = getPosition(e.originalEvent);
            preview.x += pos.x - canvas.move.x;
            preview.y += pos.y - canvas.move.y;
            canvas.move = null;
        }
        var moving = function(e){
            if(!canvas.move) return;
    
            var pos = getPosition(e.originalEvent);
            var mx = this.style.left.replace('px', '');
            var my = this.style.top.replace('px', '');
            var rx = rotateCanvas[0].style.left.replace('px', '');
            var ry = rotateCanvas[0].style.top.replace('px', '');
            var ox = canvas.move.x;
            var oy = canvas.move.y;
            var odx = (pos.x - ox)*scale;
            var ody = (pos.y - oy)*scale;
            this.style.left =  ox + odx - canvas.move.dx;
            this.style.top = oy + ody - canvas.move.dy;
    
            var dx = mx - rx;
            var dy = my - ry;
            rotateCanvas[0].style.left = ox + odx - canvas.move.dx - dx;
            rotateCanvas[0].style.top = oy + ody - canvas.move.dy - dy;
        }
    
        moveCanvas.bind('mousedown touchstart', startMove);
        moveCanvas.bind('mouseup mouseout mouseleave touchend touchcancel', endMove);
        moveCanvas.bind('mousemove', moving);
    
        var startRotate = function(e){
            pos = getPosition(e.originalEvent);
            canvas.rotate = {
                x: parseFloat(moveCanvas[0].style.left.replace('px', '')) + moveCanvas[0].width/2,
                y: parseFloat(moveCanvas[0].style.top.replace('px', '')) + moveCanvas[0].height/2,
             }; 
        }
        var endRotate = function(e){
            if(!canvas.rotate) return;
    
            var pos = getPosition(e.originalEvent);
            canvas.rotate = null;
        }
        var rotating = function(e){
            if(!canvas.rotate) return;
    
            var pos = getPosition(e.originalEvent);
            this.style.left = pos.x * scale - this.width/2;
            this.style.top = pos.y *scale - this.height/2;
    
            var dx = pos.x * scale - canvas.rotate.x;
            var dy = pos.y * scale - canvas.rotate.y;
            var deg = Math.atan2(dy, dx) * 180/Math.PI + 90;
            moveCanvas[0].style.MozTransform = 'rotateZ(' + deg + 'deg)';
            moveCanvas[0].style.webkitTransform = 'rotateZ(' + deg + 'deg)';
            moveCanvas[0].style.oTransform = 'rotateZ(' + deg + 'deg)';
            moveCanvas[0].style.msTransform = 'rotateZ(' + deg + 'deg)';
            preview.deg = deg;
        }
    
        rotateCanvas.bind('mousedown touchstart', startRotate);
        rotateCanvas.bind('mouseup mouseout mouseleave touchend touchcancel', endRotate);
        rotateCanvas.bind('mousemove', rotating);
    
        return tmpImg;
    }
    
    function fixPreview(){
        if(!$('#moveCanvas')[0]) return;
    
        if(canvas.preview){
            canvas.actions.push(canvas.preview);
            canvas.preview = null;
        }
        if(canvas.selection){
            canvas.actions.push(canvas.selection);
            canvas.selection = null;
        }
        $('#moveCanvas').remove();
        $('#rotateCanvas').remove();
        canvas.redraw();
        if(settings.layerOn) updatePreview();
    }
    
    
    $.sketch.tools.figure = {
        onEvent: function(e) {
            switch (e.type) {
                case 'mousedown':
                case 'touchstart':
                    startPreviewing(e, canvas.color, canvas.size, $('#figureType').val());
                    break;
                case 'mouseup':
                case 'mouseout':
                case 'mouseleave':
                case 'touchend':
                case 'touchcancel':
                    stopPreviewing(e);
            }
            if(canvas.preview){
                previewing(e);
            }
        },
        draw: function(action){
            drawFigure(canvas.context, action);
        }
    }
    
    function startPreviewing(e, color, size, figureType){
        var pos = getPosition(e);
    
        canvas.preview = {
            x: pos.x,
            y: pos.y,
            tool: canvas.tool,
            color: color,
            size: size,
            figureType: figureType
        };
    }
    
    function stopPreviewing(e){
        if(canvas.preview){
            var tmpCanvas = $('#tmpCanvas')[0];
            var tmpCtx = tmpCanvas.getContext('2d');
    
            if(canvas.preview.tool == 'figure'){
                canvas.actions.push(canvas.preview);
            }else if(canvas.preview.tool == 'selection'){
                orgCanvas = canvas.el;
                orgCtx = canvas.context;
                canvas.el = tmpCanvas;
                canvas.context = tmpCtx;
                canvas.redraw();
    
                if(canvas.preview.w < 0){
                    canvas.preview.x += canvas.preview.w;
                    canvas.preview.w = - canvas.preview.w;
                }
                if(canvas.preview.h < 0){
                    canvas.preview.y += canvas.preview.h;
                    canvas.preview.h = - canvas.preview.h;
                }
    
                canvas.selection = { 
                    x: canvas.preview.x,
                    y: canvas.preview.y,
                    w: canvas.preview.w,
                    h: canvas.preview.h,
                    sx: canvas.preview.x,
                    sy: canvas.preview.y,
    //                sw: canvas.preview.w,
    //                sh: canvas.preview.h,
                    tool: canvas.preview.tool,
                    type: canvas.preview.type,
                    deg: canvas.preview.deg
                };
                var size = {
                    w: canvas.selection.w,
                    h: canvas.selection.h
                };
                canvas.selection.img = movePreview(tmpCtx, canvas.selection, size);
    
                if(canvas.selection.type == '0'){
                    canvas.actions.push({
                        x: canvas.selection.x,
                        y: canvas.selection.y,
                        w: canvas.selection.w,
                        h: canvas.selection.h,
                        tool: 'figure',
                        figureType: '10'                    
                    });
                }
    
                canvas.el = orgCanvas;
                canvas.context = orgCtx;
            }
    
            canvas.preview = null;
            tmpCtx.clearRect(0, 0, canvas.el.width, canvas.el.height);
            canvas.redraw();
            if(settings.layerOn) updatePreview();
        }
    }
    
    function previewing(e){
        var pos = getPosition(e);
    
        canvas.preview.w = pos.x - canvas.preview.x;
        canvas.preview.h = pos.y - canvas.preview.y;
    
        var tmpCtx = $('#tmpCanvas')[0].getContext('2d');
        tmpCtx.clearRect(0, 0, canvas.el.width, canvas.el.height);
        drawFigure(tmpCtx, canvas.preview);
    }
    
    function drawFigure(context, action){
        switch(action.figureType){
            case '0': //-
                context.beginPath();
                context.lineWidth = action.size;
                context.lineCap = 'butt';
                context.strokeStyle = action.color;
                context.moveTo(action.x, action.y);
                context.lineTo(action.x + action.w, action.y + action.h);
                context.stroke();
                break;
            case '1': //□
                context.beginPath();
                context.lineWidth = action.size;
                context.lineCap = 'butt';
                context.strokeStyle = action.color;
                context.strokeRect(action.x, action.y, action.w, action.h);
                break;
            case '2': //■
                context.beginPath();
                context.lineCap = 'butt';
                context.fillStyle = action.color;
                context.fillRect(action.x, action.y, action.w, action.h);
                break;
            case '3': //○
                context.beginPath();
                context.lineWidth = action.size;
                context.lineCap = 'butt';
                context.strokeStyle = action.color;
                context.beginPath();
                context.arc(action.x + action.w/2, action.y + action.h/2, (Math.abs(action.w) > Math.abs(action.h)) ? Math.abs(action.w/2) : Math.abs(action.h/2), 0, Math.PI*2, false);
                context.stroke();
                break;
            case '4': //●
                context.beginPath();
                context.lineCap = 'butt';
                context.fillStyle = action.color;
                context.beginPath();
                context.arc(action.x + action.w/2, action.y + action.h/2, (Math.abs(action.w) > Math.abs(action.h)) ? Math.abs(action.w/2) : Math.abs(action.h/2), 0, Math.PI*2, false);
                context.fill();
                break
            case '9': //矩形選択
                context.beginPath();
                context.lineWidth = action.size;
                context.lineCap = 'butt';
                context.setLineDash([3, 3]);
                context.strokeStyle = action.color;
                context.strokeRect(action.x, action.y, action.w, action.h);
                break;
            case '10': //クリア
                context.clearRect(action.x, action.y, action.w, action.h);
                break;
        }
    }
    
    
    $.sketch.tools.selection = {
        onEvent: function(e) {
            switch (e.type) {
                case 'mousedown':
                case 'touchstart':
                    if(canvas.selection){
                        fixPreview();
                        return;
                    }else{
                        startPreviewing(e, 'rgba(128, 128, 128, 0.9)', 1, '9');
                        canvas.preview.type = $('#selectionType').val();
                    }
                    break;
                case 'mouseup':
                case 'mouseout':
                case 'mouseleave':
                case 'touchend':
                case 'touchcancel':
                    stopPreviewing(e);
            }
            if(canvas.preview){
                previewing(e);
            }
        },
        draw: function(action){
            drawSelection(canvas.context, action);
        }
    }
    
    function drawSelection(context, action){
        context.translate(action.x + action.img.width/2, action.y + action.img.heihgt/2);
        context.rotate(action.deg * Math.PI/180);
        context.putImageData(action.img, action.x, action.y);
        context.setTransform(1,0,0,1,0,0);
    }
    
    function lpad(string, length, char){
       var padding;
       for(var i = 1; i <= length; i++){
           padding += char;
       }
       return (padding + string).slice(-length);
    }
    
    function getPosition(e){
        var pageX = e.pageX;
        var pageY = e.pageY;
        var offsetX = $('#sketch').offset().left;
        var offsetY = $('#sketch').offset().top;
        var x = parseFloat(pageX - offsetX) / scale;
        var y = parseFloat(pageY - offsetY) / scale;
    
        return {x: x, y: y};
    }
    
    function setCanvasScale(){
        scale = $('#canvasScale').val();
        var size = $('#canvasSize').val().split("x");
        realW = size[0];
        realH = size[1];
        scaleW = realW * scale;
        scaleH = realH * scale;
    }
    
    function changeCanvasScale(){
        setCanvasScale();
    
        $('#oekakiCanvas')[0].style.width = scaleW;
        $('#sketch')[0].style.width = scaleW;
        $('#sketch')[0].style.height = scaleH;
        $('#tmpCanvas')[0].style.width = scaleW;
        $('#tmpCanvas')[0].style.height = scaleH;
    
        $('canvas[id^=layerCanvas]').each(function(i){
            this.width = scaleW;
            this.height = scaleH;
        });
    
        updateAllPreview();
    }
    
    function setDegree(deg){
        degree += deg;
        rotateCanvas();
    }
    
    function rotateCanvas(){
        canvas.el.style.MozTransform = 'rotateZ(' + deg + 'deg)';
        canvas.el.style.webkitTransform = 'rotateZ(' + deg + 'deg)';
        canvas.el.style.oTransform = 'rotateZ(' + deg + 'deg)';
        canvas.el.style.msTransform = 'rotateZ(' + deg + 'deg)';    
    }
    
    $.sketch.tools.save = {
        onEvent: function(){
            //console.log('save onEvent');
        },
        draw: function(){
            //console.log('save draw')
        }
    }
    
    $.sketch.tools.settings = {
        onEvent: function(){
            //
        },
        draw: function(){
            //
        }
    }
    
    function loadIcon(icons){
        var baseUrl = 'https://googledrive.com/host/0B1BW1N6rqpWFa0lTUW1aZThuT28/';
    
        for(var key in icons){
            var img = new Image();
            img.id = key;
            img.src = baseUrl + icons[key];
            img.style.display = 'none';
            $('#oekakiCanvas').append(img);
        }
    }
    
    $(document).keydown(function(e){
        keydownEvent(e, 37, canvas.actions, drawRedo);
        keydownEvent(e, 39, drawRedo, canvas.actions);
    });
    
    
    $("#backButton").unbind();
    $("#backButton").click(function() {
        changeAction(canvas.actions, drawRedo);
    });
    
    function keydownEvent(e, keyNum, popList, pushList){
        if(e.which === keyNum && e.ctrlKey && popList.length > 0){
            changeAction(popList, pushList);
    
            return false;
        }
    }
    
    function changeAction(popList, pushList){
        pushList.push(popList.pop());
        canvas.redraw();
        if(settings.layerOn) updatePreview();
    }
    
    
    canvas.redraw = function() {
        var sketch;
        this.el.width = realW;
        this.el.height = realH;
        this.el.style.width = scaleW;
        this.el.style.height = scaleH;
        this.context = this.el.getContext('2d');
        this.context.fillStyle = this.bgcolor;
        this.context.fillRect(0, 0, this.canvas.width(), this.canvas.height());
        if (canvas.baseImageURL) {
            if (this.baseImageCache) {
                this.context.drawImage(this.baseImageCache, 0, 0);
            } else {
                var img = new Image();
                var _this = this;
                img.src = this.baseImageURL;
                img.onload = (function() {
                    _this.baseImageCache = img;
                    _this.context.drawImage(img, 0, 0);
                });
            }
        }
        sketch = this;
        $.each(this.actions, function() {
            if (this.tool) {
                return $.sketch.tools[this.tool].draw.call(sketch, this);
            }
        });
        if (this.painting && this.action) {
            return $.sketch.tools[this.action.tool].draw.call(sketch, this.action);
        }
    };
    
    canvas.stopPainting = function(){
        if (this.action) {
           this.actions.push(this.action);
        }
        this.painting = false;
        this.action = null;
        if(settings.layerOn) updatePreview();
    };
    
    $.sketch.tools.marker = {
        onEvent: function(e) {
            switch (e.type) {
                case 'mousedown':
                case 'touchstart':
                    this.startPainting();
                    break;
                case 'mouseup':
                case 'mouseout':
                case 'mouseleave':
                case 'touchend':
                case 'touchcancel':
                    this.stopPainting();
            }
            if (this.painting) {
                var pos = getPosition(e);
                this.action.events.push({x: pos.x,y: pos.y,event: e.type});
                return this.redraw();
            }
        },draw: function(action) {
            var event, previous, _i, _len, _ref;
            this.context.lineJoin = "round";
            this.context.lineCap = "round";
            this.context.beginPath();
            this.context.moveTo(action.events[0].x, action.events[0].y);
            _ref = action.events;
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
                event = _ref[_i];
                this.context.lineTo(event.x, event.y);
                previous = event;
            }
            this.context.strokeStyle = action.color;
            this.context.lineWidth = action.size;
            return this.context.stroke();
        }
    };
    
    $.sketch.tools.eraser = {
        onEvent: function(e) {
            $.sketch.tools.marker.onEvent.call(this, e);
        },draw: function(action) {
            var oldcomposite;
            oldcomposite = this.context.globalCompositeOperation;
            if(browser == "chrome"){
                this.context.globalCompositeOperation = "copy";
                action.color = this.bgcolor;
            }else{
                this.context.globalCompositeOperation = "destination-out";
                action.color = 'rgb(0, 0, 0)';
            }
    
            $.sketch.tools.marker.draw.call(this, action);
            this.context.globalCompositeOperation = oldcomposite;
        }
    };
    
    $("#canvasSize").unbind();
    $("#canvasSize").change(function() {
        setCanvasScale();
        
        $('canvas[id^=layerCanvas]').each(function(i){
            this.width = realW;
            this.height = realH;
        });
    
        $('canvas[id^=preview]').each(function(i){
            this.width = realW;
            this.height = realH;
    
            this.style.width = realW * PREVIEW_SIZE;
            this.style.height = realH * PREVIEW_SIZE;
        });
    
        var tmpCanvas = $('#tmpCanvas')[0];
        tmpCanvas.width = realW;
        tmpCanvas.height = realH;
    
        changeCanvasScale();
    });
    
    setFile = function(file) {
        var img = new Image();
        var fileReader = new FileReader();
        fileReader.onload = function(event) {
            $(img).attr('src', event.target.result);
        }
        fileReader.readAsDataURL(file);
        img.onload = function() {
            fitImage(canvas.context, img);
            canvas.setBaseImageURL(canvas.el.toDataURL());
            isOekakiDone = 1;
        };
    }
    
    $('#submit_button').click(function(){
        if(isOekakiDone){
            addLayer();
            fixPreview();
            mergeLayer(canvas.el);
    
            var imgData = canvas.context.getImageData(0, 0, canvas.el.width, canvas.el.height);
    
            var imgCanvas = $('<canvas>').attr({
                id: 'imgCanvas',
                width: canvas.el.width,
                height: canvas.el.height,
                style: 'border: 10pt ridge #D00; background: #EEE;'
            });
    
            imgCanvas[0].getContext('2d').putImageData(imgData, 0, 0);
            $('#oekakiMode').before(imgCanvas);
    
            var result = false;
            if(window.confirm('この内容で投稿しますか?')){
                result = true;
            }
    
            deleteLayer(layers.length-2);
            imgCanvas.remove();
            canvas.context.putImageData(imgData, 0, 0);
            return result;
        }
    });
    
    $(window).bind('beforeunload', function(e) {
        if(isOekakiDone){
            return 'お絵かきの途中のようです。';
        }
    });
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。

History

  1. 2014/08/17 15:19:12 - 2014-08-17
  2. 2014/07/25 18:17:25 - 2014-07-25
  3. 2014/06/15 22:58:18 - 2014-06-15
  4. 2014/06/12 22:55:45 - 2014-06-12
  5. 2014/06/08 22:13:05 - 2014-06-08
  6. 2014/06/08 19:01:10 - 2014-06-08
  7. 2014/06/07 23:59:27 - 2014-06-07
  8. 2014/06/04 23:43:06 - 2014-06-04
  9. 2014/06/02 15:20:24 - 2014-06-02
  10. 2014/06/01 17:49:08 - 2014-06-01
  11. 2014/05/28 23:01:10 - 2014-05-28
  12. 2014/05/28 21:17:42 - 2014-05-28
  13. 2014/05/28 00:38:24 - 2014-05-28
  14. 2014/05/28 00:37:53 - 2014-05-28
  15. 2014/05/28 00:35:44 - 2014-05-28
  16. 2014/05/28 00:30:52 - 2014-05-28
  17. 2014/05/27 00:16:58 - 2014-05-27
  18. 2014/05/25 20:20:52 - 2014-05-25
  19. 2014/05/17 17:09:01 - 2014-05-17
  20. 2014/05/11 01:15:56 - 2014-05-11
  21. 2014/05/07 22:45:33 - 2014-05-07
  22. 2014/05/07 22:18:28 - 2014-05-07
  23. 2014/05/06 20:25:53 - 2014-05-06
  24. 2014/05/06 20:17:36 - 2014-05-06
  25. 2014/05/05 13:10:28 - 2014-05-05
  26. 2014/05/03 21:57:01 - 2014-05-03
  27. 2014/05/03 21:40:44 - 2014-05-03
  28. 2014/05/03 21:19:54 - 2014-05-03
  29. 2014/05/01 23:11:00 - 2014-05-01
  30. 2014/05/01 22:29:09 - 2014-05-01
  31. 2014/05/01 22:27:31 - 2014-05-01
  32. 2014/04/29 19:12:48 - 2014-04-29
  33. 2014/04/29 17:28:57 - 2014-04-29
  34. 2014/04/29 17:27:44 - 2014-04-29
  35. 2014/04/29 17:02:37 - 2014-04-29
  36. 2014/04/28 00:51:26 - 2014-04-28
  37. 2014/04/24 01:18:19 - 2014-04-24
  38. 2014/04/20 18:09:29 - 2014-04-20
  39. 2014/04/20 02:23:05 - 2014-04-20
  40. 2014/04/20 02:21:40 - 2014-04-20
  41. 2014/04/20 01:39:54 - 2014-04-20
  42. 2014/04/20 01:38:41 - 2014-04-20
  43. 2014/04/20 01:37:58 - 2014-04-20
  44. 2014/04/20 00:17:06 - 2014-04-20
  45. 2014/04/10 22:03:04 - 2014-04-10
  46. 2014/04/10 21:38:09 - 2014-04-10
  47. 2014/04/10 21:36:19 - 2014-04-10
  48. 2014/04/08 22:09:27 - 2014-04-08
  49. 2014/04/08 22:00:21 - 2014-04-08