polotno-project / polotno-board

Roadmap and bug-tracker for the Polotno project.
https://polotno.dev/
9 stars 1 forks source link

Problem rendering Polotno Toolbar #11

Closed antoine-zurcher closed 3 years ago

antoine-zurcher commented 3 years ago

Hi,

I am currently implementing the polotno package to build a canvas editor. I am initially using the Dash library in Python to create my web app, which has the possibility to create custom React components in JavaScript such as the polotno canvas. My problem comes from the fact that the toolbar does not render correctly on the web app. Here is a screenshot of it: Capture1

There is also another render problem which happens when I try to click on a button (for example Export) from the toolbar which tries to open a pop-up. Capture2

This problem might be due to the fact that I am not using the last version of polotno, since polotno@0.17.0 works with React 17 or higher however the Dash library in Python works with React 16 which resulted in a version mismatch and produced this error https://github.com/konvajs/react-konva/issues/171. So I decided to use polotno@0.3.0 which is the lastest version of polotno working with React 16. Does this problem come from the version of polotno or is something wrong with my layout ?

Here is the render function I am using to generate the canvas:

import PropTypes from 'prop-types';
import { createStore } from 'polotno/model/store';
import Toolbar from 'polotno/toolbar/toolbar';
import ZoomButtons from 'polotno/toolbar/zoom-buttons';
import SidePanel from 'polotno/side-panel/side-panel';
import Workspace from 'polotno/canvas/workspace';

export default class UIEditor extends Component {
    render() {
        const {id, label, setProps, value} = this.props;
        const store = createStore({
          key: MY-KEY, 
        });
        store.setSize({ width: 600, height: 1000 });
        const page = store.addPage({
            background: 'white',
        });
        page.addElement({
            type: 'text',
            x: 350,
            y: 200,
            locked: false,
            text: 'Header',
            placeholder: '',
            fontSize: 40,
            fontFamily: 'Roboto',
            fontStyle: 'normal', // can be normal or italic
            fontWeight: 'normal', // can be normal or bold or some other CSS variations
            textDecoration: '',
            fill: 'black',
            align: 'center',
            width: 300,
            strokeWidth: 0,
            stroke: 'black',
            lineHeight: 1,
            letterSpacing: 0, // % from font size
        });
        page.addElement({
            type: 'text',
            x: 250,
            y: 400,
            locked: false,
            text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
            placeholder: '',
            fontSize: 14,
            fontFamily: 'Roboto',
            fontStyle: 'normal', // can be normal or italic
            fontWeight: 'normal', // can be normal or bold or some other CSS variations
            textDecoration: '',
            fill: 'black',
            align: 'center',
            width: 500,
            strokeWidth: 0,
            stroke: 'black',
            lineHeight: 1,
            letterSpacing: 0, // % from font size
        });
        return (
            <div
              style={{
                display: 'flex',
                height: '100%',
                width: '100%',
                maxHeight: '90vh',
              }}
            >
              <div style={{ width: '300px', height: '90vh', display: 'flex' }}>
                <SidePanel store={store} />
              </div>
              <div
                style={{
                  display: 'flex',
                  height: '90vh',
                  margin: 'auto',
                  flex: 1,
                  flexDirection: 'column',
                  position: 'relative',
                }}
              >
                <Toolbar store={store} />
                <Workspace store={store} />
                <ZoomButtons store={store} />
              </div>
            </div>

        );
    }
}

Here is my package JSON:

  "name": "dash_react",
  "version": "0.0.1",
  "description": "Component to edit the layout of a user interface",
  "main": "build/index.js",
  "scripts": {
    "start": "webpack-serve --config ./webpack.serve.config.js --open",
    "validate-init": "python _validate_init.py",
    "prepublishOnly": "npm run validate-init",
    "build:js": "webpack --mode production",
    "build:backends": "dash-generate-components ./src/lib/components dash_react -p package-info.json --r-prefix '' --jl-prefix ''",
    "build:backends-activated": "(. venv/bin/activate || venv\\scripts\\activate && npm run build:py_and_r)",
    "build": "npm run build:js && npm run build:backends",
    "build:activated": "npm run build:js && npm run build:backends-activated"
  },
  "author": "",
  "license": "MIT",
  "dependencies": {
    "polotno": "^0.3.0",
    "ramda": "^0.26.1"
  },
  "devDependencies": {
    "@babel/core": "^7.5.4",
    "@babel/plugin-proposal-object-rest-spread": "^7.5.4",
    "@babel/preset-env": "^7.5.4",
    "@babel/preset-react": "^7.0.0",
    "babel-eslint": "^10.0.2",
    "babel-loader": "^8.0.6",
    "copyfiles": "^2.1.1",
    "css-loader": "^3.0.0",
    "eslint": "^6.0.1",
    "eslint-config-prettier": "^6.0.0",
    "eslint-plugin-import": "^2.18.0",
    "eslint-plugin-react": "^7.14.2",
    "npm": "^6.1.0",
    "prop-types": "^15.7.2",
    "react": "^16.13.1",
    "react-docgen": "^4.1.1",
    "react-dom": "^16.13.1",
    "style-loader": "^0.23.1",
    "styled-jsx": "^3.2.1",
    "webpack": "4.36.1",
    "webpack-cli": "3.3.6",
    "webpack-serve": "3.1.0"
  },
  "engines": {
    "node": ">=8.11.0",
    "npm": ">=6.1.0"
  }
}
lavrton commented 3 years ago

Looks like you didn't add blueprint styles into the page:

<link
  href="https://unpkg.com/@blueprintjs/icons@^3.4.0/lib/css/blueprint-icons.css"
  rel="stylesheet"
/>
<link
  href="https://unpkg.com/@blueprintjs/core@^3.10.0/lib/css/blueprint.css"
  rel="stylesheet"
/>

however the Dash library in Python works with React 16

Are you sure it doesn't work with React 17? I strongly recommend updating React version. If you can't do that. Wait for the next polotno release. Probably it will work with the older React version.

antoine-zurcher commented 3 years ago
https://unpkg.com/@blueprintjs/core@^3.10.0/lib/css/blueprint.css

Thanks a lot! The blueprint styles were indeed missing.

I had another question: right now I can click on an element from the sidepanel and it appears on the workspace, however I cannot drag and drop the element from the sidepanel to the workspace. Was this feature not implemented in polotno@0.3.0 or am I missing something else in the code ?

lavrton commented 3 years ago

I tried the last polotno@0.18.0 with react@16. And looks like it works ok: https://yi1v5.csb.app/

lavrton commented 3 years ago

Was this feature not implemented in polotno@0.3.0 or am I missing something else in the code ?

Probably it is not. It is an old version. It is better to update asap.

antoine-zurcher commented 3 years ago

Alright, thanks for the infos!

antoine-zurcher commented 3 years ago

I tried the last polotno@0.18.0 with react@16. And looks like it works ok: https://yi1v5.csb.app/

May I see the versions from the package JSON that you used for this demo ?

lavrton commented 3 years ago

https://codesandbox.io/s/yi1v5?file=/package.json