basic.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  1. /**
  2. * basic.js
  3. * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com>
  4. * @fileoverview
  5. */
  6. 'use strict';
  7. var supportingFileAPI = !!(window.File && window.FileList && window.FileReader);
  8. var rImageType = /data:(image\/.+);base64,/;
  9. var shapeOptions = {};
  10. var shapeType;
  11. var activeObjectId;
  12. // Buttons
  13. var $btns = $('.menu-item');
  14. var $btnsActivatable = $btns.filter('.activatable');
  15. var $inputImage = $('#input-image-file');
  16. var $btnDownload = $('#btn-download');
  17. var $btnUndo = $('#btn-undo');
  18. var $btnRedo = $('#btn-redo');
  19. var $btnClearObjects = $('#btn-clear-objects');
  20. var $btnRemoveActiveObject = $('#btn-remove-active-object');
  21. var $btnCrop = $('#btn-crop');
  22. var $btnFlip = $('#btn-flip');
  23. var $btnRotation = $('#btn-rotation');
  24. var $btnDrawLine = $('#btn-draw-line');
  25. var $btnDrawShape = $('#btn-draw-shape');
  26. var $btnApplyCrop = $('#btn-apply-crop');
  27. var $btnCancelCrop = $('#btn-cancel-crop');
  28. var $btnFlipX = $('#btn-flip-x');
  29. var $btnFlipY = $('#btn-flip-y');
  30. var $btnResetFlip = $('#btn-reset-flip');
  31. var $btnRotateClockwise = $('#btn-rotate-clockwise');
  32. var $btnRotateCounterClockWise = $('#btn-rotate-counter-clockwise');
  33. var $btnText = $('#btn-text');
  34. var $btnTextStyle = $('.btn-text-style');
  35. var $btnAddIcon = $('#btn-add-icon');
  36. var $btnRegisterIcon = $('#btn-register-icon');
  37. var $btnMaskFilter = $('#btn-mask-filter');
  38. var $btnImageFilter = $('#btn-image-filter');
  39. var $btnLoadMaskImage = $('#input-mask-image-file');
  40. var $btnApplyMask = $('#btn-apply-mask');
  41. var $btnClose = $('.close');
  42. // Input etc.
  43. var $inputRotationRange = $('#input-rotation-range');
  44. var $inputBrushWidthRange = $('#input-brush-width-range');
  45. var $inputFontSizeRange = $('#input-font-size-range');
  46. var $inputStrokeWidthRange = $('#input-stroke-width-range');
  47. var $inputCheckTransparent = $('#input-check-transparent');
  48. var $inputCheckGrayscale = $('#input-check-grayscale');
  49. var $inputCheckInvert = $('#input-check-invert');
  50. var $inputCheckSepia = $('#input-check-sepia');
  51. var $inputCheckSepia2 = $('#input-check-sepia2');
  52. var $inputCheckBlur = $('#input-check-blur');
  53. var $inputCheckSharpen = $('#input-check-sharpen');
  54. var $inputCheckEmboss = $('#input-check-emboss');
  55. var $inputCheckRemoveWhite = $('#input-check-remove-white');
  56. var $inputRangeRemoveWhiteThreshold = $('#input-range-remove-white-threshold');
  57. var $inputRangeRemoveWhiteDistance = $('#input-range-remove-white-distance');
  58. var $inputCheckBrightness = $('#input-check-brightness');
  59. var $inputRangeBrightnessValue = $('#input-range-brightness-value');
  60. var $inputCheckNoise = $('#input-check-noise');
  61. var $inputRangeNoiseValue = $('#input-range-noise-value');
  62. var $inputCheckGradientTransparency = $('#input-check-gradient-transparancy');
  63. var $inputRangeGradientTransparencyValue = $('#input-range-gradient-transparency-value');
  64. var $inputCheckPixelate = $('#input-check-pixelate');
  65. var $inputRangePixelateValue = $('#input-range-pixelate-value');
  66. var $inputCheckTint = $('#input-check-tint');
  67. var $inputRangeTintOpacityValue = $('#input-range-tint-opacity-value');
  68. var $inputCheckMultiply = $('#input-check-multiply');
  69. var $inputCheckBlend = $('#input-check-blend');
  70. var $inputCheckColorFilter = $('#input-check-color-filter');
  71. var $inputRangeColorFilterValue = $('#input-range-color-filter-value');
  72. // Sub menus
  73. var $displayingSubMenu = $();
  74. var $cropSubMenu = $('#crop-sub-menu');
  75. var $flipSubMenu = $('#flip-sub-menu');
  76. var $rotationSubMenu = $('#rotation-sub-menu');
  77. var $freeDrawingSubMenu = $('#free-drawing-sub-menu');
  78. var $drawLineSubMenu = $('#draw-line-sub-menu');
  79. var $drawShapeSubMenu = $('#draw-shape-sub-menu');
  80. var $textSubMenu = $('#text-sub-menu');
  81. var $iconSubMenu = $('#icon-sub-menu');
  82. var $filterSubMenu = $('#filter-sub-menu');
  83. var $imageFilterSubMenu = $('#image-filter-sub-menu');
  84. // Select line type
  85. var $selectLine = $('[name="select-line-type"]');
  86. // Select shape type
  87. var $selectShapeType = $('[name="select-shape-type"]');
  88. // Select color of shape type
  89. var $selectColorType = $('[name="select-color-type"]');
  90. //Select blend type
  91. var $selectBlendType = $('[name="select-blend-type"]');
  92. // Image editor
  93. var imageEditor = new tui.ImageEditor('.tui-image-editor', {
  94. cssMaxWidth: 700,
  95. cssMaxHeight: 500,
  96. selectionStyle: {
  97. cornerSize: 20,
  98. rotatingPointOffset: 70
  99. }
  100. });
  101. // Color picker for free drawing
  102. var brushColorpicker = tui.component.colorpicker.create({
  103. container: $('#tui-brush-color-picker')[0],
  104. color: '#000000'
  105. });
  106. // Color picker for text palette
  107. var textColorpicker = tui.component.colorpicker.create({
  108. container: $('#tui-text-color-picker')[0],
  109. color: '#000000'
  110. });
  111. // Color picker for shape
  112. var shapeColorpicker = tui.component.colorpicker.create({
  113. container: $('#tui-shape-color-picker')[0],
  114. color: '#000000'
  115. });
  116. // Color picker for icon
  117. var iconColorpicker = tui.component.colorpicker.create({
  118. container: $('#tui-icon-color-picker')[0],
  119. color: '#000000'
  120. });
  121. var tintColorpicker = tui.component.colorpicker.create({
  122. container: $('#tui-tint-color-picker')[0],
  123. color: '#000000'
  124. });
  125. var multiplyColorpicker = tui.component.colorpicker.create({
  126. container: $('#tui-multiply-color-picker')[0],
  127. color: '#000000'
  128. });
  129. var blendColorpicker = tui.component.colorpicker.create({
  130. container: $('#tui-blend-color-picker')[0],
  131. color: '#00FF00'
  132. });
  133. // Common global functions
  134. // HEX to RGBA
  135. function hexToRGBa(hex, alpha) {
  136. var r = parseInt(hex.slice(1, 3), 16);
  137. var g = parseInt(hex.slice(3, 5), 16);
  138. var b = parseInt(hex.slice(5, 7), 16);
  139. var a = alpha || 1;
  140. return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')';
  141. }
  142. function base64ToBlob(data) {
  143. var mimeString = '';
  144. var raw, uInt8Array, i, rawLength;
  145. raw = data.replace(rImageType, function(header, imageType) {
  146. mimeString = imageType;
  147. return '';
  148. });
  149. raw = atob(raw);
  150. rawLength = raw.length;
  151. uInt8Array = new Uint8Array(rawLength); // eslint-disable-line
  152. for (i = 0; i < rawLength; i += 1) {
  153. uInt8Array[i] = raw.charCodeAt(i);
  154. }
  155. return new Blob([uInt8Array], {type: mimeString});
  156. }
  157. function resizeEditor() {
  158. var $editor = $('.tui-image-editor');
  159. var $container = $('.tui-image-editor-canvas-container');
  160. var height = parseFloat($container.css('max-height'));
  161. $editor.height(height);
  162. }
  163. function getBrushSettings() {
  164. var brushWidth = $inputBrushWidthRange.val();
  165. var brushColor = brushColorpicker.getColor();
  166. return {
  167. width: brushWidth,
  168. color: hexToRGBa(brushColor, 0.5)
  169. };
  170. }
  171. function activateShapeMode() {
  172. if (imageEditor.getDrawingMode() !== 'SHAPE') {
  173. imageEditor.stopDrawingMode();
  174. imageEditor.startDrawingMode('SHAPE');
  175. }
  176. }
  177. function activateIconMode() {
  178. imageEditor.stopDrawingMode();
  179. }
  180. function activateTextMode() {
  181. if (imageEditor.getDrawingMode() !== 'TEXT') {
  182. imageEditor.stopDrawingMode();
  183. imageEditor.startDrawingMode('TEXT');
  184. }
  185. }
  186. function setTextToolbar(obj) {
  187. var fontSize = obj.fontSize;
  188. var fontColor = obj.fill;
  189. $inputFontSizeRange.val(fontSize);
  190. textColorpicker.setColor(fontColor);
  191. }
  192. function setIconToolbar(obj) {
  193. var iconColor = obj.fill;
  194. iconColorpicker.setColor(iconColor);
  195. }
  196. function setShapeToolbar(obj) {
  197. var strokeColor, fillColor, isTransparent;
  198. var colorType = $selectColorType.val();
  199. if (colorType === 'stroke') {
  200. strokeColor = obj.stroke;
  201. isTransparent = (strokeColor === 'transparent');
  202. if (!isTransparent) {
  203. shapeColorpicker.setColor(strokeColor);
  204. }
  205. } else if (colorType === 'fill') {
  206. fillColor = obj.fill;
  207. isTransparent = (fillColor === 'transparent');
  208. if (!isTransparent) {
  209. shapeColorpicker.setColor(fillColor);
  210. }
  211. }
  212. $inputCheckTransparent.prop('checked', isTransparent);
  213. $inputStrokeWidthRange.val(obj.strokeWidth);
  214. }
  215. function showSubMenu(type) {
  216. var $submenu;
  217. switch (type) {
  218. case 'shape':
  219. $submenu = $drawShapeSubMenu;
  220. break;
  221. case 'icon':
  222. $submenu = $iconSubMenu;
  223. break;
  224. case 'text':
  225. $submenu = $textSubMenu;
  226. break;
  227. default:
  228. $submenu = 0;
  229. }
  230. $displayingSubMenu.hide();
  231. $displayingSubMenu = $submenu.show();
  232. }
  233. function applyOrRemoveFilter(applying, type, options) {
  234. if (applying) {
  235. imageEditor.applyFilter(type, options).then(result => {
  236. console.log(result);
  237. });
  238. } else {
  239. imageEditor.removeFilter(type);
  240. }
  241. }
  242. // Attach image editor custom events
  243. imageEditor.on({
  244. objectAdded: function(objectProps) {
  245. console.info(objectProps);
  246. },
  247. undoStackChanged: function(length) {
  248. if (length) {
  249. $btnUndo.removeClass('disabled');
  250. } else {
  251. $btnUndo.addClass('disabled');
  252. }
  253. resizeEditor();
  254. },
  255. redoStackChanged: function(length) {
  256. if (length) {
  257. $btnRedo.removeClass('disabled');
  258. } else {
  259. $btnRedo.addClass('disabled');
  260. }
  261. resizeEditor();
  262. },
  263. objectScaled: function(obj) {
  264. if (obj.type === 'text') {
  265. $inputFontSizeRange.val(obj.fontSize);
  266. }
  267. },
  268. addText: function(pos) {
  269. imageEditor.addText('Double Click', {
  270. position: pos.originPosition
  271. }).then(objectProps => {
  272. console.log(objectProps);
  273. });
  274. },
  275. objectActivated: function(obj) {
  276. activeObjectId = obj.id;
  277. if (obj.type === 'rect' || obj.type === 'circle' || obj.type === 'triangle') {
  278. showSubMenu('shape');
  279. setShapeToolbar(obj);
  280. activateShapeMode();
  281. } else if (obj.type === 'icon') {
  282. showSubMenu('icon');
  283. setIconToolbar(obj);
  284. activateIconMode();
  285. } else if (obj.type === 'text') {
  286. showSubMenu('text');
  287. setTextToolbar(obj);
  288. activateTextMode();
  289. }
  290. },
  291. mousedown: function(event, originPointer) {
  292. if ($imageFilterSubMenu.is(':visible') && imageEditor.hasFilter('colorFilter')) {
  293. imageEditor.applyFilter('colorFilter', {
  294. x: parseInt(originPointer.x, 10),
  295. y: parseInt(originPointer.y, 10)
  296. });
  297. }
  298. }
  299. });
  300. // Attach button click event listeners
  301. $btns.on('click', function() {
  302. $btnsActivatable.removeClass('active');
  303. });
  304. $btnsActivatable.on('click', function() {
  305. $(this).addClass('active');
  306. });
  307. $btnUndo.on('click', function() {
  308. $displayingSubMenu.hide();
  309. if (!$(this).hasClass('disabled')) {
  310. imageEditor.undo();
  311. }
  312. });
  313. $btnRedo.on('click', function() {
  314. $displayingSubMenu.hide();
  315. if (!$(this).hasClass('disabled')) {
  316. imageEditor.redo();
  317. }
  318. });
  319. $btnClearObjects.on('click', function() {
  320. $displayingSubMenu.hide();
  321. imageEditor.clearObjects();
  322. });
  323. $btnRemoveActiveObject.on('click', function() {
  324. $displayingSubMenu.hide();
  325. imageEditor.removeObject(activeObjectId);
  326. });
  327. $btnCrop.on('click', function() {
  328. imageEditor.startDrawingMode('CROPPER');
  329. $displayingSubMenu.hide();
  330. $displayingSubMenu = $cropSubMenu.show();
  331. });
  332. $btnFlip.on('click', function() {
  333. imageEditor.stopDrawingMode();
  334. $displayingSubMenu.hide();
  335. $displayingSubMenu = $flipSubMenu.show();
  336. });
  337. $btnRotation.on('click', function() {
  338. imageEditor.stopDrawingMode();
  339. $displayingSubMenu.hide();
  340. $displayingSubMenu = $rotationSubMenu.show();
  341. });
  342. $btnClose.on('click', function() {
  343. imageEditor.stopDrawingMode();
  344. $displayingSubMenu.hide();
  345. });
  346. $btnApplyCrop.on('click', function() {
  347. imageEditor.crop(imageEditor.getCropzoneRect()).then(() => {
  348. imageEditor.stopDrawingMode();
  349. resizeEditor();
  350. });
  351. });
  352. $btnCancelCrop.on('click', function() {
  353. imageEditor.stopDrawingMode();
  354. });
  355. $btnFlipX.on('click', function() {
  356. imageEditor.flipX().then(status => {
  357. console.log('flipX: ', status.flipX);
  358. console.log('flipY: ', status.flipY);
  359. console.log('angle: ', status.angle);
  360. });
  361. });
  362. $btnFlipY.on('click', function() {
  363. imageEditor.flipY().then(status => {
  364. console.log('flipX: ', status.flipX);
  365. console.log('flipY: ', status.flipY);
  366. console.log('angle: ', status.angle);
  367. });
  368. });
  369. $btnResetFlip.on('click', function() {
  370. imageEditor.resetFlip().then(status => {
  371. console.log('flipX: ', status.flipX);
  372. console.log('flipY: ', status.flipY);
  373. console.log('angle: ', status.angle);
  374. });
  375. });
  376. $btnRotateClockwise.on('click', function() {
  377. imageEditor.rotate(30);
  378. });
  379. $btnRotateCounterClockWise.on('click', function() {
  380. imageEditor.rotate(-30);
  381. });
  382. $inputRotationRange.on('mousedown', function() {
  383. var changeAngle = function() {
  384. imageEditor.setAngle(parseInt($inputRotationRange.val(), 10)).catch(() => {});
  385. };
  386. $(document).on('mousemove', changeAngle);
  387. $(document).on('mouseup', function stopChangingAngle() {
  388. $(document).off('mousemove', changeAngle);
  389. $(document).off('mouseup', stopChangingAngle);
  390. });
  391. });
  392. $inputRotationRange.on('change', function() {
  393. imageEditor.setAngle(parseInt($inputRotationRange.val(), 10)).catch(() => {});
  394. });
  395. $inputBrushWidthRange.on('change', function() {
  396. imageEditor.setBrush({width: parseInt(this.value, 10)});
  397. });
  398. $inputImage.on('change', function(event) {
  399. var file;
  400. if (!supportingFileAPI) {
  401. alert('This browser does not support file-api');
  402. }
  403. file = event.target.files[0];
  404. imageEditor.loadImageFromFile(file).then(result => {
  405. console.log(result);
  406. imageEditor.clearUndoStack();
  407. });
  408. });
  409. $btnDownload.on('click', function() {
  410. var imageName = imageEditor.getImageName();
  411. var dataURL = imageEditor.toDataURL();
  412. var blob, type, w;
  413. if (supportingFileAPI) {
  414. blob = base64ToBlob(dataURL);
  415. type = blob.type.split('/')[1];
  416. if (imageName.split('.').pop() !== type) {
  417. imageName += '.' + type;
  418. }
  419. // Library: FileSaver - saveAs
  420. saveAs(blob, imageName); // eslint-disable-line
  421. } else {
  422. alert('This browser needs a file-server');
  423. w = window.open();
  424. w.document.body.innerHTML = '<img src=' + dataURL + '>';
  425. }
  426. });
  427. // control draw line mode
  428. $btnDrawLine.on('click', function() {
  429. imageEditor.stopDrawingMode();
  430. $displayingSubMenu.hide();
  431. $displayingSubMenu = $drawLineSubMenu.show();
  432. $selectLine.eq(0).change();
  433. });
  434. $selectLine.on('change', function() {
  435. var mode = $(this).val();
  436. var settings = getBrushSettings();
  437. imageEditor.stopDrawingMode();
  438. if (mode === 'freeDrawing') {
  439. imageEditor.startDrawingMode('FREE_DRAWING', settings);
  440. } else {
  441. imageEditor.startDrawingMode('LINE_DRAWING', settings);
  442. }
  443. });
  444. brushColorpicker.on('selectColor', function(event) {
  445. imageEditor.setBrush({
  446. color: hexToRGBa(event.color, 0.5)
  447. });
  448. });
  449. // control draw shape mode
  450. $btnDrawShape.on('click', function() {
  451. showSubMenu('shape');
  452. // step 1. get options to draw shape from toolbar
  453. shapeType = $('[name="select-shape-type"]:checked').val();
  454. shapeOptions.stroke = '#000000';
  455. shapeOptions.fill = '#ffffff';
  456. shapeOptions.strokeWidth = Number($inputStrokeWidthRange.val());
  457. // step 2. set options to draw shape
  458. imageEditor.setDrawingShape(shapeType, shapeOptions);
  459. // step 3. start drawing shape mode
  460. activateShapeMode();
  461. });
  462. $selectShapeType.on('change', function() {
  463. shapeType = $(this).val();
  464. imageEditor.setDrawingShape(shapeType);
  465. });
  466. $inputCheckTransparent.on('change', function() {
  467. var colorType = $selectColorType.val();
  468. var isTransparent = $(this).prop('checked');
  469. var color;
  470. if (!isTransparent) {
  471. color = shapeColorpicker.getColor();
  472. } else {
  473. color = 'transparent';
  474. }
  475. if (colorType === 'stroke') {
  476. imageEditor.changeShape(activeObjectId, {
  477. stroke: color
  478. });
  479. } else if (colorType === 'fill') {
  480. imageEditor.changeShape(activeObjectId, {
  481. fill: color
  482. });
  483. }
  484. imageEditor.setDrawingShape(shapeType, shapeOptions);
  485. });
  486. shapeColorpicker.on('selectColor', function(event) {
  487. var colorType = $selectColorType.val();
  488. var isTransparent = $inputCheckTransparent.prop('checked');
  489. var color = event.color;
  490. if (isTransparent) {
  491. return;
  492. }
  493. if (colorType === 'stroke') {
  494. imageEditor.changeShape(activeObjectId, {
  495. stroke: color
  496. });
  497. } else if (colorType === 'fill') {
  498. imageEditor.changeShape(activeObjectId, {
  499. fill: color
  500. });
  501. }
  502. imageEditor.setDrawingShape(shapeType, shapeOptions);
  503. });
  504. $inputStrokeWidthRange.on('change', function() {
  505. var strokeWidth = Number($(this).val());
  506. imageEditor.changeShape(activeObjectId, {
  507. strokeWidth: strokeWidth
  508. });
  509. imageEditor.setDrawingShape(shapeType, shapeOptions);
  510. });
  511. // control text mode
  512. $btnText.on('click', function() {
  513. showSubMenu('text');
  514. activateTextMode();
  515. });
  516. $inputFontSizeRange.on('change', function() {
  517. imageEditor.changeTextStyle(activeObjectId, {
  518. fontSize: parseInt(this.value, 10)
  519. });
  520. });
  521. $btnTextStyle.on('click', function(e) { // eslint-disable-line
  522. var styleType = $(this).attr('data-style-type');
  523. var styleObj;
  524. e.stopPropagation();
  525. switch (styleType) {
  526. case 'b':
  527. styleObj = {fontWeight: 'bold'};
  528. break;
  529. case 'i':
  530. styleObj = {fontStyle: 'italic'};
  531. break;
  532. case 'u':
  533. styleObj = {textDecoration: 'underline'};
  534. break;
  535. case 'l':
  536. styleObj = {textAlign: 'left'};
  537. break;
  538. case 'c':
  539. styleObj = {textAlign: 'center'};
  540. break;
  541. case 'r':
  542. styleObj = {textAlign: 'right'};
  543. break;
  544. default:
  545. styleObj = {};
  546. }
  547. imageEditor.changeTextStyle(activeObjectId, styleObj);
  548. });
  549. textColorpicker.on('selectColor', function(event) {
  550. imageEditor.changeTextStyle(activeObjectId, {
  551. 'fill': event.color
  552. });
  553. });
  554. // control icon
  555. $btnAddIcon.on('click', function() {
  556. showSubMenu('icon');
  557. activateIconMode();
  558. });
  559. function onClickIconSubMenu(event) {
  560. var element = event.target || event.srcElement;
  561. var iconType = $(element).attr('data-icon-type');
  562. imageEditor.once('mousedown', function(e, originPointer) {
  563. imageEditor.addIcon(iconType, {
  564. left: originPointer.x,
  565. top: originPointer.y
  566. }).then(objectProps => {
  567. console.log(objectProps);
  568. });
  569. });
  570. }
  571. $btnRegisterIcon.on('click', function() {
  572. $iconSubMenu.find('.menu-item').eq(3).after(
  573. '<li id="customArrow" class="menu-item icon-text" data-icon-type="customArrow">↑</li>'
  574. );
  575. imageEditor.registerIcons({
  576. customArrow: 'M 60 0 L 120 60 H 90 L 75 45 V 180 H 45 V 45 L 30 60 H 0 Z'
  577. });
  578. $btnRegisterIcon.off('click');
  579. $iconSubMenu.on('click', '#customArrow', onClickIconSubMenu);
  580. });
  581. $iconSubMenu.on('click', '.icon-text', onClickIconSubMenu);
  582. iconColorpicker.on('selectColor', function(event) {
  583. imageEditor.changeIconColor(activeObjectId, event.color);
  584. });
  585. // control mask filter
  586. $btnMaskFilter.on('click', function() {
  587. imageEditor.stopDrawingMode();
  588. $displayingSubMenu.hide();
  589. $displayingSubMenu = $filterSubMenu.show();
  590. });
  591. $btnImageFilter.on('click', function() {
  592. var filters = {
  593. 'grayscale': $inputCheckGrayscale,
  594. 'invert': $inputCheckInvert,
  595. 'sepia': $inputCheckSepia,
  596. 'sepia2': $inputCheckSepia2,
  597. 'blur': $inputCheckBlur,
  598. 'shapren': $inputCheckSharpen,
  599. 'emboss': $inputCheckEmboss,
  600. 'removeWhite': $inputCheckRemoveWhite,
  601. 'brightness': $inputCheckBrightness,
  602. 'noise': $inputCheckNoise,
  603. 'gradientTransparency': $inputCheckGradientTransparency,
  604. 'pixelate': $inputCheckPixelate,
  605. 'tint': $inputCheckTint,
  606. 'multiply': $inputCheckMultiply,
  607. 'blend': $inputCheckBlend,
  608. 'colorFilter': $inputCheckColorFilter
  609. };
  610. tui.util.forEach(filters, function($value, key) {
  611. $value.prop('checked', imageEditor.hasFilter(key));
  612. });
  613. $displayingSubMenu.hide();
  614. $displayingSubMenu = $imageFilterSubMenu.show();
  615. });
  616. $btnLoadMaskImage.on('change', function() {
  617. var file;
  618. var imgUrl;
  619. if (!supportingFileAPI) {
  620. alert('This browser does not support file-api');
  621. }
  622. file = event.target.files[0];
  623. if (file) {
  624. imgUrl = URL.createObjectURL(file);
  625. imageEditor.loadImageFromURL(imageEditor.toDataURL(), 'FilterImage').then(() => {
  626. imageEditor.addImageObject(imgUrl).then(objectProps => {
  627. URL.revokeObjectURL(file);
  628. console.log(objectProps);
  629. });
  630. });
  631. }
  632. });
  633. $btnApplyMask.on('click', function() {
  634. imageEditor.applyFilter('mask', {
  635. maskObjId: activeObjectId
  636. }).then(result => {
  637. console.log(result);
  638. });
  639. });
  640. $inputCheckGrayscale.on('change', function() {
  641. applyOrRemoveFilter(this.checked, 'Grayscale', null);
  642. });
  643. $inputCheckInvert.on('change', function() {
  644. applyOrRemoveFilter(this.checked, 'Invert', null);
  645. });
  646. $inputCheckSepia.on('change', function() {
  647. applyOrRemoveFilter(this.checked, 'Sepia', null);
  648. });
  649. $inputCheckSepia2.on('change', function() {
  650. applyOrRemoveFilter(this.checked, 'Sepia2', null);
  651. });
  652. $inputCheckBlur.on('change', function() {
  653. applyOrRemoveFilter(this.checked, 'Blur', null);
  654. });
  655. $inputCheckSharpen.on('change', function() {
  656. applyOrRemoveFilter(this.checked, 'Sharpen', null);
  657. });
  658. $inputCheckEmboss.on('change', function() {
  659. applyOrRemoveFilter(this.checked, 'Emboss', null);
  660. });
  661. $inputCheckRemoveWhite.on('change', function() {
  662. applyOrRemoveFilter(this.checked, 'removeWhite', {
  663. threshold: parseInt($inputRangeRemoveWhiteThreshold.val(), 10),
  664. distance: parseInt($inputRangeRemoveWhiteDistance.val(), 10)
  665. });
  666. });
  667. $inputRangeRemoveWhiteThreshold.on('change', function() {
  668. applyOrRemoveFilter($inputCheckRemoveWhite.is(':checked'), 'removeWhite', {
  669. threshold: parseInt(this.value, 10)
  670. });
  671. });
  672. $inputRangeRemoveWhiteDistance.on('change', function() {
  673. applyOrRemoveFilter($inputCheckRemoveWhite.is(':checked'), 'removeWhite', {
  674. distance: parseInt(this.value, 10)
  675. });
  676. });
  677. $inputCheckBrightness.on('change', function() {
  678. applyOrRemoveFilter(this.checked, 'brightness', {
  679. brightness: parseInt($inputRangeBrightnessValue.val(), 10)
  680. });
  681. });
  682. $inputRangeBrightnessValue.on('change', function() {
  683. applyOrRemoveFilter($inputCheckBrightness.is(':checked'), 'brightness', {
  684. brightness: parseInt(this.value, 10)
  685. });
  686. });
  687. $inputCheckNoise.on('change', function() {
  688. applyOrRemoveFilter(this.checked, 'noise', {
  689. noise: parseInt($inputRangeNoiseValue.val(), 10)
  690. });
  691. });
  692. $inputRangeNoiseValue.on('change', function() {
  693. applyOrRemoveFilter($inputCheckNoise.is(':checked'), 'noise', {
  694. noise: parseInt(this.value, 10)
  695. });
  696. });
  697. $inputCheckGradientTransparency.on('change', function() {
  698. applyOrRemoveFilter(this.checked, 'gradientTransparency', {
  699. threshold: parseInt($inputRangeGradientTransparencyValue.val(), 10)
  700. });
  701. });
  702. $inputRangeGradientTransparencyValue.on('change', function() {
  703. applyOrRemoveFilter($inputCheckGradientTransparency.is(':checked'), 'gradientTransparency', {
  704. threshold: parseInt(this.value, 10)
  705. });
  706. });
  707. $inputCheckPixelate.on('change', function() {
  708. applyOrRemoveFilter(this.checked, 'pixelate', {
  709. blocksize: parseInt($inputRangePixelateValue.val(), 10)
  710. });
  711. });
  712. $inputRangePixelateValue.on('change', function() {
  713. applyOrRemoveFilter($inputCheckPixelate.is(':checked'), 'pixelate', {
  714. blocksize: parseInt(this.value, 10)
  715. });
  716. });
  717. $inputCheckTint.on('change', function() {
  718. applyOrRemoveFilter(this.checked, 'tint', {
  719. color: tintColorpicker.getColor(),
  720. opacity: parseFloat($inputRangeTintOpacityValue.val())
  721. });
  722. });
  723. tintColorpicker.on('selectColor', function(e) {
  724. applyOrRemoveFilter($inputCheckTint.is(':checked'), 'tint', {
  725. color: e.color
  726. });
  727. });
  728. $inputRangeTintOpacityValue.on('change', function() {
  729. applyOrRemoveFilter($inputCheckTint.is(':checked'), 'tint', {
  730. opacity: parseFloat($inputRangeTintOpacityValue.val())
  731. });
  732. });
  733. $inputCheckMultiply.on('change', function() {
  734. applyOrRemoveFilter(this.checked, 'multiply', {
  735. color: multiplyColorpicker.getColor()
  736. });
  737. });
  738. multiplyColorpicker.on('selectColor', function(e) {
  739. applyOrRemoveFilter($inputCheckMultiply.is(':checked'), 'multiply', {
  740. color: e.color
  741. });
  742. });
  743. $inputCheckBlend.on('change', function() {
  744. applyOrRemoveFilter(this.checked, 'blend', {
  745. color: blendColorpicker.getColor(),
  746. mode: $selectBlendType.val()
  747. });
  748. });
  749. blendColorpicker.on('selectColor', function(e) {
  750. applyOrRemoveFilter($inputCheckBlend.is(':checked'), 'blend', {
  751. color: e.color
  752. });
  753. });
  754. $selectBlendType.on('change', function() {
  755. applyOrRemoveFilter($inputCheckBlend.is(':checked'), 'blend', {
  756. mode: this.value
  757. });
  758. });
  759. $inputCheckColorFilter.on('change', function() {
  760. applyOrRemoveFilter(this.checked, 'colorFilter', {
  761. color: '#FFFFFF',
  762. threshold: $inputRangeColorFilterValue.val()
  763. });
  764. });
  765. $inputRangeColorFilterValue.on('change', function() {
  766. applyOrRemoveFilter($inputCheckColorFilter.is(':checked'), 'colorFilter', {
  767. threshold: this.value
  768. });
  769. });
  770. // Etc..
  771. // Load sample image
  772. imageEditor.loadImageFromURL('/statics/v1/library/imageEditor/img/sampleImage.jpg', 'SampleImage').then(sizeValue => {
  773. console.log(sizeValue);
  774. imageEditor.clearUndoStack();
  775. });
  776. // IE9 Unselectable
  777. $('.menu').on('selectstart', function() {
  778. return false;
  779. });