avm99963 | 04def3e | 2016-11-27 22:53:05 +0100 | [diff] [blame] | 1 | // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this |
| 2 | // source code is governed by a BSD-style license that can be found in the |
| 3 | // LICENSE file. |
| 4 | |
| 5 | function isHighVersion() { |
| 6 | var version = navigator.userAgent.match(/Chrome\/(\d+)/)[1]; |
| 7 | return version > 9; |
| 8 | } |
| 9 | |
| 10 | function $(id) { |
| 11 | return document.getElementById(id); |
| 12 | } |
| 13 | function i18nReplace(id, messageKey) { |
| 14 | return $(id).innerHTML = chrome.i18n.getMessage(messageKey); |
| 15 | } |
avm99963 | 04def3e | 2016-11-27 22:53:05 +0100 | [diff] [blame] | 16 | |
| 17 | var bg = chrome.extension.getBackgroundPage(); |
| 18 | var canvas = new Canvas(); |
| 19 | var photoshop = { |
| 20 | canvas: document.createElement("canvas"), |
| 21 | tabTitle: '', |
| 22 | startX: 0, |
| 23 | startY: 0, |
| 24 | endX: 0, |
| 25 | endY: 0, |
| 26 | dragFlag: false, |
| 27 | flag: 'rectangle', |
| 28 | layerId: 'layer0', |
| 29 | canvasId: '', |
| 30 | color: '#ff0000', |
| 31 | highlightColor: '', |
| 32 | lastValidAction: 0, |
| 33 | markedArea: [], |
| 34 | isDraw: true, |
| 35 | offsetX: 0, |
| 36 | offsetY: 36, |
| 37 | nowHeight: 0, |
| 38 | nowWidth: 0, |
| 39 | highlightType: 'border', |
| 40 | highlightMode: 'rectangle', |
| 41 | text: '', |
| 42 | |
| 43 | i18nReplace: i18nReplace, |
| 44 | |
| 45 | initCanvas: function() { |
| 46 | $('canvas').width = $('mask-canvas').width = $('photo').style.width = |
| 47 | photoshop.canvas.width = bg.screenshot.canvas.width; |
| 48 | $('canvas').height = $('mask-canvas').height = $('photo').style.height = |
| 49 | photoshop.canvas.height = bg.screenshot.canvas.height; |
| 50 | var context = photoshop.canvas.getContext('2d'); |
| 51 | context.drawImage(bg.screenshot.canvas, 0, 0); |
| 52 | context = $('canvas').getContext('2d'); |
| 53 | context.drawImage(photoshop.canvas, 0, 0); |
| 54 | $('canvas').style.display = 'block'; |
| 55 | }, |
| 56 | |
| 57 | init: function() { |
| 58 | photoshop.initTools(); |
| 59 | photoshop.initCanvas(); |
| 60 | photoshop.tabTitle = bg.screenshot.tab.title; |
| 61 | var showBoxHeight = function() { |
| 62 | $('showBox').style.height = window.innerHeight - photoshop.offsetY - 1; |
| 63 | } |
| 64 | setTimeout(showBoxHeight, 50); |
| 65 | }, |
| 66 | |
| 67 | markCurrentElement: function(element) { |
| 68 | if (element && element.parentNode) { |
| 69 | var children = element.parentNode.children; |
| 70 | for (var i = 0; i < children.length; i++) { |
| 71 | var node = children[i]; |
| 72 | if (node == element) { |
| 73 | element.className = 'mark'; |
| 74 | } else { |
| 75 | node.className = ''; |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | }, |
| 80 | |
| 81 | setHighLightMode: function() { |
| 82 | photoshop.highlightType = localStorage.highlightType || 'border'; |
| 83 | photoshop.color = localStorage.highlightColor || '#FF0000'; |
| 84 | $(photoshop.layerId).style.border = '2px solid ' + photoshop.color; |
| 85 | if (photoshop.highlightType == 'rect') { |
| 86 | $(photoshop.layerId).style.backgroundColor = photoshop.color; |
| 87 | $(photoshop.layerId).style.opacity = 0.5; |
| 88 | } |
| 89 | if (photoshop.flag == 'rectangle') { |
| 90 | $(photoshop.layerId).style.borderRadius = '0 0'; |
| 91 | } else if (photoshop.flag == 'radiusRectangle') { |
| 92 | $(photoshop.layerId).style.borderRadius = '6px 6px'; |
| 93 | } else if (photoshop.flag == 'ellipse') { |
| 94 | $(photoshop.layerId).style.border = '0'; |
| 95 | $(photoshop.layerId).style.backgroundColor = ''; |
| 96 | $(photoshop.layerId).style.opacity = 1; |
| 97 | } |
| 98 | |
| 99 | }, |
| 100 | |
| 101 | setBlackoutMode: function() { |
| 102 | photoshop.color = '#000000'; |
| 103 | $(photoshop.layerId).style.opacity = 1; |
| 104 | $(photoshop.layerId).style.backgroundColor = '#000000'; |
| 105 | $(photoshop.layerId).style.border = '2px solid #000000'; |
| 106 | }, |
| 107 | |
| 108 | setTextMode: function() { |
| 109 | localStorage.fontSize = localStorage.fontSize || '16'; |
| 110 | photoshop.color = localStorage.fontColor = |
| 111 | localStorage.fontColor || '#FF0000'; |
| 112 | $(photoshop.layerId).setAttribute('contentEditable', true); |
| 113 | $(photoshop.layerId).style.border = '1px dotted #333333'; |
| 114 | $(photoshop.layerId).style.cursor = 'text'; |
| 115 | $(photoshop.layerId).style.lineHeight = localStorage.fontSize + 'px'; |
| 116 | $(photoshop.layerId).style.fontSize = localStorage.fontSize + 'px'; |
| 117 | $(photoshop.layerId).style.color = photoshop.color; |
| 118 | $(photoshop.layerId).innerHTML = '<br/>'; |
| 119 | var layer = $(photoshop.layerId); |
| 120 | var id = photoshop.layerId; |
| 121 | layer.addEventListener('blur', function() { |
| 122 | photoshop.setTextToArray(id); |
| 123 | }, true); |
| 124 | layer.addEventListener('click', function() { |
| 125 | this.style.border = '1px dotted #333333'; |
| 126 | }, true); |
| 127 | layer.addEventListener('mouseout', function() { |
| 128 | if (!photoshop.dragFlag) { |
| 129 | this.style.borderWidth = 0; |
| 130 | } |
| 131 | }, false); |
| 132 | layer.addEventListener('mousemove', function() { |
| 133 | this.style.border = '1px dotted #333333'; |
| 134 | }, false); |
| 135 | }, |
| 136 | |
| 137 | setTextToArray: function(id) { |
| 138 | var str = $(id).innerText.split("\n"); |
| 139 | if (photoshop.markedArea.length > 0) { |
| 140 | for (var i = photoshop.markedArea.length - 1; i >= 0; i--) { |
| 141 | if (photoshop.markedArea[i].id == id) { |
| 142 | photoshop.markedArea[i].context = str; |
| 143 | break; |
| 144 | } |
| 145 | } |
| 146 | $(id).style.borderWidth = 0; |
| 147 | } |
| 148 | }, |
| 149 | |
| 150 | openOptionPage: function() { |
| 151 | chrome.tabs.create({url: chrome.extension.getURL("options.html")}); |
| 152 | }, |
| 153 | |
| 154 | closeCurrentTab: function() { |
| 155 | chrome.tabs.getSelected(null, function(tab) { |
| 156 | chrome.tabs.remove(tab.id); |
| 157 | }); |
| 158 | }, |
| 159 | |
| 160 | finish: function() { |
| 161 | var context = $('canvas').getContext('2d'); |
| 162 | context.drawImage(photoshop.canvas, 0, 0); |
| 163 | }, |
| 164 | |
| 165 | colorRgba: function(color, opacity) { |
| 166 | var sColor = color.toLowerCase(); |
| 167 | var sColorChange = []; |
| 168 | for (var i = 1; i < sColor.length; i += 2) { |
| 169 | sColorChange.push(parseInt("0x" + sColor.slice(i,i + 2))); |
| 170 | } |
| 171 | return "rgba(" + sColorChange.join(",") + "," + opacity + ")"; |
| 172 | }, |
| 173 | |
| 174 | /** |
| 175 | * Undo the current operation |
| 176 | */ |
| 177 | toDo: function(element, what) { |
| 178 | photoshop.flag = what; |
| 179 | photoshop.isDraw = true; |
| 180 | photoshop.markCurrentElement(element); |
| 181 | }, |
| 182 | |
| 183 | setDivStyle: function(x, y) { |
| 184 | $(photoshop.layerId).setAttribute("style", ""); |
| 185 | $(photoshop.layerId).setAttribute("contentEditable", false); |
| 186 | switch(photoshop.flag) { |
| 187 | case 'rectangle': |
| 188 | case 'radiusRectangle': |
| 189 | case 'ellipse': |
| 190 | photoshop.setHighLightMode(); |
| 191 | break; |
| 192 | case 'redact': |
| 193 | photoshop.setBlackoutMode(); |
| 194 | break; |
| 195 | case 'text': |
| 196 | photoshop.setTextMode(); |
| 197 | break; |
| 198 | case 'line': |
| 199 | case 'arrow': |
| 200 | photoshop.drawLineOnMaskCanvas(x, y, x, y, 'lineStart', |
| 201 | photoshop.layerId); |
| 202 | break; |
| 203 | case 'blur': |
| 204 | photoshop.createCanvas(photoshop.layerId); |
| 205 | break; |
| 206 | } |
| 207 | }, |
| 208 | |
| 209 | /** |
| 210 | * Create a layer and set style |
| 211 | */ |
| 212 | createDiv: function() { |
| 213 | photoshop.lastValidAction++; |
| 214 | photoshop.layerId = 'layer' + photoshop.lastValidAction; |
| 215 | if ($(photoshop.layerId)) { |
| 216 | photoshop.removeElement(photoshop.layerId); |
| 217 | } |
| 218 | var divElement = document.createElement('div'); |
| 219 | divElement.id = photoshop.layerId; |
| 220 | divElement.className = 'layer'; |
| 221 | $('photo').appendChild(divElement); |
| 222 | if (photoshop.flag == 'blur') { |
| 223 | photoshop.createCanvas(photoshop.layerId); |
| 224 | } |
| 225 | return divElement; |
| 226 | }, |
| 227 | |
| 228 | createCanvas: function(parentId) { |
| 229 | photoshop.canvasId = 'cav-' + parentId; |
| 230 | if (!$(photoshop.canvasId)) { |
| 231 | var cav = document.createElement('canvas'); |
| 232 | cav.id = photoshop.canvasId; |
| 233 | cav.width = 10; |
| 234 | cav.height = 10; |
| 235 | $(photoshop.layerId).appendChild(cav); |
| 236 | return cav; |
| 237 | } |
| 238 | return $(photoshop.canvasId); |
| 239 | |
| 240 | }, |
| 241 | |
| 242 | createCloseButton: function(parent, id, left, top, flag) { |
| 243 | var imgElement = document.createElement('img'); |
| 244 | imgElement.id = id; |
| 245 | imgElement.src = 'images/cross.png'; |
| 246 | imgElement.className = 'closeButton'; |
| 247 | imgElement.style.left = left - 15 + 'px'; |
| 248 | if (photoshop.flag == 'line' || photoshop.flag == 'arrow') { |
| 249 | imgElement.style.left = left / 2 - 5 + 'px'; |
| 250 | imgElement.style.top = top / 2 - 5 + 'px'; |
| 251 | } |
| 252 | imgElement.onclick = function() { |
| 253 | $(parent).style.display = 'none'; |
| 254 | photoshop.removeLayer(parent); |
| 255 | }; |
| 256 | $(parent).onmousemove = function() { |
| 257 | if (!photoshop.dragFlag) { |
| 258 | photoshop.showCloseButton(id); |
| 259 | $(parent).style.zIndex = 110; |
| 260 | photoshop.isDraw = (flag == 'text' ? false : photoshop.isDraw); |
| 261 | } |
| 262 | }; |
| 263 | $(parent).onmouseout = function() { |
| 264 | photoshop.hideCloseButton(id); |
| 265 | $(parent).style.zIndex = 100; |
| 266 | photoshop.isDraw = true; |
| 267 | }; |
| 268 | $(parent).appendChild(imgElement); |
| 269 | return imgElement; |
| 270 | }, |
| 271 | |
| 272 | showCloseButton: function(id) { |
| 273 | $(id).style.display = 'block'; |
| 274 | }, |
| 275 | |
| 276 | hideCloseButton: function(id) { |
| 277 | $(id).style.display = 'none'; |
| 278 | photoshop.isDraw = true; |
| 279 | }, |
| 280 | |
| 281 | removeLayer: function(id) { |
| 282 | for (var i = 0; i < photoshop.markedArea.length; i++) { |
| 283 | if (photoshop.markedArea[i].id == id) { |
| 284 | photoshop.markedArea.splice(i, 1); |
| 285 | break; |
| 286 | } |
| 287 | } |
| 288 | photoshop.removeElement(id); |
| 289 | }, |
| 290 | |
| 291 | /** |
| 292 | * Set the starting point(x,y) when mouse pressed |
| 293 | */ |
| 294 | onMouseDown: function(event) { |
| 295 | if (photoshop.isDraw && event.button != 2) { |
| 296 | photoshop.startX = event.pageX + $('showBox').scrollLeft - |
| 297 | photoshop.offsetX; |
| 298 | photoshop.startY = event.pageY + $('showBox').scrollTop - |
| 299 | photoshop.offsetY; |
| 300 | photoshop.setDivStyle(photoshop.startX, photoshop.startY); |
| 301 | photoshop.dragFlag = true; |
| 302 | |
| 303 | $(photoshop.layerId).style.left = photoshop.startX + 'px'; |
| 304 | $(photoshop.layerId).style.top = photoshop.startY + 'px'; |
| 305 | $(photoshop.layerId).style.height = 0; |
| 306 | $(photoshop.layerId).style.width = 0; |
| 307 | $(photoshop.layerId).style.display = 'block'; |
| 308 | } |
| 309 | }, |
| 310 | |
| 311 | onMouseUp: function(event) { |
| 312 | $('mask-canvas').style.zIndex = 10; |
| 313 | photoshop.endX = event.pageX + $('showBox').scrollLeft - |
| 314 | photoshop.offsetX; |
| 315 | if (photoshop.endX > photoshop.canvas.width) { |
| 316 | photoshop.endX = photoshop.canvas.width ; |
| 317 | } |
| 318 | |
| 319 | if (photoshop.endX < 0) { |
| 320 | photoshop.endX = 0; |
| 321 | } |
| 322 | |
| 323 | photoshop.endY = event.pageY + $('showBox').scrollTop - |
| 324 | photoshop.offsetY; |
| 325 | if (photoshop.endY > photoshop.canvas.height) { |
| 326 | photoshop.endY = photoshop.canvas.height ; |
| 327 | } |
| 328 | if (photoshop.endY < 0) { |
| 329 | photoshop.endY = 0; |
| 330 | } |
| 331 | if (photoshop.isDraw && photoshop.dragFlag && (photoshop.endX != |
| 332 | photoshop.startX || photoshop.endY != photoshop.startY)) { |
| 333 | if (photoshop.flag == 'line' || photoshop.flag == 'arrow') { |
| 334 | photoshop.drawLineOnMaskCanvas(photoshop.startX, photoshop.startY, |
| 335 | photoshop.endX, photoshop.endY, 'drawEnd', photoshop.layerId); |
| 336 | } else if (photoshop.flag == 'blur') { |
| 337 | canvas.blurImage(photoshop.canvas, $(photoshop.canvasId), |
| 338 | photoshop.layerId, photoshop.startX, photoshop.startY, |
| 339 | photoshop.endX, photoshop.endY); |
| 340 | } else if (photoshop.flag == 'ellipse') { |
| 341 | photoshop.drawEllipseOnMaskCanvas(photoshop.endX, |
| 342 | photoshop.endY, 'end', photoshop.layerId); |
| 343 | } |
| 344 | photoshop.markedArea.push({ |
| 345 | 'id': photoshop.layerId, |
| 346 | 'startX': photoshop.startX, |
| 347 | 'startY': photoshop.startY, |
| 348 | 'endX': photoshop.endX, |
| 349 | 'endY': photoshop.endY, |
| 350 | 'width': photoshop.nowWidth, |
| 351 | 'height': photoshop.nowHeight, |
| 352 | 'flag': photoshop.flag, |
| 353 | 'highlightType': photoshop.highlightType, |
| 354 | 'fontSize': localStorage.fontSize, |
| 355 | 'color': photoshop.color, |
| 356 | 'context': '' |
| 357 | }); |
| 358 | $(photoshop.layerId).focus(); |
| 359 | var imageBtnId = 'close_' + photoshop.layerId; |
| 360 | photoshop.createCloseButton(photoshop.layerId, imageBtnId, |
| 361 | photoshop.nowWidth, photoshop.nowHeight, photoshop.flag); |
| 362 | photoshop.createDiv(); |
| 363 | } else if (photoshop.endX == |
| 364 | photoshop.startX && photoshop.endY == photoshop.startY) { |
| 365 | photoshop.removeElement(photoshop.layerId); |
| 366 | photoshop.createDiv(); |
| 367 | } |
| 368 | photoshop.dragFlag = false; |
| 369 | |
| 370 | }, |
| 371 | |
| 372 | /** |
| 373 | * Refresh div‘s height and width when the mouse move |
| 374 | */ |
| 375 | onMouseMove: function(event) { |
| 376 | if(photoshop.dragFlag) { |
| 377 | $('mask-canvas').style.zIndex = 200; |
| 378 | photoshop.endX = event.pageX + $('showBox').scrollLeft - |
| 379 | photoshop.offsetX; |
| 380 | if (photoshop.endX > photoshop.canvas.width) { |
| 381 | photoshop.endX = photoshop.canvas.width ; |
| 382 | } |
| 383 | |
| 384 | if (photoshop.endX < 0) { |
| 385 | photoshop.endX = 0; |
| 386 | } |
| 387 | |
| 388 | photoshop.endY = event.pageY + $('showBox').scrollTop - |
| 389 | photoshop.offsetY; |
| 390 | if (photoshop.endY > photoshop.canvas.height) { |
| 391 | photoshop.endY = photoshop.canvas.height ; |
| 392 | } |
| 393 | if (photoshop.endY < 0) { |
| 394 | photoshop.endY = 0; |
| 395 | } |
| 396 | photoshop.nowHeight = photoshop.endY - photoshop.startY - 1 ; |
| 397 | photoshop.nowWidth = photoshop.endX - photoshop.startX - 1 ; |
| 398 | |
| 399 | if(photoshop.nowHeight < 0) { |
| 400 | $(photoshop.layerId).style.top = photoshop.endY + 'px'; |
| 401 | photoshop.nowHeight = -1 * photoshop.nowHeight; |
| 402 | } |
| 403 | if(photoshop.nowWidth < 0) { |
| 404 | $(photoshop.layerId).style.left = photoshop.endX + 'px'; |
| 405 | photoshop.nowWidth = -1 * photoshop.nowWidth; |
| 406 | } |
| 407 | |
| 408 | $(photoshop.layerId).style.height = photoshop.nowHeight - 3; |
| 409 | $(photoshop.layerId).style.width = photoshop.nowWidth - 3; |
| 410 | if (photoshop.flag == 'line' || photoshop.flag == 'arrow') { |
| 411 | photoshop.drawLineOnMaskCanvas(photoshop.startX, photoshop.startY, |
| 412 | photoshop.endX, photoshop.endY, 'lineDrawing', photoshop.layerId); |
| 413 | } else if (photoshop.flag == 'blur') { |
| 414 | $(photoshop.layerId).style.height = photoshop.nowHeight ; |
| 415 | $(photoshop.layerId).style.width = photoshop.nowWidth ; |
| 416 | canvas.blurImage(photoshop.canvas, $(photoshop.canvasId), |
| 417 | photoshop.layerId, photoshop.startX, photoshop.startY, |
| 418 | photoshop.endX, photoshop.endY); |
| 419 | } else if (photoshop.flag == 'ellipse') { |
| 420 | photoshop.drawEllipseOnMaskCanvas(photoshop.endX, |
| 421 | photoshop.endY, 'drawing', photoshop.layerId); |
| 422 | } |
| 423 | } |
| 424 | |
| 425 | }, |
| 426 | |
| 427 | /** |
| 428 | * Remove a div |
| 429 | */ |
| 430 | removeElement: function(id) { |
| 431 | if($(id)) { |
| 432 | $(id).parentNode.removeChild($(id)); |
| 433 | } |
| 434 | }, |
| 435 | |
| 436 | /** |
| 437 | * Use fillStyle, fillText and fillRect functions to draw rectangles, |
| 438 | * and render to canvas |
| 439 | */ |
| 440 | draw: function() { |
| 441 | var context = $('canvas').getContext('2d'); |
| 442 | for (var j = 0; j < photoshop.markedArea.length; j++) { |
| 443 | var mark = photoshop.markedArea[j]; |
| 444 | var x = (mark.startX < mark.endX) ? mark.startX : mark.endX; |
| 445 | var y = (mark.startY < mark.endY) ? mark.startY : mark.endY; |
| 446 | var width = mark.width; |
| 447 | var height = mark.height; |
| 448 | var color = mark.color; |
| 449 | switch(mark.flag) { |
| 450 | case 'rectangle': |
| 451 | if (mark.highlightType == 'border') { |
| 452 | canvas.drawStrokeRect(context, color, x, y, width, height, 2); |
| 453 | } else { |
| 454 | var color = changeColorToRgba(color, 0.5); |
| 455 | canvas.drawFillRect(context, color, x, y, width, height); |
| 456 | } |
| 457 | break; |
| 458 | case 'radiusRectangle': |
| 459 | canvas.drawRoundedRect( |
| 460 | context, color, x, y, width, height, 6, mark.highlightType); |
| 461 | break; |
| 462 | case 'ellipse': |
| 463 | x = (mark.startX + mark.endX) / 2; |
| 464 | y = (mark.startY + mark.endY) / 2; |
| 465 | var xAxis = Math.abs(mark.endX - mark.startX) / 2; |
| 466 | var yAxis = Math.abs(mark.endY - mark.startY) / 2; |
| 467 | canvas.drawEllipse( |
| 468 | context, color, x, y, xAxis, yAxis, 3, mark.highlightType); |
| 469 | break; |
| 470 | case 'redact': |
| 471 | canvas.drawFillRect(context, color, x, y, width, height); |
| 472 | break; |
| 473 | case 'text': |
| 474 | for (var i = 0; i < mark.context.length; i++) { |
| 475 | canvas.setText( |
| 476 | context, mark.context[i], color, mark.fontSize, 'arial', |
| 477 | mark.fontSize, x, y + mark.fontSize * i, width); |
| 478 | } |
| 479 | break; |
| 480 | case 'blur': |
| 481 | var imageData = context.getImageData( |
| 482 | x, y, photoshop.markedArea[j].width, |
| 483 | photoshop.markedArea[j].height); |
| 484 | imageData = canvas.boxBlur( |
| 485 | imageData, photoshop.markedArea[j].width, |
| 486 | photoshop.markedArea[j].height, 10); |
| 487 | context.putImageData( |
| 488 | imageData, x, y, 0, 0, photoshop.markedArea[j].width, |
| 489 | photoshop.markedArea[j].height); |
| 490 | break; |
| 491 | case 'line': |
| 492 | canvas.drawLine( |
| 493 | context, color, 'round', 2, |
| 494 | mark.startX, mark.startY, mark.endX, mark.endY); |
| 495 | break; |
| 496 | case 'arrow': |
| 497 | canvas.drawArrow( |
| 498 | context, color, 2, 4, 10, 'round', |
| 499 | mark.startX, mark.startY, mark.endX, mark.endY); |
| 500 | break; |
| 501 | } |
| 502 | } |
| 503 | }, |
| 504 | |
avm99963 | 873bf6f | 2021-02-07 00:01:31 +0100 | [diff] [blame] | 505 | save: function() { |
| 506 | photoshop.draw(); |
avm99963 | 8044b40 | 2021-02-07 14:24:12 +0100 | [diff] [blame] | 507 | chrome.storage.local.get('screenshotQuality', options => { |
| 508 | var formatParam = options['screenshotQuality'] || 'png'; |
avm99963 | 476a2a6 | 2021-02-07 00:40:02 +0100 | [diff] [blame] | 509 | var dataUrl; |
| 510 | var isJpeg = formatParam == 'jpeg'; |
| 511 | $('canvas').toBlob(function(blob) { |
avm99963 | 8044b40 | 2021-02-07 14:24:12 +0100 | [diff] [blame] | 512 | saveAs(blob, chrome.extension.getBackgroundPage().screenshot.screenshotName + (isJpeg ? ".jpeg" : ".png")); |
avm99963 | 476a2a6 | 2021-02-07 00:40:02 +0100 | [diff] [blame] | 513 | }, 'image/' + (isJpeg ? 'jpeg' : 'png'), (isJpeg ? 0.5 : null)); |
| 514 | photoshop.finish(); |
| 515 | }); |
avm99963 | 873bf6f | 2021-02-07 00:01:31 +0100 | [diff] [blame] | 516 | }, |
| 517 | |
avm99963 | 04def3e | 2016-11-27 22:53:05 +0100 | [diff] [blame] | 518 | drawLineOnMaskCanvas: function(startX, startY, endX, endY, type, layerId) { |
| 519 | var ctx = $('mask-canvas').getContext('2d'); |
| 520 | ctx.clearRect(0, 0, $('mask-canvas').width, $('mask-canvas').height); |
| 521 | if (type == 'drawEnd') { |
| 522 | var offset = 20; |
| 523 | var width = Math.abs(endX - photoshop.startX) > 0 ? |
| 524 | Math.abs(endX - photoshop.startX): 0; |
| 525 | var height = Math.abs(endY - photoshop.startY) > 0 ? |
| 526 | Math.abs(endY - photoshop.startY): 0; |
| 527 | var offsetLeft = parseInt($(layerId).style.left); |
| 528 | var offsetTop = parseInt($(layerId).style.top); |
| 529 | startX = startX - offsetLeft + offset / 2; |
| 530 | startY = startY - offsetTop + offset / 2; |
| 531 | endX = endX - offsetLeft + offset / 2; |
| 532 | endY = endY - offsetTop + offset / 2; |
| 533 | $(layerId).style.left = offsetLeft - offset / 2; |
| 534 | $(layerId).style.top = offsetTop - offset / 2; |
| 535 | var cavCopy = photoshop.createCanvas(layerId); |
| 536 | cavCopy.width = width + offset; |
| 537 | cavCopy.height = height + offset; |
| 538 | ctx = cavCopy.getContext('2d'); |
| 539 | } |
| 540 | if (localStorage.lineType == 'line') { |
| 541 | canvas.drawLine(ctx, localStorage.lineColor, 'round', 2, |
| 542 | startX, startY, endX, endY); |
| 543 | } else { |
| 544 | canvas.drawArrow(ctx, localStorage.lineColor, 2, 4, 10, 'round', |
| 545 | startX, startY, endX, endY) |
| 546 | } |
| 547 | |
| 548 | }, |
| 549 | |
| 550 | createColorPadStr: function(element, type) { |
| 551 | var colorList = ['#000000', '#0036ff', '#008000', '#dacb23', '#d56400', |
| 552 | '#c70000', '#be00b3', '#1e2188', '#0090ff', '#22cc01', '#ffff00', |
| 553 | '#ff9600', '#ff0000', '#ff008e', '#7072c3', '#49d2ff', '#9dff3d', |
| 554 | '#ffffff', '#ffbb59', '#ff6b6b', '#ff6bbd']; |
| 555 | |
| 556 | var div = document.createElement("div"); |
| 557 | div.id = "colorpad"; |
| 558 | element.appendChild(div); |
| 559 | |
| 560 | for(var i = 0; i < colorList.length; i++) { |
| 561 | var a = document.createElement("a"); |
| 562 | var color = colorList[i]; |
| 563 | a.id = color; |
| 564 | a.title = color; |
| 565 | a.style.backgroundColor = color; |
| 566 | if (color == '#ffffff') { |
| 567 | a.style.border = "1px solid #444"; |
| 568 | a.style.width = "12px" |
| 569 | a.style.height = "12px"; |
| 570 | } |
| 571 | a.addEventListener('click', function(e) { |
| 572 | photoshop.colorPadPick(e.target.id, type); |
| 573 | return false; |
| 574 | }); |
| 575 | div.appendChild(a); |
| 576 | } |
| 577 | }, |
| 578 | |
| 579 | colorPadPick: function(color, type) { |
| 580 | photoshop.color = color; |
| 581 | if(type == 'highlight') { |
| 582 | localStorage.highlightColor = color; |
| 583 | photoshop.setHighlightColorBoxStyle(color); |
| 584 | } else if(type == 'text') { |
| 585 | localStorage.fontColor = color; |
| 586 | $('fontColorBox').style.backgroundColor = color; |
| 587 | } else if (type == 'line') { |
| 588 | localStorage.lineColor = color; |
| 589 | photoshop.setLineColorBoxStyle(); |
| 590 | } else if (type == 'ellipse') { |
| 591 | $('ellipseBox').style.borderColor = color; |
| 592 | } |
| 593 | }, |
| 594 | |
| 595 | setHighlightColorBoxStyle: function(color) { |
| 596 | var highlightColorBox = $('highlightColorBox'); |
| 597 | highlightColorBox.style.borderColor = color; |
| 598 | localStorage.highlightType = localStorage.highlightType || 'border'; |
| 599 | if (localStorage.highlightType == 'border') { |
| 600 | highlightColorBox.style.background = '#ffffff'; |
| 601 | highlightColorBox.style.opacity = 1; |
| 602 | $('borderMode').className = 'mark'; |
| 603 | $('rectMode').className = ''; |
| 604 | } else if (localStorage.highlightType == 'rect') { |
| 605 | highlightColorBox.style.background = color; |
| 606 | highlightColorBox.style.opacity = 0.5; |
| 607 | $('borderMode').className = ''; |
| 608 | $('rectMode').className = 'mark'; |
| 609 | } |
| 610 | if (photoshop.flag == 'rectangle') { |
| 611 | highlightColorBox.style.borderRadius = '0 0'; |
| 612 | } else if (photoshop.flag == 'radiusRectangle') { |
| 613 | highlightColorBox.style.borderRadius = '3px 3px'; |
| 614 | } else if (photoshop.flag == 'ellipse') { |
| 615 | highlightColorBox.style.borderRadius = '12px 12px'; |
| 616 | } |
| 617 | photoshop.markCurrentElement($(photoshop.flag)); |
| 618 | }, |
| 619 | |
| 620 | setBlackoutColorBoxStyle: function() { |
| 621 | localStorage.blackoutType = localStorage.blackoutType || 'redact'; |
| 622 | if (localStorage.blackoutType == 'redact') { |
| 623 | $('blackoutBox').className = 'rectBox'; |
| 624 | $('redact').className = 'mark'; |
| 625 | $('blur').className = ''; |
| 626 | } else if (localStorage.blackoutType == 'blur') { |
| 627 | $('blackoutBox').className = 'blurBox'; |
| 628 | $('redact').className = ''; |
| 629 | $('blur').className = 'mark'; |
| 630 | } |
| 631 | }, |
| 632 | |
| 633 | setFontSize: function(size) { |
| 634 | var id = 'size_' + size; |
| 635 | localStorage.fontSize = size; |
| 636 | $('size_10').className = ''; |
| 637 | $('size_16').className = ''; |
| 638 | $('size_18').className = ''; |
| 639 | $('size_32').className = ''; |
| 640 | $(id).className = 'mark'; |
| 641 | }, |
| 642 | |
| 643 | setLineColorBoxStyle: function() { |
| 644 | localStorage.lineType = localStorage.lineType || 'line'; |
| 645 | photoshop.color = localStorage.lineColor = |
| 646 | localStorage.lineColor || '#FF0000'; |
| 647 | var ctx = $('lineIconCav').getContext('2d'); |
| 648 | ctx.clearRect(0, 0, 14, 14); |
| 649 | if (localStorage.lineType == 'line') { |
| 650 | $('straightLine').className = 'mark'; |
| 651 | $('arrow').className = ''; |
| 652 | canvas.drawLine(ctx, photoshop.color, 'round', 2, 1, 13, 13, 1); |
| 653 | } else if (localStorage.lineType == 'arrow') { |
| 654 | $('straightLine').className = ''; |
| 655 | $('arrow').className = 'mark'; |
| 656 | canvas.drawArrow(ctx, photoshop.color, 2, 4, 7, 'round',1, 13, 13, 1); |
| 657 | } |
| 658 | |
| 659 | }, |
| 660 | |
| 661 | initTools: function() { |
| 662 | photoshop.i18nReplace('tHighlight', 'highlight'); |
| 663 | photoshop.i18nReplace('tRedact', 'redact'); |
| 664 | photoshop.i18nReplace('redactText', 'solid_black'); |
| 665 | photoshop.i18nReplace('tText', 'text'); |
| 666 | photoshop.i18nReplace('tSave', 'save'); |
| 667 | photoshop.i18nReplace('tClose', 'close'); |
| 668 | photoshop.i18nReplace('border', 'border'); |
| 669 | photoshop.i18nReplace('rect', 'rect'); |
| 670 | photoshop.i18nReplace('blurText', 'blur'); |
| 671 | photoshop.i18nReplace('lineText', 'line'); |
| 672 | photoshop.i18nReplace('size_10', 'size_small'); |
| 673 | photoshop.i18nReplace('size_16', 'size_normal'); |
| 674 | photoshop.i18nReplace('size_18', 'size_large'); |
| 675 | photoshop.i18nReplace('size_32', 'size_huge'); |
| 676 | var fontSize = localStorage.fontSize = localStorage.fontSize || 16; |
| 677 | if (fontSize != 10 && fontSize != 16 && fontSize != 18 && fontSize != 32) { |
| 678 | localStorage.fontSize = 16; |
| 679 | } |
| 680 | localStorage.highlightMode = photoshop.flag = |
| 681 | localStorage.highlightMode || 'rectangle'; |
| 682 | localStorage.highlightColor = localStorage.highlightColor || '#FF0000'; |
| 683 | localStorage.fontColor = localStorage.fontColor || '#FF0000'; |
| 684 | localStorage.highlightType = photoshop.highlightType = |
| 685 | localStorage.highlightType || 'border'; |
| 686 | localStorage.blackoutType = localStorage.blackoutType || 'redact'; |
| 687 | localStorage.lineType = localStorage.lineType || 'line'; |
| 688 | localStorage.lineColor = localStorage.lineColor || '#FF0000'; |
| 689 | photoshop.setHighlightColorBoxStyle(localStorage.highlightColor); |
| 690 | $('fontColorBox').style.backgroundColor = |
| 691 | localStorage.fontColor || '#FF0000'; |
| 692 | $('btnHighlight').addEventListener('click', function() { |
| 693 | photoshop.toDo(this, localStorage.highlightMode); |
| 694 | photoshop.setHighlightColorBoxStyle(localStorage.highlightColor); |
| 695 | }, false); |
| 696 | |
| 697 | $('btnBlackout').addEventListener('click', function() { |
| 698 | photoshop.toDo(this, localStorage.blackoutType); |
| 699 | photoshop.setBlackoutColorBoxStyle(); |
| 700 | }, false); |
| 701 | |
| 702 | $('btnText').addEventListener('click', function() { |
| 703 | photoshop.toDo(this, 'text'); |
| 704 | }, false); |
| 705 | |
| 706 | $('btnLine').addEventListener('click', function() { |
| 707 | photoshop.toDo(this, localStorage.lineType); |
| 708 | photoshop.setLineColorBoxStyle(); |
| 709 | }, false); |
| 710 | |
| 711 | |
| 712 | |
| 713 | photoshop.setHighlightColorBoxStyle(localStorage.highlightColor); |
| 714 | $('borderMode').addEventListener('click', function() { |
| 715 | localStorage.highlightType = 'border'; |
| 716 | }, false); |
| 717 | $('rectMode').addEventListener('click', function() { |
| 718 | localStorage.highlightType = 'rect'; |
| 719 | }, false); |
| 720 | $('rectangle').addEventListener('click', function() { |
| 721 | localStorage.highlightMode = photoshop.flag = 'rectangle'; |
| 722 | photoshop.markCurrentElement(this); |
| 723 | }, false); |
| 724 | $('radiusRectangle').addEventListener('click', function() { |
| 725 | localStorage.highlightMode = photoshop.flag = 'radiusRectangle'; |
| 726 | photoshop.markCurrentElement(this); |
| 727 | }, false); |
| 728 | $('ellipse').addEventListener('click', function() { |
| 729 | localStorage.highlightMode = photoshop.flag = 'ellipse'; |
| 730 | photoshop.markCurrentElement(this); |
| 731 | }, false); |
| 732 | photoshop.setBlackoutColorBoxStyle(); |
| 733 | $('redact').addEventListener('click', function() { |
| 734 | localStorage.blackoutType = 'redact'; |
| 735 | }, false); |
| 736 | $('blur').addEventListener('click', function() { |
| 737 | localStorage.blackoutType = 'blur'; |
| 738 | }, false); |
| 739 | |
| 740 | photoshop.setLineColorBoxStyle(); |
| 741 | |
| 742 | photoshop.createColorPadStr($('highlightColorPad'), 'highlight'); |
| 743 | photoshop.createColorPadStr($('fontColorPad'), 'text'); |
| 744 | photoshop.createColorPadStr($('lineColorPad'), 'line'); |
| 745 | |
| 746 | $('straightLine').addEventListener('click', function() { |
| 747 | localStorage.lineType = 'line'; |
| 748 | photoshop.setLineColorBoxStyle(); |
| 749 | }, false); |
| 750 | $('arrow').addEventListener('click', function() { |
| 751 | localStorage.lineType = 'arrow'; |
| 752 | photoshop.setLineColorBoxStyle(); |
| 753 | }, false); |
| 754 | |
| 755 | photoshop.setFontSize(localStorage.fontSize); |
| 756 | $('size_10').addEventListener('click', function() { |
| 757 | photoshop.setFontSize(10); |
| 758 | }, false); |
| 759 | $('size_16').addEventListener('click', function() { |
| 760 | photoshop.setFontSize(16); |
| 761 | }, false); |
| 762 | $('size_18').addEventListener('click', function() { |
| 763 | photoshop.setFontSize(18); |
| 764 | }, false); |
| 765 | $('size_32').addEventListener('click', function() { |
| 766 | photoshop.setFontSize(32); |
| 767 | }, false); |
| 768 | }, |
| 769 | |
| 770 | drawEllipseOnMaskCanvas: function(endX, endY, type, layerId) { |
| 771 | var ctx = $('mask-canvas').getContext('2d'); |
| 772 | ctx.clearRect(0, 0, $('mask-canvas').width, $('mask-canvas').height); |
| 773 | var x = (photoshop.startX + endX) / 2; |
| 774 | var y = (photoshop.startY + endY) / 2; |
| 775 | var xAxis = Math.abs(endX - photoshop.startX) / 2; |
| 776 | var yAxis = Math.abs(endY - photoshop.startY) / 2; |
| 777 | canvas.drawEllipse(ctx, photoshop.color, x, y, xAxis, yAxis, 3, |
| 778 | photoshop.highlightType); |
| 779 | if (type == 'end') { |
| 780 | var offsetLeft = parseInt($(layerId).style.left); |
| 781 | var offsetTop = parseInt($(layerId).style.top); |
| 782 | var startX = photoshop.startX - offsetLeft ; |
| 783 | var startY = photoshop.startY - offsetTop ; |
| 784 | var newEndX = photoshop.endX - offsetLeft ; |
| 785 | var newEndY = photoshop.endY - offsetTop ; |
| 786 | x = (startX + newEndX) / 2; |
| 787 | y = (startY + newEndY) / 2; |
| 788 | xAxis = Math.abs(newEndX - startX) / 2; |
| 789 | yAxis = Math.abs(newEndY - startY) / 2; |
| 790 | var cavCopy = photoshop.createCanvas(layerId); |
| 791 | cavCopy.width = Math.abs(endX - photoshop.startX); |
| 792 | cavCopy.height = Math.abs(endY - photoshop.startY); |
| 793 | var ctxCopy = cavCopy.getContext('2d'); |
| 794 | canvas.drawEllipse(ctxCopy, photoshop.color, x, y, |
| 795 | xAxis, yAxis, 3, photoshop.highlightType); |
| 796 | ctx.clearRect(0, 0, $('mask-canvas').width, $('mask-canvas').height); |
| 797 | } |
| 798 | }, |
| 799 | |
| 800 | showTip: function(className, message, delay) { |
| 801 | delay = delay || 2000; |
| 802 | var div = document.createElement('div'); |
| 803 | div.className = className; |
| 804 | div.innerHTML = message; |
| 805 | document.body.appendChild(div); |
| 806 | div.style.left = (document.body.clientWidth - div.clientWidth) / 2 + 'px'; |
| 807 | window.setTimeout(function() { |
| 808 | document.body.removeChild(div); |
| 809 | }, delay); |
| 810 | } |
| 811 | }; |
| 812 | |
| 813 | photoshop.init(); |
| 814 | $('photo').addEventListener('mousemove', photoshop.onMouseMove, true); |
| 815 | $('photo').addEventListener('mousedown', photoshop.onMouseDown, true); |
| 816 | $('photo').addEventListener('mouseup', photoshop.onMouseUp, true); |
| 817 | document.addEventListener('mouseup', photoshop.onMouseUp, true); |
| 818 | document.addEventListener('mousemove', photoshop.onMouseMove, true); |
| 819 | |
| 820 | $('canvas').addEventListener( |
| 821 | 'selectstart', function f(e) { return false }); |
| 822 | $('mask-canvas').addEventListener( |
| 823 | 'selectstart', function f(e) { return false }); |
avm99963 | 873bf6f | 2021-02-07 00:01:31 +0100 | [diff] [blame] | 824 | $('btnSave').addEventListener('click', photoshop.save); |
avm99963 | 04def3e | 2016-11-27 22:53:05 +0100 | [diff] [blame] | 825 | $('btnClose').addEventListener('click', photoshop.closeCurrentTab); |