From e9b889532d81705aadf8049af6ff018b2a935764 Mon Sep 17 00:00:00 2001 From: Desuwa Date: Thu, 26 Sep 2019 15:43:13 +0200 Subject: [PATCH] 0.3.0 - Faster paint functions - Pressure fixes - Open File feature --- .jshintrc | 2 + js/main.js | 12 ++-- js/tools/airbrush.js | 2 + js/tools/blur.js | 120 +++++++++++++++++++++++++++++++-------- js/tools/brush.js | 130 ++++++++++++++++++++++++++++--------------- js/tools/bucket.js | 7 ++- js/tools/burn.js | 37 ++++++------ js/tools/dodge.js | 36 ++++++------ js/tools/eraser.js | 25 +++++---- js/tools/pen.js | 18 +++++- js/tools/pencil.js | 35 ++++++------ js/tools/pipette.js | 1 - js/tools/tone.js | 30 +++++----- 13 files changed, 299 insertions(+), 156 deletions(-) diff --git a/.jshintrc b/.jshintrc index a75af40..3cc7cbc 100644 --- a/.jshintrc +++ b/.jshintrc @@ -14,6 +14,8 @@ "esversion": 6, "globals": { + "ImageData": true, + "$T": true, "Tegaki": true, "TegakiPencil": true, diff --git a/js/main.js b/js/main.js index 256de7a..a3babbf 100644 --- a/js/main.js +++ b/js/main.js @@ -1,7 +1,7 @@ var Tegaki; Tegaki = { - VERSION: '0.2.1', + VERSION: '0.3.0', bg: null, canvas: null, @@ -22,7 +22,7 @@ Tegaki = { activeLayer: null, layerIndex: null, - skipPointerMove: false, + activePointerId: 0, isPainting: false, isErasing: false, @@ -1167,8 +1167,8 @@ Tegaki = { }, onPointerMove: function(e) { - if (Tegaki.skipPointerMove) { - Tegaki.skipPointerMove = false; + if (Tegaki.activePointerId !== e.pointerId) { + Tegaki.activePointerId = e.pointerId; return; } @@ -1189,6 +1189,8 @@ Tegaki = { return; } + Tegaki.activePointerId = e.pointerId; + if (e.target.parentNode === Tegaki.layersCnt) { if (Tegaki.activeLayer === null) { alert(TegakiStrings.noActiveLayer); @@ -1230,7 +1232,7 @@ Tegaki = { }, onPointerUp: function(e) { - Tegaki.skipPointerMove = true; + Tegaki.activePointerId = e.pointerId; if (Tegaki.isPainting) { Tegaki.tool.commit && Tegaki.tool.commit(); diff --git a/js/tools/airbrush.js b/js/tools/airbrush.js index fcce46f..b49d02c 100644 --- a/js/tools/airbrush.js +++ b/js/tools/airbrush.js @@ -5,6 +5,8 @@ TegakiAirbrush = { keybind: 'a', + useGhostLayer: true, + init: function() { this.size = 32; this.alpha = 0.5; diff --git a/js/tools/blur.js b/js/tools/blur.js index ce5e0cd..5a2ce5a 100644 --- a/js/tools/blur.js +++ b/js/tools/blur.js @@ -10,7 +10,6 @@ TegakiBlur = { this.step = 0.25; this.stepAcc = 0; - this.draw = TegakiBrush.draw; this.generateBrush = TegakiBrush.generateBrush; this.setSize = TegakiBrush.setSize; this.setAlpha = TegakiBrush.setAlpha; @@ -18,37 +17,40 @@ TegakiBlur = { this.set = TegakiBrush.set; }, - brushFn: function(x, y) { - var i, j, ctx, src, size, srcData, dest, destData, lim, kernel, - sx, sy, r, g, b, a, aa, acc, kx, ky; + brushFn: function(x, y, src, imgData) { + var i, j, size, srcData, destData, limX, limY, kernel, + sx, sy, r, g, b, a, aa, acc, kx, ky, px, w, h; x = 0 | x; y = 0 | y; size = this.brushSize; - ctx = Tegaki.activeCtx; - src = ctx.getImageData(x, y, size, size); srcData = src.data; - dest = ctx.createImageData(size, size); - destData = dest.data; + destData = imgData.data; kernel = this.kernel; - lim = size - 1; + + w = imgData.width; + h = imgData.height; + limX = w - 1; + limY = h - 1; for (sx = 0; sx < size; ++sx) { for (sy = 0; sy < size; ++sy) { r = g = b = a = acc = 0; i = (sy * size + sx) * 4; - if (kernel[(sy * size + sx) * 4 + 3] === 0 - || sx === 0 || sy === 0 || sx === lim || sy === lim) { - destData[i] = srcData[i]; ++i; - destData[i] = srcData[i]; ++i; - destData[i] = srcData[i]; ++i; - destData[i] = srcData[i]; + px = ((sy + y) * w + (sx + x)) * 4; + + if (kernel[i + 3] === 0 || sx === 0 || sy === 0 || (sx + x) === limX || (sy + y) === limY) { + destData[px] = srcData[px]; ++px; + destData[px] = srcData[px]; ++px; + destData[px] = srcData[px]; ++px; + destData[px] = srcData[px]; continue; } + for (kx = -1; kx < 2; ++kx) { for (ky = -1; ky < 2; ++ky) { - j = ((sy - ky) * size + (sx - kx)) * 4; + j = ((sy + y - ky) * w + (sx + x - kx)) * 4; aa = srcData[j + 3]; acc += aa; r += srcData[j] * aa; ++j; @@ -57,17 +59,89 @@ TegakiBlur = { a += srcData[j]; } } - destData[i] = r / acc; ++i; - destData[i] = g / acc; ++i; - destData[i] = b / acc; ++i; - destData[i] = a / 9; + + destData[px] = r / acc; ++px; + destData[px] = g / acc; ++px; + destData[px] = b / acc; ++px; + destData[px] = a / 9; } } - - ctx.putImageData(dest, x, y); }, - draw: null, + draw: function(posX, posY, pt) { + var mx, my, fromX, fromY, sx, sy, dx, dy, err, derr, stepAcc, + srcImgData, destImgData, center, tainted; + + center = this.center; + + if (pt === true) { + this.stepAcc = 0; + this.posX = posX; + this.posY = posY; + + srcImgData = Tegaki.activeCtx.getImageData( + posX - this.center, + posY - this.center, + this.brushSize, this.brushSize + ); + + destImgData = new ImageData(new Uint8ClampedArray(srcImgData.data), srcImgData.width); + + this.brushFn(0, 0, srcImgData, destImgData); + + Tegaki.activeCtx.putImageData(destImgData, posX - center, posY - center); + + return; + } + + stepAcc = this.stepAcc; + + fromX = this.posX; + fromY = this.posY; + + if (fromX < posX) { dx = posX - fromX; sx = fromX - center; mx = 1; } + else { dx = fromX - posX; sx = posX - center; mx = -1; } + + if (fromY < posY) { dy = posY - fromY; sy = fromY - center; my = 1; } + else { dy = fromY - posY; sy = posY - center; my = -1; } + + + srcImgData = Tegaki.activeCtx.getImageData(sx, sy, dx + this.brushSize, dy + this.brushSize); + destImgData = new ImageData(new Uint8ClampedArray(srcImgData.data), srcImgData.width); + + err = (dx > dy ? dx : -dy) / 2; + + dx = -dx; + + tainted = false; + + while (true) { + ++stepAcc; + + if (stepAcc > this.stepSize) { + this.brushFn(fromX - center - sx, fromY - center - sy, srcImgData, destImgData); + tainted = true; + stepAcc = 0; + } + + if (fromX === posX && fromY === posY) { + break; + } + + derr = err; + + if (derr > dx) { err -= dy; fromX += mx; } + if (derr < dy) { err -= dx; fromY += my; } + } + + this.stepAcc = stepAcc; + this.posX = posX; + this.posY = posY; + + if (tainted) { + Tegaki.activeCtx.putImageData(destImgData, sx, sy); + } + }, generateBrush: null, diff --git a/js/tools/brush.js b/js/tools/brush.js index 7550b91..8d1651a 100644 --- a/js/tools/brush.js +++ b/js/tools/brush.js @@ -3,61 +3,75 @@ var TegakiBrush; TegakiBrush = { name: 'brush', - brushFn: function(x, y) { - var i, ctx, dest, data, len, kernel; + brushFn: function(x, y, imgData) { + var i, data, kernel, w, xx, yy, px, brushSize; x = 0 | x; y = 0 | y; - ctx = Tegaki.ghostCtx; - dest = ctx.getImageData(x, y, this.brushSize, this.brushSize); - data = dest.data; + brushSize = this.brushSize; + kernel = this.kernel; - len = kernel.length; - i = 0; - while (i < len) { - data[i] = this.rgb[0]; ++i; - data[i] = this.rgb[1]; ++i; - data[i] = this.rgb[2]; ++i; - data[i] += kernel[i] * (1.0 - data[i] / 255); ++i; - } + data = imgData.data; + w = imgData.width; - ctx.putImageData(dest, x, y); + for (yy = 0; yy < brushSize; ++yy) { + for (xx = 0; xx < brushSize; ++xx) { + i = (yy * brushSize + xx) * 4; + px = ((y + yy) * w + (x + xx)) * 4; + + data[px] = this.rgb[0]; ++px; + data[px] = this.rgb[1]; ++px; + data[px] = this.rgb[2]; ++px; + data[px] += kernel[i + 3] * (1.0 - data[px] / 255); ++i; + } + } }, - generateBrushCache: function() { + generateBrushCache: function(force) { var i, tmp; + if (force || !this.pressureCache[0]) { + this.pressureCache = []; + i = 0; + } + else { + i = this.pressureCache.length; + } + tmp = this.size; - for (i = this.pressureCache.length; i < tmp; ++i) { + for (; i < tmp; ++i) { this.size = i + 1; + this.generateBrush(); - this.pressureCache.push(this.kernel); + + this.pressureCache[i] = { + kernel: this.kernel, + brushSize: this.brushSize, + center: this.center, + stepSize: this.stepSize + }; } this.size = tmp; }, updateDynamics: function(t) { - var pressure, size, d; + var pressure, brush; pressure = TegakiPressure.lerp(t); - if (this.sizePressureCtrl === true) { - size = 0 | Math.ceil(pressure * this.size); - - d = 0 | Math.round((size - this.size) / 2); - - this.center = 0 | (size / 2); - - this.kernel = this.pressureCache[size - 1]; - - this.stepSize = 0 | Math.min(Math.floor(size * this.step), 8); - - this.brushSize = size; - } + brush = this.pressureCache[Math.ceil(pressure * this.size) - 1]; + + this.center = brush.center; + + this.kernel = brush.kernel; + + this.stepSize = brush.stepSize; + + this.brushSize = brush.brushSize; }, commit: function() { @@ -66,10 +80,10 @@ TegakiBrush = { }, draw: function(posX, posY, pt) { - var mx, my, fromX, fromY, dx, dy, err, derr, stepAcc, - distBase, distLeft; + var mx, my, fromX, fromY, offsetX, offsetY, dx, dy, err, derr, stepAcc, + distBase, distLeft, imgData, ctx, brush, center, brushSize; - stepAcc = this.stepAcc; + ctx = this.useGhostLayer ? Tegaki.ghostCtx : Tegaki.activeCtx; if (pt === true) { this.stepAcc = 0; @@ -80,26 +94,49 @@ TegakiBrush = { this.updateDynamics(1.0); } - this.brushFn(posX - this.center, posY - this.center); + imgData = ctx.getImageData( + posX - this.center, + posY - this.center, + this.brushSize, this.brushSize + ); + + this.brushFn(0, 0, imgData, posX - this.center, posY - this.center); + + ctx.putImageData(imgData, posX - this.center, posY - this.center); return; } + stepAcc = this.stepAcc; + fromX = this.posX; fromY = this.posY; - if (fromX < posX) { dx = posX - fromX; mx = 1; } - else { dx = fromX - posX; mx = -1; } - if (fromY < posY) { dy = posY - fromY; my = 1; } - else { dy = fromY - posY; my = -1; } + if (fromX < posX) { dx = posX - fromX; offsetX = fromX; mx = 1; } + else { dx = fromX - posX; offsetX = posX; mx = -1; } - err = (dx > dy ? dx : -dy) / 2; + if (fromY < posY) { dy = posY - fromY; offsetY = fromY; my = 1; } + else { dy = fromY - posY; offsetY = posY; my = -1; } - dx = -dx; if (this.sizePressureCtrl) { + brush = this.pressureCache[this.size - 1]; + center = brush.center; + brushSize = brush.brushSize; distBase = Math.sqrt((posX - fromX) * (posX - fromX) + (posY - fromY) * (posY - fromY)); } + else { + center = this.center; + brushSize = this.brushSize; + } + + offsetX -= center; + offsetY -= center; + + imgData = ctx.getImageData(offsetX, offsetY, dx + brushSize, dy + brushSize); + + err = (dx > dy ? dx : -dy) / 2; + dx = -dx; while (true) { ++stepAcc; @@ -108,10 +145,10 @@ TegakiBrush = { if (this.sizePressureCtrl) { distLeft = Math.sqrt((posX - fromX) * (posX - fromX) + (posY - fromY) * (posY - fromY)); this.updateDynamics(1.0 - (distLeft / distBase)); - this.brushFn(fromX - this.center, fromY - this.center); + this.brushFn(fromX - this.center - offsetX, fromY - this.center - offsetY, imgData, offsetX, offsetY); } else { - this.brushFn(fromX - this.center, fromY - this.center); + this.brushFn(fromX - this.center - offsetX, fromY - this.center - offsetY, imgData, offsetX, offsetY); } stepAcc = 0; @@ -130,6 +167,8 @@ TegakiBrush = { this.stepAcc = stepAcc; this.posX = posX; this.posY = posY; + + ctx.putImageData(imgData, offsetX, offsetY); }, generateBrush: function() { @@ -191,6 +230,7 @@ TegakiBrush = { ctx.putImageData(dest, 0, 0); this.center = r; + this.stepSize = 0 | Math.min(Math.floor(size * this.step), 8); this.brushSize = size; this.brush = brush; this.kernel = data; @@ -207,13 +247,11 @@ TegakiBrush = { this.generateBrush(); } } - - this.stepSize = Math.min(Math.floor(this.size * this.step), 8); }, setAlpha: function(alpha, noBrush) { this.alpha = alpha; - if (!noBrush) this.generateBrush(); + if (!noBrush) { this.generateBrush(); } }, setColor: function(color, noBrush) { diff --git a/js/tools/bucket.js b/js/tools/bucket.js index 95c2120..4a7b061 100644 --- a/js/tools/bucket.js +++ b/js/tools/bucket.js @@ -14,7 +14,6 @@ TegakiBucket = { this.stepAcc = 0; this.commit = TegakiBrush.commit; - this.draw = TegakiBrush.draw; this.generateBrush = TegakiPen.generateBrush; this.setSize = TegakiBrush.setSize; this.setAlpha = TegakiBrush.setAlpha; @@ -174,9 +173,11 @@ TegakiBucket = { ; }, - commit: null, + draw: function(x, y, pt) { + this.brushFn(x, y); + }, - draw: null, + commit: null, generateBrush: null, diff --git a/js/tools/burn.js b/js/tools/burn.js index 19bf59f..ce866dc 100644 --- a/js/tools/burn.js +++ b/js/tools/burn.js @@ -10,7 +10,7 @@ TegakiBurn = { this.step = 0.25; this.stepAcc = 0; - this.draw = TegakiBrush.draw; + this.draw = TegakiBrush.draw; this.generateBrush = TegakiBrush.generateBrush; this.setSize = TegakiBrush.setSize; this.setAlpha = TegakiBrush.setAlpha; @@ -18,28 +18,31 @@ TegakiBurn = { this.set = TegakiBrush.set; }, - brushFn: function(x, y) { - var i, a, ctx, dest, data, len, kernel; + brushFn: function(x, y, imgData) { + var data, a, kernel, w, xx, yy, px, brushSize; x = 0 | x; y = 0 | y; - ctx = Tegaki.activeCtx; - dest = ctx.getImageData(x, y, this.brushSize, this.brushSize); - data = dest.data; + brushSize = this.brushSize; + kernel = this.kernel; - len = kernel.length; - - i = 0; - while (i < len) { - a = 1 - kernel[i + 3] / 255; - data[i] = data[i] * a; ++i; - data[i] = data[i] * a; ++i; - data[i] = data[i] * a; ++i; - ++i; - } - ctx.putImageData(dest, x, y); + data = imgData.data; + w = imgData.width; + + a = 0 | (this.alpha * 255); + + for (yy = 0; yy < brushSize; ++yy) { + for (xx = 0; xx < brushSize; ++xx) { + px = ((y + yy) * w + (x + xx)) * 4; + + a = 1 - kernel[((yy * brushSize + xx) * 4) + 3] / 255; + data[px] = data[px] * a; ++px; + data[px] = data[px] * a; ++px; + data[px] = data[px] * a; ++px; + } + } }, draw: null, diff --git a/js/tools/dodge.js b/js/tools/dodge.js index 22be417..d2d4a16 100644 --- a/js/tools/dodge.js +++ b/js/tools/dodge.js @@ -10,7 +10,7 @@ TegakiDodge = { this.step = 0.25; this.stepAcc = 0; - this.draw = TegakiBrush.draw; + this.draw = TegakiBrush.draw; this.generateBrush = TegakiBrush.generateBrush; this.setSize = TegakiBrush.setSize; this.setAlpha = TegakiBrush.setAlpha; @@ -18,29 +18,31 @@ TegakiDodge = { this.set = TegakiBrush.set; }, - brushFn: function(x, y) { - var i, a, aa, ctx, dest, data, len, kernel; + brushFn: function(x, y, imgData) { + var data, a, aa, kernel, w, xx, yy, px, brushSize; x = 0 | x; y = 0 | y; - ctx = Tegaki.activeCtx; - dest = ctx.getImageData(x, y, this.brushSize, this.brushSize); - data = dest.data; + brushSize = this.brushSize; + kernel = this.kernel; - len = kernel.length; - i = 0; - while (i < len) { - aa = kernel[i + 3] * 0.3; - a = 1 + kernel[i + 3] / 255; - data[i] = data[i] * a + aa; ++i; - data[i] = data[i] * a + aa; ++i; - data[i] = data[i] * a + aa; ++i; - ++i; - } + data = imgData.data; + w = imgData.width; - ctx.putImageData(dest, x, y); + a = 0 | (this.alpha * 255); + + for (yy = 0; yy < brushSize; ++yy) { + for (xx = 0; xx < brushSize; ++xx) { + px = ((y + yy) * w + (x + xx)) * 4; + aa = kernel[(yy * brushSize + xx) + 3] * 0.3; + a = 1 + kernel[((yy * brushSize + xx) * 4) + 3] / 255; + data[px] = data[px] * a + aa; ++px; + data[px] = data[px] * a + aa; ++px; + data[px] = data[px] * a + aa; ++px; + } + } }, draw: null, diff --git a/js/tools/eraser.js b/js/tools/eraser.js index 3a432cd..2e7b8af 100644 --- a/js/tools/eraser.js +++ b/js/tools/eraser.js @@ -19,25 +19,28 @@ TegakiEraser = { this.set = TegakiBrush.set; }, - brushFn: function(x, y) { - var i, ctx, dest, data, len, kernel; + brushFn: function(x, y, imgData) { + var data, a, kernel, w, xx, yy, brushSize; x = 0 | x; y = 0 | y; - ctx = Tegaki.activeCtx; - dest = ctx.getImageData(x, y, this.brushSize, this.brushSize); - data = dest.data; + brushSize = this.brushSize; + kernel = this.kernel; - len = kernel.length; - for (i = 3; i < len; i += 4) { - if (kernel[i] > 0) { - data[i] = 0; + data = imgData.data; + w = imgData.width; + + a = 0 | (this.alpha * 255); + + for (yy = 0; yy < brushSize; ++yy) { + for (xx = 0; xx < brushSize; ++xx) { + if (kernel[(yy * brushSize + xx) * 4 + 3] > 0) { + data[((y + yy) * w + (x + xx)) * 4 + 3] = 0; + } } } - - ctx.putImageData(dest, x, y); }, draw: null, diff --git a/js/tools/pen.js b/js/tools/pen.js index bdf3688..826a9a4 100644 --- a/js/tools/pen.js +++ b/js/tools/pen.js @@ -5,6 +5,7 @@ TegakiPen = { keybind: 'p', + useGhostLayer: true, sizePressureCtrl: false, pressureCache: [], @@ -18,7 +19,6 @@ TegakiPen = { this.commit = TegakiBrush.commit; this.brushFn = TegakiBrush.brushFn; this.setSize = TegakiBrush.setSize; - this.setAlpha = TegakiBrush.setAlpha; this.setColor = TegakiBrush.setColor; this.set = TegakiBrush.set; this.setSizePressureCtrl = TegakiBrush.setSizePressureCtrl; @@ -43,11 +43,25 @@ TegakiPen = { ctx.closePath(); this.center = r; + this.stepSize = 0 | Math.min(Math.floor(size * this.step), 8); this.brushSize = size; this.brush = brush; this.kernel = ctx.getImageData(0, 0, this.brushSize, this.brushSize).data; }, + setAlpha: function(alpha, noBrush) { + this.alpha = alpha; + + if (!noBrush) { + if (this.sizePressureCtrl === true) { + this.generateBrushCache(true); + } + else { + this.generateBrush(); + } + } + }, + draw: null, commit: null, @@ -56,8 +70,6 @@ TegakiPen = { setSize: null, - setAlpha: null, - setColor: null, set: null, diff --git a/js/tools/pencil.js b/js/tools/pencil.js index cbeb485..5c2d276 100644 --- a/js/tools/pencil.js +++ b/js/tools/pencil.js @@ -5,6 +5,7 @@ TegakiPencil = { keybind: 'b', + useGhostLayer: true, sizePressureCtrl: false, pressureCache: [], @@ -25,34 +26,35 @@ TegakiPencil = { this.generateBrushCache = TegakiBrush.generateBrushCache; }, - brushFn: function(x, y) { - var i, ctx, dest, data, len, a, kernel; + brushFn: function(x, y, imgData) { + var i, data, a, kernel, w, xx, yy, px, brushSize; x = 0 | x; y = 0 | y; - ctx = Tegaki.ghostCtx; + brushSize = this.brushSize; - dest = ctx.getImageData(x, y, this.brushSize, this.brushSize); kernel = this.kernel; - len = kernel.length; - data = dest.data; + data = imgData.data; + w = imgData.width; a = 0 | (this.alpha * 255); - i = 0; - while (i < len) { - data[i] = this.rgb[0]; ++i; - data[i] = this.rgb[1]; ++i; - data[i] = this.rgb[2]; ++i; - if (kernel[i] > 0) { - data[i] = a; + for (yy = 0; yy < brushSize; ++yy) { + for (xx = 0; xx < brushSize; ++xx) { + i = (yy * brushSize + xx) * 4; + px = ((y + yy) * w + (x + xx)) * 4; + + data[px] = this.rgb[0]; ++px; + data[px] = this.rgb[1]; ++px; + data[px] = this.rgb[2]; ++px; + + if (kernel[i + 3] > 0) { + data[px] = a; + } } - ++i; } - - ctx.putImageData(dest, x, y); }, generateBrush: function() { @@ -108,6 +110,7 @@ TegakiPencil = { } this.center = r; + this.stepSize = 0 | Math.min(Math.floor(size * this.step), 8); this.brushSize = size; this.brush = brush; this.kernel = imageData.data; diff --git a/js/tools/pipette.js b/js/tools/pipette.js index 3ddbd39..cf4b1c5 100644 --- a/js/tools/pipette.js +++ b/js/tools/pipette.js @@ -22,7 +22,6 @@ TegakiPipette = { c = Tegaki.getColorAt(ctx, posX, posY); Tegaki.setToolColor(c); - Tegaki.updateUI('color'); }, set: function() { diff --git a/js/tools/tone.js b/js/tools/tone.js index ed3d5e9..d849c6a 100644 --- a/js/tools/tone.js +++ b/js/tools/tone.js @@ -5,6 +5,8 @@ TegakiTone = { keybind: 't', + useGhostLayer: true, + matrix: null, data: null, @@ -35,34 +37,36 @@ TegakiTone = { this.set = TegakiBrush.set; }, - brushFn: function(x, y) { - var ctx, dest, data, kernel, brushSize, map, - px, mapWidth, mapHeight, xx, yy; + brushFn: function(x, y, imgData, offsetX, offsetY) { + var data, kernel, brushSize, map, + px, mapWidth, mapHeight, xx, yy, gx, gy, w; x = 0 | x; y = 0 | y; - ctx = Tegaki.ghostCtx; - dest = ctx.getImageData(x, y, this.brushSize, this.brushSize); - data = dest.data; + gx = 0 | (x + offsetX); + gy = 0 | (y + offsetY); + + data = imgData.data; kernel = this.kernel; brushSize = this.brushSize; - mapWidth = Tegaki.canvas.width; - mapHeight = Tegaki.canvas.height; + mapWidth = Tegaki.baseWidth; + mapHeight = Tegaki.baseHeight; + + w = imgData.width; map = this.generate(mapWidth, mapHeight); for (yy = 0; yy < brushSize; ++yy) { for (xx = 0; xx < brushSize; ++xx) { - px = (brushSize * yy + xx) * 4; - - if (kernel[px + 3] === 0) { + if (kernel[((yy * brushSize + xx) * 4) + 3] === 0) { continue; } - if (map[(yy + y) * mapWidth + xx + x] === 0) { + if (map[(yy + gy) * mapWidth + xx + gx] === 0) { + px = ((yy + y) * w + xx + x) * 4; data[px] = this.rgb[0]; ++px; data[px] = this.rgb[1]; ++px; data[px] = this.rgb[2]; ++px; @@ -70,8 +74,6 @@ TegakiTone = { } } } - - ctx.putImageData(dest, x, y); }, generate: function(w, h) {