Search results

Render Image Editor in Dialog

08 May 2023 / 3 minutes to read

Image Editor is rendered within a dialog and opens an image by passing its URL path to the open method of the Image Editor control.

The following operations are supported in the Image Editor:

  • Selection : Multiple selection options are available. The selection region can be a square or circle, customized to various aspect ratios, and customized by dragging and resizing.
  • Crop : The image can be cropped based on the selection.
  • Rotate : The image can be rotated both clockwise and anticlockwise by 90 degrees.
Source
Preview
app.ts
index.html
styles.css
Copied to clipboard
import { ImageEditor } from '@syncfusion/ej2-image-editor';
import { Dialog } from '@syncfusion/ej2-popups';
import { getComponent, createElement } from '@syncfusion/ej2-base';
import { loadCultureFiles } from '../common/culture-loader';

loadCultureFiles();
const img: HTMLImageElement = document.querySelector('#custom-img');

img.onload = function() {
    const canvas: HTMLCanvasElement = document.querySelector('#img-canvas');
    const ctx: CanvasRenderingContext2D = canvas.getContext('2d');
    canvas.width = img.width < img.height ? img.width : img.height; canvas.height = canvas.width;
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}

const dialogObj: Dialog = new Dialog({
    header: 'Edit Profile Image',
    animationSettings: { effect: 'None' },
    showCloseIcon: true,
    target: '.control-section',
    width: '340px',
    height: '400px',
    position: {X: 'center', Y: 'center'},
    visible: false,
    close: () => {
        const imageEditor: ImageEditor = getComponent(document.getElementById('image-editor'), 'image-editor') as ImageEditor;
        imageEditor.destroy();
        document.getElementById('image-editor').className = '';
    },
    open: () => {
        new ImageEditor({
            fileOpened: () => {
                const imageEditor: ImageEditor = getComponent(document.getElementById('image-editor'), 'image-editor') as ImageEditor;
                imageEditor.select('circle');
            },
            created: () => {
                const imageEditor: ImageEditor = getComponent(document.getElementById('image-editor'), 'image-editor') as ImageEditor;
                imageEditor.theme = window.location.href.split('#')[1].split('/')[1];
            },
            toolbar: []
        }, '#image-editor');
    },
    buttons: [
    {
        click: () => {
            document.getElementById('img-upload').click();
        },
        buttonModel: { content: 'Open', isPrimary: false, cssClass: 'e-custom-img-btn e-img-custom-open' }
    },
    {
        click: () => {
            const imageEditor: ImageEditor = getComponent(document.getElementById('image-editor'), 'image-editor') as ImageEditor;
            imageEditor.reset();
        },
        buttonModel: { content: 'Reset', isPrimary: false, cssClass: 'e-custom-img-btn e-img-custom-reset' }
    },
    {
        click: () => {
            const imageEditor: ImageEditor = getComponent(document.getElementById('image-editor'), 'image-editor') as ImageEditor;
            imageEditor.rotate(-90);
        },
        buttonModel: { content: 'Rotate', isPrimary: false, cssClass: 'e-custom-img-btn e-img-custom-rotate' }
    },
    {
        click: () => {
            const imageEditor: ImageEditor = getComponent(document.getElementById('image-editor'), 'image-editor') as ImageEditor;
            imageEditor.crop();
            const croppedData: ImageData = imageEditor.getImageData();
            const canvas: HTMLCanvasElement = document.querySelector('#img-canvas');
            const ctx: CanvasRenderingContext2D = canvas.getContext('2d');
            const parentDiv: HTMLElement = document.querySelector('.e-profile');
            const tempCanvas: HTMLCanvasElement = parentDiv.appendChild(createElement('canvas') as HTMLCanvasElement);
            const tempContext: CanvasRenderingContext2D = tempCanvas.getContext('2d');
            tempCanvas.width = croppedData.width; tempCanvas.height = croppedData.height;
            tempContext.putImageData(croppedData, 0, 0);
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.drawImage(tempCanvas, 0, 0, canvas.width, canvas.height);
            tempCanvas.remove();
            parentDiv.style.borderRadius = '100%'; canvas.style.backgroundColor = '#fff';
            dialogObj.hide();
        },
        buttonModel: { content: 'Apply', isPrimary: true, cssClass: 'e-custom-img-btn e-img-custom-apply' }
    }]
});

dialogObj.appendTo('#profile-dialog');

document.getElementById('custom-edit').onclick = (): void => {
    dialogObj.show();
    const imageEditor: ImageEditor = getComponent(document.getElementById('image-editor'), 'image-editor') as ImageEditor;
    const canvas: HTMLCanvasElement = document.querySelector('#img-canvas');
    imageEditor.open(canvas.toDataURL());
};

document.getElementById('img-upload').onchange = (args: any): void => {
    const URL = window.URL; const url = URL.createObjectURL((args.target as any).files[0]);
    const imageEditor: ImageEditor = getComponent(document.getElementById('image-editor'), 'image-editor');
    imageEditor.open(url.toString());
    (document.getElementById('img-upload') as HTMLInputElement).value = null;
};
(document.getElementsByClassName('sb-desktop-wrapper')[0] as HTMLElement).onclick = function (args) {
    const target: HTMLElement = args.target as HTMLElement;
    if (target.className.indexOf('e-img-editor-sample') > -1 || target.className.indexOf('sb-content') > -1) {
        dialogObj.hide();
        }
}
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
            
    <title>Essential JS 2</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
    <meta name="description" content="Essential JS 2" />
    <meta name="author" content="Syncfusion" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-image-editor/styles/material.css" rel="stylesheet" />


    <!--style reference from app-->
    <link href="styles.css" rel="stylesheet" />

    <!--system js reference and configuration-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>
<body>
    <div id='loader'>LOADING....</div>
    <div class="col-lg-12 control-section e-img-editor-sample">
        <div class="e-profile">
            <div class="e-custom-wrapper">
                <canvas id="img-canvas" style="max-width: 200px; max-height: 200px;"></canvas>
                <img alt="img" id="custom-img" crossorigin="anonymous" src="images/profile.png"
                style="display: none;"/>
                <input type="file" id="img-upload" style="display:none"/>
                <span id="custom-edit" class="e-custom-edit" contenteditable="false">
                    <span class="e-custom-icon sb-icons" contenteditable="false"></span>
                </span>
            </div>
        </div>
    </div>
    <div id="profile-dialog">
        <div id="image-editor"></div>
    </div>
    
    
    <style>
        .e-img-editor-sample,
        .e-img-editor-sample .control-wrapper {
            position: relative;
        }
    
        .e-profile {
            width: 200px;
            height: 200px;
            position: absolute;
            left: 50%;
            -webkit-transform: translate(-50%, 30%);
            transform: translate(-50%, 30%);
            border-radius: 50%;
        }
    
        .e-custom-wrapper {
            position: relative;
        }
    
        .e-custom-edit {
            position: absolute;
            width: 36px;
            height: 36px;
            border-radius: 50%;
            background-color: blue;
            top: calc(100% - 54px);
            left: calc(100% - 47px);
        }
    
        .e-custom-icon::before {
            content: '\e911';
            font-size: 28px;
            color: white;
            left: 5px;
            top: -2px;
            position: absolute;
        }
</style>    
</body>

</html>
Copied to clipboard