avm99963 | 04def3e | 2016-11-27 22:53:05 +0100 | [diff] [blame] | 1 | function Canvas() {}
|
| 2 |
|
| 3 | Canvas.prototype.drawStrokeRect = function(
|
| 4 | ctx, color, x, y, width, height, lineWidth) {
|
| 5 | ctx.strokeStyle = color;
|
| 6 | ctx.lineWidth = lineWidth;
|
| 7 | ctx.strokeRect(x, y, width, height);
|
| 8 | }
|
| 9 |
|
| 10 | Canvas.prototype.drawFillRect = function(ctx, color, x, y, width, height) {
|
| 11 | ctx.fillStyle = color;
|
| 12 | ctx.fillRect(x, y, width, height);
|
| 13 | }
|
| 14 |
|
| 15 | Canvas.prototype.drawEllipse = function(
|
| 16 | ctx, color, x, y, xAxis, yAxis, lineWidth, type) {
|
| 17 | var startX = x + xAxis;
|
| 18 | var startY = y;
|
| 19 | ctx.beginPath();
|
| 20 | ctx.lineWidth = lineWidth;
|
| 21 | ctx.moveTo(startX, startY);
|
| 22 | for (var i = 0; i <= 360; i++) {
|
| 23 | var degree = i * Math.PI / 180;
|
| 24 | startX = x + (xAxis - 2) * Math.cos(degree);
|
| 25 | startY = y - (yAxis - 2) * Math.sin(degree);
|
| 26 | ctx.lineTo(startX, startY);
|
| 27 | }
|
| 28 | if (type == 'rect') {
|
| 29 | ctx.fillStyle = changeColorToRgba(color, 0.5);
|
| 30 | ctx.fill();
|
| 31 | } else if (type == 'border') {
|
| 32 | ctx.strokeStyle = color;
|
| 33 | ctx.stroke();
|
| 34 | }
|
| 35 | ctx.closePath();
|
| 36 | }
|
| 37 |
|
| 38 | // Divide an entire phrase in an array of phrases, all with the max pixel
|
| 39 | // length given.
|
| 40 | Canvas.prototype.getLines = function(ctx, text, width, font) {
|
| 41 | var words = text.split(" ");
|
| 42 | var lines = [];
|
| 43 | var lastLine = "";
|
| 44 | var measure = 0;
|
| 45 | ctx.font = font;
|
| 46 | for (var i = 0; i < words.length; i++) {
|
| 47 | var word = words[i];
|
| 48 | measure = ctx.measureText(lastLine + word).width;
|
| 49 | if (measure <= width || word == "") {
|
| 50 | lastLine += word + " ";
|
| 51 | } else {
|
| 52 | if (lastLine != "")
|
| 53 | lines.push(lastLine);
|
| 54 |
|
| 55 | // break the word if necessary
|
| 56 | measure = ctx.measureText(word).width;
|
| 57 | if (measure <= width) {
|
| 58 | lastLine = word + " ";
|
| 59 | } else {
|
| 60 | lastLine = word[0];
|
| 61 | for (var j = 1; j < word.length; j++) {
|
| 62 | measure = ctx.measureText(lastLine + word[j]).width;
|
| 63 | if (measure <= width) {
|
| 64 | lastLine += word[j];
|
| 65 | } else {
|
| 66 | lines.push(lastLine);
|
| 67 | lastLine = word[j];
|
| 68 | }
|
| 69 | }
|
| 70 | lastLine += " ";
|
| 71 | }
|
| 72 | }
|
| 73 | }
|
| 74 | if (lastLine != "")
|
| 75 | lines.push(lastLine);
|
| 76 | return lines;
|
| 77 | }
|
| 78 |
|
| 79 | Canvas.prototype.setText = function(
|
| 80 | ctx, text, color, fontSize, fontFamily, lineHeight, x, y, width) {
|
| 81 | ctx.textBaseline = 'top';
|
| 82 | ctx.fillStyle = color;
|
| 83 | ctx.font = fontSize + ' ' + fontFamily;
|
| 84 | ctx.lineHeight = lineHeight;
|
| 85 | var lines = Canvas.prototype.getLines(ctx, text, width - 2, ctx.font);
|
| 86 | for (var i = 0; i < lines.length; i++)
|
| 87 | ctx.fillText(lines[i], x, y + lineHeight * i, width);
|
| 88 | }
|
| 89 |
|
| 90 | Canvas.prototype.drawLine = function(
|
| 91 | ctx, color, lineCap, lineWidth, startX, startY, endX, endY) {
|
| 92 | ctx.beginPath();
|
| 93 | ctx.moveTo(startX, startY);
|
| 94 | ctx.strokeStyle = color;
|
| 95 | ctx.lineWidth = lineWidth;
|
| 96 | ctx.lineCap = lineCap;
|
| 97 | ctx.lineTo(endX, endY);
|
| 98 | ctx.closePath();
|
| 99 | ctx.stroke();
|
| 100 | }
|
| 101 |
|
| 102 | Canvas.prototype.drawArrow = function(
|
| 103 | ctx, color, lineWidth, arrowWidth, arrowHeight, lineCap,
|
| 104 | startX, startY, endX, endY) {
|
| 105 | var arrowCoordinates = calculateArrowCoordinates(
|
| 106 | arrowWidth, arrowHeight,startX, startY, endX, endY);
|
| 107 | ctx.beginPath();
|
| 108 | ctx.strokeStyle = color;
|
| 109 | ctx.lineWidth = lineWidth;
|
| 110 | ctx.lineCap = lineCap;
|
| 111 | ctx.moveTo(startX, startY);
|
| 112 | ctx.lineTo(endX, endY);
|
| 113 | ctx.lineTo(arrowCoordinates.p1.x, arrowCoordinates.p1.y);
|
| 114 | ctx.moveTo(endX, endY);
|
| 115 | ctx.lineTo(arrowCoordinates.p2.x, arrowCoordinates.p2.y);
|
| 116 | ctx.closePath();
|
| 117 | ctx.stroke();
|
| 118 | }
|
| 119 |
|
| 120 | Canvas.prototype.drawRoundedRect = function(
|
| 121 | ctx, color, x, y, width, height, radius, type) {
|
| 122 | ctx.beginPath();
|
| 123 | ctx.moveTo(x, y + radius);
|
| 124 | ctx.lineTo(x, y + height - radius);
|
| 125 | ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
|
| 126 | ctx.lineTo(x + width - radius, y + height);
|
| 127 | ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
|
| 128 | ctx.lineTo(x + width, y + radius);
|
| 129 | ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
|
| 130 | ctx.lineTo(x + radius, y);
|
| 131 | ctx.quadraticCurveTo(x, y, x, y + radius);
|
| 132 | if (type == 'rect') {
|
| 133 | ctx.fillStyle = changeColorToRgba(color, 0.5);
|
| 134 | ctx.fill();
|
| 135 | } else if (type == 'border') {
|
| 136 | ctx.strokeStyle = color;
|
| 137 | ctx.lineWidth = 2;
|
| 138 | ctx.stroke();
|
| 139 | }
|
| 140 | ctx.closePath();
|
| 141 | }
|
| 142 |
|
| 143 | Canvas.prototype.blurImage = function(
|
| 144 | realCanvas, simulateCanvas, layerId, startX, startY, endX, endY) {
|
| 145 | var x = startX < endX ? startX : endX;
|
| 146 | var y = startY < endY ? startY : endY;
|
| 147 | var width = Math.abs(endX - startX - 1);
|
| 148 | var height = Math.abs(endY - startY - 1);
|
| 149 | simulateCanvas.width = $(layerId).clientWidth + 10;
|
| 150 | simulateCanvas.height = $(layerId).clientHeight + 10;
|
| 151 | var ctx = simulateCanvas.getContext('2d');
|
| 152 | try {
|
| 153 | ctx.drawImage(realCanvas, x, y, width, height, 0, 0, width, height);
|
| 154 | } catch (error) {
|
| 155 | console.log(error + ', width : height = ' + width + ' : ' + height);
|
| 156 | }
|
| 157 | var imageData = ctx.getImageData(0, 0, width, height);
|
| 158 | imageData = this.boxBlur(imageData, width, height, 10);
|
| 159 | ctx.putImageData(imageData, 0, 0);
|
| 160 | }
|
| 161 |
|
| 162 | Canvas.prototype.boxBlur = function(image, width, height, count) {
|
| 163 | var j;
|
| 164 | var pix = image.data;
|
| 165 | var inner = 0;
|
| 166 | var outer = 0;
|
| 167 | var step = 0;
|
| 168 | var rowOrColumn;
|
| 169 | var nextPosition;
|
| 170 | var nowPosition;
|
| 171 | for(rowOrColumn = 0; rowOrColumn < 2; rowOrColumn++) {
|
| 172 | if (rowOrColumn) {
|
| 173 | // column blurring
|
| 174 | outer = width;
|
| 175 | inner = height;
|
| 176 | step = width * 4;
|
| 177 | } else {
|
| 178 | // Row blurring
|
| 179 | outer = height;
|
| 180 | inner = width;
|
| 181 | step = 4;
|
| 182 | }
|
| 183 | for (var i = 0; i < outer; i++) {
|
| 184 | // Calculate for r g b a
|
| 185 | nextPosition = (rowOrColumn == 0 ? (i * width * 4) : (4 * i));
|
| 186 | for (var k = 0; k < 4; k++) {
|
| 187 | nowPosition = nextPosition + k;
|
| 188 | var pixSum = 0;
|
| 189 | for(var m = 0; m < count; m++) {
|
| 190 | pixSum += pix[nowPosition + step * m];
|
| 191 | }
|
| 192 | pix[nowPosition] = pix[nowPosition + step] =
|
| 193 | pix[nowPosition + step * 2] = Math.floor(pixSum/count);
|
| 194 | for (j = 3; j < inner-2; j++) {
|
| 195 | pixSum = Math.max(0, pixSum - pix[nowPosition + (j - 2) * step]
|
| 196 | + pix[nowPosition + (j + 2) * step]);
|
| 197 | pix[nowPosition + j * step] = Math.floor(pixSum/count);
|
| 198 | }
|
| 199 | pix[nowPosition + j * step] = pix[nowPosition + (j + 1) * step] =
|
| 200 | Math.floor(pixSum / count);
|
| 201 | }
|
| 202 | }
|
| 203 | }
|
| 204 | return image;
|
| 205 | }
|
| 206 |
|
| 207 | function changeColorToRgba(color, opacity) {
|
| 208 | var sColor = color.toLowerCase();
|
| 209 | var sColorChange = [];
|
| 210 | for (var i = 1; i < sColor.length; i += 2) {
|
| 211 | sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
|
| 212 | }
|
| 213 | return "rgba(" + sColorChange.join(",") + "," + opacity + ")";
|
| 214 | }
|
| 215 |
|
| 216 | // Calculate coordinates of arrow
|
| 217 | function calculateArrowCoordinates(
|
| 218 | arrowWidth, arrowHeight, startX, startY, endX, endY) {
|
| 219 | var p1 = function() {
|
| 220 | var x = startX - endX;
|
| 221 | var y = startY - endY;
|
| 222 | var hypotenuse = Math.sqrt(x * x + y * y);
|
| 223 | hypotenuse = (hypotenuse == 0 ? arrowHeight : hypotenuse);
|
| 224 | var dx = Math.round(x / hypotenuse * arrowHeight);
|
| 225 | var dy = Math.round(y / hypotenuse * arrowHeight);
|
| 226 | return {x: endX + dx, y: endY + dy};
|
| 227 | }
|
| 228 |
|
| 229 | var p2 = function(p1, direct) {
|
| 230 | var x = p1.x - startX;
|
| 231 | var y = p1.y - startY;
|
| 232 | var hypotenuse = Math.sqrt(x * x + y * y);
|
| 233 | hypotenuse = (hypotenuse == 0 ? arrowHeight : hypotenuse);
|
| 234 | var dx = Math.round((y / hypotenuse * arrowWidth) * direct);
|
| 235 | var dy = Math.round((x / hypotenuse * arrowWidth) * direct);
|
| 236 | return {x: p1.x + dx, y: p1.y - dy }
|
| 237 | }
|
| 238 |
|
| 239 | return {p1:p2(p1(), 1), p2: p2(p1(), -1) } ;
|
| 240 | }
|