<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Image editor basic</title> <link type="text/css" href="https://cdn.rawgit.com/nhnent/tui.component.image-editor/1.3.0/samples/css/colorpicker.min.css" rel="stylesheet"> <link type="text/css" href="https://cdn.rawgit.com/nhnent/tui.component.image-editor/1.3.0/samples/css/tui-image-editor.css" rel="stylesheet"> </head> <body> <h1><a href="https://github.com/nhnent/tui.component.image-editor" target="_blank">TUI Component Image Editor</a></h1> <div class="code-html"> <div class="body-container"> <div class="tui-image-editor-controls"> <div class="header"> <img class="logo" src="https://cdn.rawgit.com/nhnent/tui.component.image-editor/1.3.0/samples/img/TOAST UI Component.png"> <span class="name"> Image Editor</span> <ul class="menu"> <li class="menu-item border input-wrapper"> Load <input type="file" accept="image/*" id="input-image-file"> </li> <li class="menu-item border" id="btn-download">Download</li> </ul> </div> <ul class="menu"> <li class="menu-item disabled" id="btn-undo">Undo</li> <li class="menu-item disabled" id="btn-redo">Redo</li> <li class="menu-item" id="btn-clear-objects">ClearObjects</li> <li class="menu-item" id="btn-remove-active-object">RemoveActiveObject</li> <li class="menu-item" id="btn-crop">Crop</li> <li class="menu-item" id="btn-flip">Flip</li> <li class="menu-item" id="btn-rotation">Rotation</li> <li class="menu-item" id="btn-draw-line">DrawLine</li> <li class="menu-item" id="btn-add-icon">Icon</li> <li class="menu-item" id="btn-text">Text</li> <li class="menu-item" id="btn-mask-filter">Mask</li> </ul> <div class="sub-menu-container" id="crop-sub-menu"> <ul class="menu"> <li class="menu-item" id="btn-apply-crop">Apply</li> <li class="menu-item" id="btn-cancel-crop">Cancel</li> </ul> </div> <div class="sub-menu-container" id="flip-sub-menu"> <ul class="menu"> <li class="menu-item" id="btn-flip-x">FlipX</li> <li class="menu-item" id="btn-flip-y">FlipY</li> <li class="menu-item" id="btn-reset-flip">Reset</li> <li class="menu-item close">Close</li> </ul> </div> <div class="sub-menu-container" id="rotation-sub-menu"> <ul class="menu"> <li class="menu-item" id="btn-rotate-clockwise">Clockwise(30)</li> <li class="menu-item" id="btn-rotate-counter-clockwise">Counter-Clockwise(-30)</li> <li class="menu-item no-pointer"><label>Range input<input id="input-rotation-range" type="range" min="-360" value="0" max="360"></label></li> <li class="menu-item close">Close</li> </ul> </div> <div class="sub-menu-container menu" id="draw-line-sub-menu"> <ul class="menu"> <li class="menu-item"> <label><input type="radio" class="select-line-type" name="select-line-type" value="freeDrawing"> Free drawing</label> </li> <li class="menu-item"> <label><input type="radio" class="select-line-type" name="select-line-type" value="lineDrawing"> Straight line</label> </li> <li class="menu-item"> <div id="tui-brush-color-picker">Brush color</div> </li> <li class="menu-item"><label class="menu-item no-pointer">Brush width<input id="input-brush-width-range" type="range" min="5" max="30" value="12"></label></li> <li class="menu-item close">Close</li> </ul> </div> <div class="sub-menu-container" id="icon-sub-menu"> <ul class="menu"> <li class="menu-item"> <div id="tui-icon-color-picker">Icon color</div> </li> <li class="menu-item border" id="btn-register-icon">Register custom icon</li> <li class="menu-item icon-text" data-icon-type="arrow">➡</li> <li class="menu-item icon-text" data-icon-type="cancel">✖</li> <li class="menu-item close">Close</li> </ul> </div> <div class="sub-menu-container" id="text-sub-menu"> <ul class="menu"> <li class="menu-item"> <div> <button class="btn-text-style" data-style-type="b">Bold</button> <button class="btn-text-style" data-style-type="i">Italic</button> <button class="btn-text-style" data-style-type="u">Underline</button> </div> <div> <button class="btn-text-style" data-style-type="l">Left</button> <button class="btn-text-style" data-style-type="c">Center</button> <button class="btn-text-style" data-style-type="r">Right</button> </div> </li> <li class="menu-item"><label class="no-pointer"><input id="input-font-size-range" type="range" min="10" max="100" value="10"></label></li> <li class="menu-item"> <div id="tui-text-color-picker">Text color</div> </li> <li class="menu-item close">Close</li> </ul> </div> <div class="sub-menu-container" id="filter-sub-menu"> <ul class="menu"> <li class="menu-item border input-wrapper"> Load Mask Image <input type="file" accept="image/*" id="input-mask-image-file"> </li> <li class="menu-item" id="btn-apply-mask">Apply mask filter</li> <li class="menu-item close">Close</li> </ul> </div> </div> <div class="tui-image-editor"> <canvas></canvas> </div> </div> </div> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.6/fabric.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script> <script type="text/javascript" src="https://cdn.rawgit.com/nhnent/tui.code-snippet/1.2.1/code-snippet.js"></script> <script type="text/javascript" src="https://cdn.rawgit.com/nhnent/tui.component.colorpicker/1.0.2/dist/colorpicker.min.js"></script> <script type="text/javascript" src="https://cdn.rawgit.com/nhnent/tui.component.image-editor/1.3.0/dist/image-editor.min.js"></script> <script class="code-js"> /** * basic.js * @author NHN Ent. FE Development Team <dl_javascript@nhnent.com> * @fileoverview */ /* eslint-disable vars-on-top */ 'use strict'; var supportingFileAPI = !!(window.File && window.FileList && window.FileReader); var rImageType = /data:(image\/.+);base64,/; var mask; // Functions // HEX to RGBA function hexToRGBa(hex, alpha) { var r = parseInt(hex.slice(1, 3), 16); var g = parseInt(hex.slice(3, 5), 16); var b = parseInt(hex.slice(5, 7), 16); var a = alpha || 1; return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + a + ')'; } function base64ToBlob(data) { var mimeString = ''; var raw, uInt8Array, i, rawLength; raw = data.replace(rImageType, function(header, imageType) { mimeString = imageType; return ''; }); raw = atob(raw); rawLength = raw.length; uInt8Array = new Uint8Array(rawLength); // eslint-disable-line for (i = 0; i < rawLength; i += 1) { uInt8Array[i] = raw.charCodeAt(i); } return new Blob([uInt8Array], {type: mimeString}); } function getBrushSettings() { var brushWidth = $inputBrushWidthRange.val(); var brushColor = brushColorpicker.getColor(); return { width: brushWidth, color: hexToRGBa(brushColor, 0.5) }; } // Buttons var $btns = $('.menu-item'); var $btnsActivatable = $btns.filter('.activatable'); var $inputImage = $('#input-image-file'); var $btnDownload = $('#btn-download'); var $btnUndo = $('#btn-undo'); var $btnRedo = $('#btn-redo'); var $btnClearObjects = $('#btn-clear-objects'); var $btnRemoveActiveObject = $('#btn-remove-active-object'); var $btnCrop = $('#btn-crop'); var $btnFlip = $('#btn-flip'); var $btnRotation = $('#btn-rotation'); var $btnDrawLine = $('#btn-draw-line'); var $btnApplyCrop = $('#btn-apply-crop'); var $btnCancelCrop = $('#btn-cancel-crop'); var $btnFlipX = $('#btn-flip-x'); var $btnFlipY = $('#btn-flip-y'); var $btnResetFlip = $('#btn-reset-flip'); var $btnRotateClockwise = $('#btn-rotate-clockwise'); var $btnRotateCounterClockWise = $('#btn-rotate-counter-clockwise'); var $btnText = $('#btn-text'); var $btnClosePalette = $('#btn-close-palette'); var $btnTextStyle = $('.btn-text-style'); var $btnAddIcon = $('#btn-add-icon'); var $btnRegisterIcon = $('#btn-register-icon'); var $btnMaskFilter = $('#btn-mask-filter'); var $btnLoadMaskImage = $('#input-mask-image-file'); var $btnApplyMask = $('#btn-apply-mask'); var $btnClose = $('.close'); // Range Input var $inputRotationRange = $('#input-rotation-range'); var $inputBrushWidthRange = $('#input-brush-width-range'); var $inputFontSizeRange = $('#input-font-size-range'); // Sub menus var $displayingSubMenu = $(); var $cropSubMenu = $('#crop-sub-menu'); var $flipSubMenu = $('#flip-sub-menu'); var $rotationSubMenu = $('#rotation-sub-menu'); var $freeDrawingSubMenu = $('#free-drawing-sub-menu'); var $drawLineSubMenu = $('#draw-line-sub-menu'); var $textSubMenu = $('#text-sub-menu'); var $iconSubMenu = $('#icon-sub-menu'); var $filterSubMenu = $('#filter-sub-menu'); // Select line type var $selectMode = $('[name="select-line-type"]'); // Text palette var $textPalette = $('#tui-text-palette'); // Image editor var imageEditor = new tui.component.ImageEditor('.tui-image-editor canvas', { cssMaxWidth: 700, cssMaxHeight: 500 }); // Color picker for free drawing var brushColorpicker = tui.component.colorpicker.create({ container: $('#tui-brush-color-picker')[0], color: '#000000' }); // Color picker for text palette var textPaletteColorpicker = tui.component.colorpicker.create({ container: $('#tui-text-color-picker')[0], color: '#000000' }); // Color picker for icon var iconColorpicker = tui.component.colorpicker.create({ container: $('#tui-icon-color-picker')[0], color: '#000000' }); brushColorpicker.on('selectColor', function(event) { imageEditor.setBrush({ color: hexToRGBa(event.color, 0.5) }); }); // Attach image editor custom events imageEditor.once('loadImage', function() { imageEditor.clearUndoStack(); }); var resizeEditor = function() { var $editor = $('.tui-image-editor'); var $container = $('.tui-image-editor-canvas-container'); var height = parseFloat($container.css('max-height')); $editor.height(height); }; imageEditor.on({ endCropping: function() { $cropSubMenu.hide(); resizeEditor(); }, endFreeDrawing: function() { $freeDrawingSubMenu.hide(); }, emptyUndoStack: function() { $btnUndo.addClass('disabled'); resizeEditor(); }, emptyRedoStack: function() { $btnRedo.addClass('disabled'); resizeEditor(); }, pushUndoStack: function() { $btnUndo.removeClass('disabled'); resizeEditor(); }, pushRedoStack: function() { $btnRedo.removeClass('disabled'); resizeEditor(); }, activateText: function(obj) { $displayingSubMenu.hide(); $displayingSubMenu = $textSubMenu.show(); if (obj.type === 'new') { // add new text on cavas imageEditor.addText('Double Click', { position: obj.originPosition }); } }, adjustObject: function(obj, type) { if (obj.type === 'text' && type === 'scale') { $inputFontSizeRange.val(obj.getFontSize()); } }, removeObject: function(obj) { console.log(obj); } }); // Attach button click event listeners $btns.on('click', function() { $btnsActivatable.removeClass('active'); }); $btnsActivatable.on('click', function() { $(this).addClass('active'); }); $btnUndo.on('click', function() { $displayingSubMenu.hide(); imageEditor.undo(); }); $btnRedo.on('click', function() { $displayingSubMenu.hide(); imageEditor.redo(); }); $btnClearObjects.on('click', function() { $displayingSubMenu.hide(); imageEditor.clearObjects(); }); $btnRemoveActiveObject.on('click', function() { $displayingSubMenu.hide(); imageEditor.removeActiveObject(); }); $btnCrop.on('click', function() { imageEditor.startCropping(); $displayingSubMenu.hide(); $displayingSubMenu = $cropSubMenu.show(); }); $btnFlip.on('click', function() { imageEditor.endAll(); $displayingSubMenu.hide(); $displayingSubMenu = $flipSubMenu.show(); }); $btnRotation.on('click', function() { imageEditor.endAll(); $displayingSubMenu.hide(); $displayingSubMenu = $rotationSubMenu.show(); }); $btnClose.on('click', function() { imageEditor.endAll(); $displayingSubMenu.hide(); }); $btnApplyCrop.on('click', function() { imageEditor.endCropping(true); }); $btnCancelCrop.on('click', function() { imageEditor.endCropping(); $displayingSubMenu.hide(); }); $btnFlipX.on('click', function() { imageEditor.flipX(); }); $btnFlipY.on('click', function() { imageEditor.flipY(); }); $btnResetFlip.on('click', function() { imageEditor.resetFlip(); }); $btnRotateClockwise.on('click', function() { imageEditor.rotate(30); }); $btnRotateCounterClockWise.on('click', function() { imageEditor.rotate(-30); }); $inputRotationRange.on('mousedown', function() { var changeAngle = function() { imageEditor.setAngle(parseInt($inputRotationRange.val(), 10)); }; $(document).on('mousemove', changeAngle); $(document).on('mouseup', function stopChangingAngle() { $(document).off('mousemove', changeAngle); $(document).off('mouseup', stopChangingAngle); }); }); $inputBrushWidthRange.on('change', function() { imageEditor.setBrush({width: parseInt(this.value, 10)}); }); $inputImage.on('change', function(event) { var file; if (!supportingFileAPI) { alert('This browser does not support file-api'); } file = event.target.files[0]; imageEditor.loadImageFromFile(file); }); $btnDownload.on('click', function() { var imageName = imageEditor.getImageName(); var dataURL = imageEditor.toDataURL(); var blob, type, w; if (supportingFileAPI) { blob = base64ToBlob(dataURL); type = blob.type.split('/')[1]; if (imageName.split('.').pop() !== type) { imageName += '.' + type; } // Library: FileSaver - saveAs saveAs(blob, imageName); // eslint-disable-line } else { alert('This browser needs a file-server'); w = window.open(); w.document.body.innerHTML = '<img src=' + dataURL + '>'; } }); // control draw mode $btnDrawLine.on('click', function() { imageEditor.endAll(); $displayingSubMenu.hide(); $displayingSubMenu = $drawLineSubMenu.show(); $selectMode.removeAttr('checked'); }); $selectMode.on('change', function() { var mode = $(this).val(); var settings = getBrushSettings(); var state = imageEditor.getCurrentState(); if (mode === 'freeDrawing') { if (state === 'FREE_DRAWING') { imageEditor.endFreeDrawing(); } imageEditor.startFreeDrawing(settings); } else { if (state === 'LINE') { imageEditor.endLineDrawing(); } imageEditor.startLineDrawing(settings); } }); // control text mode $btnText.on('click', function() { if (imageEditor.getCurrentState() === 'TEXT') { $(this).removeClass('active'); imageEditor.endTextMode(); } else { $displayingSubMenu.hide(); $displayingSubMenu = $textSubMenu.show(); imageEditor.startTextMode(); $textPalette.hide(); } }); $inputFontSizeRange.on('change', function() { imageEditor.changeTextStyle({ fontSize: parseInt(this.value, 10) }); }); $btnTextStyle.on('click', function(e) { // eslint-disable-line var styleType = $(this).attr('data-style-type'); var styleObj; e.stopPropagation(); switch (styleType) { case 'b': styleObj = {fontWeight: 'bold'}; break; case 'i': styleObj = {fontStyle: 'italic'}; break; case 'u': styleObj = {textDecoration: 'underline'}; break; case 'l': styleObj = {textAlign: 'left'}; break; case 'c': styleObj = {textAlign: 'center'}; break; case 'r': styleObj = {textAlign: 'right'}; break; default: styleObj = {}; } imageEditor.changeTextStyle(styleObj); }); textPaletteColorpicker.on('selectColor', function(event) { imageEditor.changeTextStyle({ 'fill': event.color }); }); $btnClosePalette.on('click', function() { imageEditor.deactivateAll(); $textPalette.hide(); }); // control icon $btnAddIcon.on('click', function() { imageEditor.endAll(); $displayingSubMenu.hide(); $displayingSubMenu = $iconSubMenu.show(); }); $btnRegisterIcon.on('click', function() { $iconSubMenu.find('.menu').append( '<li class="menu-item icon-text" data-icon-type="customArrow">↑</li>' ); imageEditor.registerIcons({ customArrow: 'M 60 0 L 120 60 H 90 L 75 45 V 180 H 45 V 45 L 30 60 H 0 Z' }); $btnRegisterIcon.off('click'); }); $iconSubMenu.on('click', '.menu-item', function() { var iconType = $(this).attr('data-icon-type'); imageEditor.addIcon(iconType); }); iconColorpicker.on('selectColor', function(event) { imageEditor.changeIconColor(event.color); }); // control mask filter $btnMaskFilter.on('click', function() { imageEditor.endAll(); $displayingSubMenu.hide(); $displayingSubMenu = $filterSubMenu.show(); }); $btnLoadMaskImage.on('change', function() { var file; var imgUrl; if (!supportingFileAPI) { alert('This browser does not support file-api'); } file = event.target.files[0]; if (file) { imgUrl = URL.createObjectURL(file); imageEditor.loadImageFromURL(imageEditor.toDataURL(), 'FilterImage'); imageEditor.addImageObject(imgUrl); } }); $btnApplyMask.on('click', function() { imageEditor.applyFilter('mask'); }); // Etc.. // Load sample image imageEditor.loadImageFromURL('https://cdn.rawgit.com/nhnent/tui.component.image-editor/1.3.0/samples/img/sampleImage.jpg', 'SampleImage'); // IE9 Unselectable $('.menu').on('selectstart', function() { return false; }); </script> </body> </html>