123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611 |
- <!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>
|