nhn / toast-ui.react-image-editor

TOAST UI ImageEditor wrapper for React.js
MIT License
117 stars 51 forks source link

SVG icons are not displayed on the editor #19

Closed joongbae closed 4 years ago

joongbae commented 4 years ago

Version

"@toast-ui/react-image-editor": "^1.0.1"

Test Environment

Windows10, Chrome

Current Behavior

I created a basic implementation of the TOAT UI using React.js however I am facing an issue with the svg icons which are not displayed somehow.

import React from 'react';
import 'tui-image-editor/dist/tui-image-editor.css'
import 'tui-image-editor/dist/svg/icon-a.svg';
import 'tui-image-editor/dist/svg/icon-b.svg';
import 'tui-image-editor/dist/svg/icon-c.svg';
import 'tui-image-editor/dist/svg/icon-d.svg';
import ImageEditor from '@toast-ui/react-image-editor';

var customTheme = {
  'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',
  'common.bisize.width': '251px',
  'common.bisize.height': '21px',
  'common.backgroundImage': 'none',
  'common.backgroundColor': '#1e1e1e',
  'common.border': '0px',

  // header
  'header.backgroundImage': 'none',
  'header.backgroundColor': 'transparent',
  'header.border': '0px',

  // load button
  'loadButton.backgroundColor': '#fff',
  'loadButton.border': '1px solid #ddd',
  'loadButton.color': '#222',
  'loadButton.fontFamily': 'NotoSans, sans-serif',
  'loadButton.fontSize': '12px',

  // download button
  'downloadButton.backgroundColor': '#fdba3b',
  'downloadButton.border': '1px solid #fdba3b',
  'downloadButton.color': '#fff',
  'downloadButton.fontFamily': 'NotoSans, sans-serif',
  'downloadButton.fontSize': '12px',

  // main icons
  'menu.normalIcon.path': '../dist/svg/icon-b.svg',
  'menu.normalIcon.name': 'icon-b',
  'menu.activeIcon.path': '../dist/svg/icon-a.svg',
  'menu.activeIcon.name': 'icon-a',
  'menu.iconSize.width': '24px',
  'menu.iconSize.height': '24px',

  // submenu primary color
  'submenu.backgroundColor': '#1e1e1e',
  'submenu.partition.color': '#858585',

  // submenu icons
  'submenu.normalIcon.path': '../dist/svg/icon-a.svg',
  'submenu.normalIcon.name': 'icon-a',
  'submenu.activeIcon.path': '../dist/svg/icon-c.svg',
  'submenu.activeIcon.name': 'icon-c',
  'submenu.iconSize.width': '32px',
  'submenu.iconSize.height': '32px',

  // submenu labels
  'submenu.normalLabel.color': '#858585',
  'submenu.normalLabel.fontWeight': 'lighter',
  'submenu.activeLabel.color': '#fff',
  'submenu.activeLabel.fontWeight': 'lighter',

  // checkbox style
  'checkbox.border': '1px solid #ccc',
  'checkbox.backgroundColor': '#fff',

  // rango style
  'range.pointer.color': '#fff',
  'range.bar.color': '#666',
  'range.subbar.color': '#d1d1d1',
  'range.value.color': '#fff',
  'range.value.fontWeight': 'lighter',
  'range.value.fontSize': '11px',
  'range.value.border': '1px solid #353535',
  'range.value.backgroundColor': '#151515',
  'range.title.color': '#fff',
  'range.title.fontWeight': 'lighter',

  // colorpicker style
  'colorpicker.button.border': '1px solid #1e1e1e',
  'colorpicker.title.color': '#fff'
  };

const PaintingForm = () => (
  <ImageEditor
    includeUI={{
      loadImage: {
        path: 'img/sampleImage.jpg',
        name: 'SampleImage',
      },
      theme: customTheme,
      menu: [
        'crop',
        'flip',
        'rotate',
        'draw',
        'shape',
        'icon',
        'text',
        'mask',
        'filter',
      ],
      initMenu: 'draw',
      uiSize: {
        width: '1000px',
        height: '700px',
      },
      menuBarPosition: 'left',
    }}
    cssMaxHeight={500}
    cssMaxWidth={700}
    selectionStyle={{
      cornerSize: 20,
      rotatingPointOffset: 70,
      cornerColor: 'blue',
      cornerStrokeColor: '#00a9ff',
      borderColor: '#00a9ff',
    }}
    usageStatistics={true}
  />
);

const PaintingPage = () => {
  return (
    <PaintingForm />
  );
};

export default PaintingPage;

Expected Behavior

I want load SVG icon.

Please help me.

image

jinwoo-kim-nhn commented 4 years ago

hi, @joongbae

If you used the webpack's file-loader as:

...
            }, {
                test: /\.svg$/,
                loader: 'file-loader',
                options: {
                    publicPath: './dist/'
                }
            },
...

You can do as follows.

import iconA from 'tui-image-editor/dist/svg/icon-a.svg';

...
...

var customTheme = {
   ...
   'submenu.normalIcon.path': iconA,
   ...

thanks.

joongbae commented 4 years ago

I have tried But the issue still remains.

import React from 'react';
import 'tui-image-editor/dist/tui-image-editor.css'
import ImageEditor from '@toast-ui/react-image-editor';
import iconA from 'tui-image-editor/dist/svg/icon-a.svg';
import iconB from 'tui-image-editor/dist/svg/icon-b.svg';
import iconC from 'tui-image-editor/dist/svg/icon-c.svg';

var customTheme = {
  'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',
  'common.bisize.width': '251px',
  'common.bisize.height': '21px',
  'common.backgroundImage': 'none',
  'common.backgroundColor': '#1e1e1e',
  'common.border': '0px',

  // header
  'header.backgroundImage': 'none',
  'header.backgroundColor': 'transparent',
  'header.border': '0px',

  // load button
  'loadButton.backgroundColor': '#fff',
  'loadButton.border': '1px solid #ddd',
  'loadButton.color': '#222',
  'loadButton.fontFamily': 'NotoSans, sans-serif',
  'loadButton.fontSize': '12px',

  // download button
  'downloadButton.backgroundColor': '#fdba3b',
  'downloadButton.border': '1px solid #fdba3b',
  'downloadButton.color': '#fff',
  'downloadButton.fontFamily': 'NotoSans, sans-serif',
  'downloadButton.fontSize': '12px',

  // main icons
  'menu.normalIcon.path': iconB,
  'menu.normalIcon.name': 'icon-b',
  'menu.activeIcon.path': iconA,
  'menu.activeIcon.name': 'icon-a',
  'menu.iconSize.width': '24px',
  'menu.iconSize.height': '24px',

  // submenu primary color
  'submenu.backgroundColor': '#1e1e1e',
  'submenu.partition.color': '#858585',

  // submenu icons
  'submenu.normalIcon.path': iconA,
  'submenu.normalIcon.name': 'icon-a',
  'submenu.activeIcon.path': iconC,
  'submenu.activeIcon.name': 'icon-c',
  'submenu.iconSize.width': '32px',
  'submenu.iconSize.height': '32px',

  // submenu labels
  'submenu.normalLabel.color': '#858585',
  'submenu.normalLabel.fontWeight': 'lighter',
  'submenu.activeLabel.color': '#fff',
  'submenu.activeLabel.fontWeight': 'lighter',

  // checkbox style
  'checkbox.border': '1px solid #ccc',
  'checkbox.backgroundColor': '#fff',

  // rango style
  'range.pointer.color': '#fff',
  'range.bar.color': '#666',
  'range.subbar.color': '#d1d1d1',
  'range.value.color': '#fff',
  'range.value.fontWeight': 'lighter',
  'range.value.fontSize': '11px',
  'range.value.border': '1px solid #353535',
  'range.value.backgroundColor': '#151515',
  'range.title.color': '#fff',
  'range.title.fontWeight': 'lighter',

  // colorpicker style
  'colorpicker.button.border': '1px solid #1e1e1e',
  'colorpicker.title.color': '#fff'
};

const PaintingForm = () => (
  <ImageEditor
    includeUI={{
      loadImage: {
        path: 'img/sampleImage.jpg',
        name: 'SampleImage',
      },
      theme: customTheme,
      menu: [
        'crop',
        'flip',
        'rotate',
        'draw',
        'shape',
        'icon',
        'text',
        'mask',
        'filter',
      ],
      initMenu: 'draw',
      uiSize: {
        width: '1000px',
        height: '700px',
      },
      menuBarPosition: 'left',
    }}
    cssMaxHeight={500}
    cssMaxWidth={700}
    selectionStyle={{
      cornerSize: 20,
      rotatingPointOffset: 70,
      cornerColor: 'blue',
      cornerStrokeColor: '#00a9ff',
      borderColor: '#00a9ff',
    }}
    usageStatistics={true}
  />
);

const PaintingPage = () => {
  return (
    <PaintingForm />
  );
};

export default PaintingPage;

Is there something I'm missing?

image

jinwoo-kim-nhn commented 4 years ago

@joongbae I think you should check this part.

theme  = {
      ...
      'menu.disabledIcon.path': iconA,
      'menu.hoverIcon.path': iconC
      ...
}
joongbae commented 4 years ago

Wow, You are a great engineer. But the download button doesn't work and I can't import the initial image.

...
loadImage: {
        path: 'img/sampleImage.jpg',
        name: 'SampleImage',
      }
...

When the download button is executed, the image will appear in a new window. Why is this?

import React from 'react';
import 'tui-image-editor/dist/tui-image-editor.css'
import ImageEditor from '@toast-ui/react-image-editor';
import iconA from 'tui-image-editor/dist/svg/icon-a.svg';
import iconB from 'tui-image-editor/dist/svg/icon-b.svg';
import iconC from 'tui-image-editor/dist/svg/icon-c.svg';

var customTheme = {
  'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',
  'common.bisize.width': '251px',
  'common.bisize.height': '21px',
  'common.backgroundImage': 'none',
  'common.backgroundColor': '#1e1e1e',
  'common.border': '0px',

  // header
  'header.backgroundImage': 'none',
  'header.backgroundColor': 'transparent',
  'header.border': '0px',

  // load button
  'loadButton.backgroundColor': '#fff',
  'loadButton.border': '1px solid #ddd',
  'loadButton.color': '#222',
  'loadButton.fontFamily': 'NotoSans, sans-serif',
  'loadButton.fontSize': '12px',

  // download button
  'downloadButton.backgroundColor': '#fdba3b',
  'downloadButton.border': '1px solid #fdba3b',
  'downloadButton.color': '#fff',
  'downloadButton.fontFamily': 'NotoSans, sans-serif',
  'downloadButton.fontSize': '12px',

  // main icons
  'menu.normalIcon.path': iconB,
  'menu.normalIcon.name': 'icon-b',
  'menu.activeIcon.path': iconA,
  'menu.activeIcon.name': 'icon-a',
  'menu.iconSize.width': '24px',
  'menu.iconSize.height': '24px',
  'menu.disabledIcon.path': iconA,
  'menu.hoverIcon.path': iconC,

  // submenu primary color
  'submenu.backgroundColor': '#1e1e1e',
  'submenu.partition.color': '#858585',

  // submenu icons
  'submenu.normalIcon.path': iconA,
  'submenu.normalIcon.name': 'icon-a',
  'submenu.activeIcon.path': iconC,
  'submenu.activeIcon.name': 'icon-c',
  'submenu.iconSize.width': '32px',
  'submenu.iconSize.height': '32px',

  // submenu labels
  'submenu.normalLabel.color': '#858585',
  'submenu.normalLabel.fontWeight': 'lighter',
  'submenu.activeLabel.color': '#fff',
  'submenu.activeLabel.fontWeight': 'lighter',

  // checkbox style
  'checkbox.border': '1px solid #ccc',
  'checkbox.backgroundColor': '#fff',

  // rango style
  'range.pointer.color': '#fff',
  'range.bar.color': '#666',
  'range.subbar.color': '#d1d1d1',
  'range.value.color': '#fff',
  'range.value.fontWeight': 'lighter',
  'range.value.fontSize': '11px',
  'range.value.border': '1px solid #353535',
  'range.value.backgroundColor': '#151515',
  'range.title.color': '#fff',
  'range.title.fontWeight': 'lighter',

  // colorpicker style
  'colorpicker.button.border': '1px solid #1e1e1e',
  'colorpicker.title.color': '#fff'
};

const PaintingForm = () => (
  <ImageEditor
    includeUI={{
      loadImage: {
        path: 'img/sampleImage.jpg',
        name: 'SampleImage',
      },
      theme: customTheme,
      menu: [
        'crop',
        'flip',
        'rotate',
        'draw',
        'shape',
        'icon',
        'text',
        'mask',
        'filter',
      ],
      initMenu: 'draw',
      uiSize: {
        width: '1000px',
        height: '900px',
      },
      menuBarPosition: 'left',
    }}
    cssMaxHeight={500}
    cssMaxWidth={700}
    selectionStyle={{
      cornerSize: 20,
      rotatingPointOffset: 70,
      cornerColor: 'blue',
      cornerStrokeColor: '#00a9ff',
      borderColor: '#00a9ff',
    }}
    usageStatistics={true}
  />
);

const PaintingPage = () => {
  return (
    <PaintingForm />
  );
};

export default PaintingPage;

image

image

jinwoo-kim-nhn commented 4 years ago

@joongbae

Please refer to this issue.

there is still a shortage in many parts, but I will improve it all.

joongbae commented 4 years ago

As a result of how you told me, I succeeded. The initial image is imported and the download button works fine. I hope this code will help others.

Thank you!!

import React from 'react';
import 'tui-image-editor/dist/tui-image-editor.css'
import ImageEditor from '@toast-ui/react-image-editor';
import iconA from 'tui-image-editor/dist/svg/icon-a.svg';
import iconB from 'tui-image-editor/dist/svg/icon-b.svg';
import iconC from 'tui-image-editor/dist/svg/icon-c.svg';
import startImg from '../img/sampleImage.jpg';
import FileSaver from 'file-saver';

var customTheme = {
  'common.bi.image': 'https://uicdn.toast.com/toastui/img/tui-image-editor-bi.png',
  'common.bisize.width': '251px',
  'common.bisize.height': '21px',
  'common.backgroundImage': 'none',
  'common.backgroundColor': '#1e1e1e',
  'common.border': '0px',

  // header
  'header.backgroundImage': 'none',
  'header.backgroundColor': 'transparent',
  'header.border': '0px',

  // load button
  'loadButton.backgroundColor': '#fff',
  'loadButton.border': '1px solid #ddd',
  'loadButton.color': '#222',
  'loadButton.fontFamily': 'NotoSans, sans-serif',
  'loadButton.fontSize': '12px',

  // download button
  'downloadButton.backgroundColor': '#fdba3b',
  'downloadButton.border': '1px solid #fdba3b',
  'downloadButton.color': '#fff',
  'downloadButton.fontFamily': 'NotoSans, sans-serif',
  'downloadButton.fontSize': '12px',

  // main icons
  'menu.normalIcon.path': iconB,
  'menu.normalIcon.name': 'icon-b',
  'menu.activeIcon.path': iconA,
  'menu.activeIcon.name': 'icon-a',
  'menu.iconSize.width': '24px',
  'menu.iconSize.height': '24px',
  'menu.disabledIcon.path': iconA,
  'menu.hoverIcon.path': iconC,

  // submenu primary color
  'submenu.backgroundColor': '#1e1e1e',
  'submenu.partition.color': '#858585',

  // submenu icons
  'submenu.normalIcon.path': iconA,
  'submenu.normalIcon.name': 'icon-a',
  'submenu.activeIcon.path': iconC,
  'submenu.activeIcon.name': 'icon-c',
  'submenu.iconSize.width': '32px',
  'submenu.iconSize.height': '32px',

  // submenu labels
  'submenu.normalLabel.color': '#858585',
  'submenu.normalLabel.fontWeight': 'lighter',
  'submenu.activeLabel.color': '#fff',
  'submenu.activeLabel.fontWeight': 'lighter',

  // checkbox style
  'checkbox.border': '1px solid #ccc',
  'checkbox.backgroundColor': '#fff',

  // rango style
  'range.pointer.color': '#fff',
  'range.bar.color': '#666',
  'range.subbar.color': '#d1d1d1',
  'range.value.color': '#fff',
  'range.value.fontWeight': 'lighter',
  'range.value.fontSize': '11px',
  'range.value.border': '1px solid #353535',
  'range.value.backgroundColor': '#151515',
  'range.title.color': '#fff',
  'range.title.fontWeight': 'lighter',

  // colorpicker style
  'colorpicker.button.border': '1px solid #1e1e1e',
  'colorpicker.title.color': '#fff'
};

const PaintingForm = () => (
  <ImageEditor
    includeUI={{
      loadImage: {
        path: startImg,
        name: 'SampleImage',
      },
      theme: customTheme,
      menu: [
        'crop',
        'flip',
        'rotate',
        'draw',
        'shape',
        'icon',
        'text',
        'mask',
        'filter',
      ],
      initMenu: 'draw',
      uiSize: {
        width: '700px',
        height: '900px',
      },
      menuBarPosition: 'bottom',
    }}
    cssMaxHeight={500}
    cssMaxWidth={700}
    selectionStyle={{
      cornerSize: 20,
      rotatingPointOffset: 70,
      cornerColor: 'blue',
      cornerStrokeColor: '#00a9ff',
      borderColor: '#00a9ff',
    }}
    usageStatistics={true}
  />
);
const onTestSaveFile = () => {
  var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
  FileSaver.saveAs(blob, "hello world.txt");
}

const PaintingPage = () => {
  return (
    <>
    <PaintingForm />
    <onTestSaveFile/>
    </>
  );
};

export default PaintingPage;