Toolbar
is a UI components to change elements on the canvas, reorder and align them, apply undo/redo.
Basic usage:
import Toolbar from 'polotno/toolbar/toolbar';
import Workspace from 'polotno/canvas/workspace';
const App = ({ store }) => {
return (
<div
style={{
display: 'flex',
height: '100%',
margin: 'auto',
flex: 1,
flexDirection: 'column',
position: 'relative',
}}
>
<Toolbar store={store} />
<Workspace store={store} />
</div>
);
};
Also Toolbar
component has additional properties to hide some elements and overwrite inputs for some properties.
type ToolbarProps = {
store: StoreType,
downloadButtonEnabled?: Boolean,
components?: any,
};
<Toolbar store={store} downloadButtonEnabled />;
How to overwrite available inputs for an element type?
Toolbar supports special components
property to add/change/remove most of its UI components.
In some application you may want to change available properties for selected element type. E.g. you may want to display a different color picker for text
element. Just pass a component in format TypeName
e.g. TextFill
. You can use all built-element types as Text
, Image
, Svg
. But also you can use Many
prefix when several elements are selected. Also you can define your own new components for any element type. E.g. ImageAlertButton
There are several built-in components but also you can add your own.
text element:
TextFontFamily
TextFontSize
TextFontVariant
TextFilters
TextFill
TextSpacing
TextAnimations
TextAiWrite
image elements
ImageFlip
ImageFilters
ImageFitToBackground
ImageCrop
ImageClip
ImageRemoveBackground
ImageAnimations
svg element:
SvgFlip
SvgFilters
SvgColors
SvgAnimations
line element:
LineSettings
LineColor
LineHeads
LineAnimations
figure element:
FigureFill
FigureStroke
FigureSettings
FigureFilters
FigureAnimations
video element:
VideoTrim
VideoAnimations
many elements selected:
ManyAnimations
page (no elements selected):
PageDuration
common:
History
Group
Position
Opacity
Lock
Duplicate
Remove
import Toolbar from 'polotno/toolbar/toolbar';
import Workspace from 'polotno/canvas/workspace';
import { observer } from 'mobx-react-lite';
const MyColorPicker = observer(({ store, element, elements }) => {
return (
<div>
<input
type="color"
value={element.fill}
onChange={(e) => {
element.set({
fill: e.target.value,
});
}}
/>
</div>
);
});
const TextTextFontSize = () => null;
const TextAlertButton = observer(({ store, element, elements }) => {
return (
<button
onClick={() => {
alert('Hello!');
}}
>
Alert
</button>
);
});
const History = () => null;
const App = ({ store }) => {
return (
<div
style={{
display: 'flex',
height: '100%',
margin: 'auto',
flex: 1,
flexDirection: 'column',
position: 'relative',
}}
>
<Toolbar
store={store}
components={{
TextFill: MyColorPicker,
TextTextFontSize,
TextAlertButton,
History,
}}
/>
<Workspace store={store} />
</div>
);
};
How to overwrite all inputs at once?
Following Custom Element Example, you can make your own React component for any available element.
Recommendation: leverage blueprintjs
components to build your own UI and use <Navbar.Group>
to group inputs. Also remember to wrap your component in observer
from mobx-react-lite
library to add automatic reactivity of your components.
Example:
import React from 'react';
import { observer } from 'mobx-react-lite';
import { NumericInput, Navbar, Alignment } from '@blueprintjs/core';
import ColorPicker from 'polotno/toolbar/color-picker';
import { unstable_registerToolbarComponent } from 'polotno/config';
const TextToolbar = observer(({ store }) => {
const element = store.selectedElements[0];
return (
<Navbar.Group align={Alignment.LEFT}>
<ColorPicker
value={element.fill}
onChange={(fill) =>
element.set({
fill,
})
}
store={store}
/>
<NumericInput
onValueChange={(fontSize) => {
element.set({ fontSize: fontSize });
}}
value={element.fontSize}
style={{ width: '50px', marginLeft: '10px' }}
min={1}
max={40}
/>
</Navbar.Group>
);
});
unstable_registerToolbarComponent('text', TextToolbar);
How to overwrite 'Download; button
On the right side of the toolbar, Polotno has 'Action Controls' section. You can use components
prop to overwrite this section.
Recommendation: keep 'Action Controls' as small as possible. <Toolbar />
component already has a lot of tools. So it is better give it as much available width as possible. You can put 'Action Controls" somewhere else in the UI of your application. For example, take a look into https://studio.polotno.com/. Download button is placed on the top of the app instead of the <Toolbar />
.
import { Toolbar } from 'polotno/toolbar/toolbar';
import { Button } from '@blueprintjs/core';
import { DownloadButton } from 'polotno/toolbar/download-button';
const ActionControls = ({ store }) => {
return (
<div>
<DownloadButton store={store} />
<Button
intent="primary"
onClick={() => {
alert('Saving');
}}
>
Save
</Button>
</div>
);
};
const MyToolbar = ({ store }) => {
return (
<Toolbar
store={store}
components={{
ActionControls,
}}
/>
);
};