README
GFX Editor
Canvas editor using Fabricjs. Available as a React component and in VanillaJS
Installation and usage
🚧 Coming soon 🚧
Storybook development
Run:
npm install
npm run storybook
How to use it
This is an example of how we want it to be used. This is not the current functionality.
import { useRef, useState } from 'react';
function App() {
const ref = useRef();
const [selectedObj, setSelectedObject] = useState();
const someCallback = () => {
ref.addImage(url) // local images are saved to the db and the s3 url is added to designs
ref.addTextbox()
ref.updateObject(obj);
// Zoom & Scale
ref.zoomIn()
ref.zoomOut()
ref.zoom(2) // or ref.scale()
console.log(ref.currentScale);
// Rotate objects
ref.selectedObject.rotate()
ref.selectedObject.rotate(45)
// Align objects
ref.selectedObject.align('left' | 'right' | 'center')
}
return (
<>
<Editor
width={width}
height={height}
template={template}
initialDesign={design} // Or designTemplate
onChange={(design: DesignJson, action: ActionType) => {
switch (action.type) {
case('BACKGROUND_REMOVED'):
console.log(`Background removed from image ${action.payload.src}`)
break;
default:
break;
}
saveDesign(design);
}}
onObjectSelected={(obj: Object) => {
setObject(obj);
}}
{/*
Someday we can specify which extension we need?
OR really the necessary extensions should be determined by the
design
*/}
config={{
// Theme stuff.
fabricCustomControls: {
settings: {
borderColor,
cornerSize,
cornerShape,
cornerBackgroundColor,
cornerPadding,
},
tl: {
icon: rotateIcon,
},
tr: {
icon: resizeIcon,
},
},
}}
ref={ref}
/>
{
selectedObj
&& renderCustomToolbar(selectedObj) // Only some selected objects warrant custom toolbars
|| (
<CoolToolbar>
<AddImage onImageAdded={addImage} />
<AddTextbox onTextboxAdded={addTextbox} />
</CoolToolbar>
)
}
</>
)
}
After planning
Canvas
- add-image.ts
- add-slot.ts
- add-text.ts
- canvas-editor.ts
- change-theme.ts
- clear.ts
- clone.ts
- cycle-zoom-stage.ts
- flash-slots.ts [Daniel]
- get-art.ts [Morgan]
- get-screenshot.ts
- hide-quick-actions.ts [Daniel]
- is-dirty.ts
- load-from-json.ts
- remove-flash-slots.ts
- remove-unused-elements.ts
- set-image-resolution.ts
- set-objects-coords.ts
- set-size.spec.ts
- set-size.ts [Morgan]
- set-zoom-cycle.ts
- set-zoom-cycle-stage.ts
- show-quick-actions.ts
- stop-animation.ts
- to-json.ts
Object extensions
- align
- rotate
- scale
- add-tag.ts
- has-tag.ts
- remove-tag.ts
- scale-to-printable-area.ts
To do
- Do we need babel.config.js?
- Do we need rollup.config.js?
Other
- Make default configuration for FabricCanvas component
- Everything that needs a story. From Daniel. With features and options to toggle.
- For EditorCanvas
- Example: A button that highlights slots
- and EditorUI
- And components of shirt-app-mobile that can be moved to EditorCanvas
Examples
- Shopify
- With editor buttons inside the iframe (easy mode)
- With editor buttons outside of iframe (advanced/custom)
- GFX Storefront
- With editor buttons inside the iframe (easy mode)
- With editor buttons outside of iframe (advanced/custom)
From shopify theme
- Generate modal to alert user of supported browsers
<script
async
src="{`http://localhost:3002/api/embed?id=${CHANNEL_ID}`}"
/>
<script>
window.GFXInstance({
productId: document.getElementById('').attribute('data-shopify-product-id'),
channelId: 12435,
uiTheme: 'default' // What warrants a new theme? It has to be structurally different?
// This css 👇 is an override
css: `
.gfx--AddToCart {
}
`,
// This comes from db and managed in admin UI
// This IS part of the API for now
customStyles: {
addToCart: `
padding: 4px;
margin: 4px;
width: 300px;
`
},
}, document.getElementById('gfx-container'))
</script>
<div id="gfx" />
import styled from 'styled-components'
const StyledDiv = styled.div`
padding: 2px;
margin: 4px;
width: 200px;
${({ theme: { AddToCart }}) => AddToCart}
`
const AddToCart = () => {
<StyledDiv>
<button>
Add to Cart
</button>
</StyledDiv>
}
- Integration with window.GFX and snippet and we provide all UI
- Use window.GFX and snippet but with additional customization via listeners, actions, and dom attachments.
- Use
@gfx/editor
which is kind of the IFrame component. And you use listeners, actions via React api
import {
Editor, // IFrame
BlankEditor, // Instead of a param to hide UI
Zoom,
Flip,
ChangeColorButton,
AddImage,
} from '@gfx/editor'
GFX components
We need to have components to use flexibly. We need to not worry about the editor. Communicating with the editor. Style it how you want it. Put it where you want it. Themeable integrations.
Question
- We have a library of components. Editor is one of them.
- The IFrame can have everything put together.
- Should we NOT use an iframe. We will manage all GFX storefronts. We can manage DNS, CORS issues, analytics and third-party plugins.
Notes from 1/19/21
To do
- Use clipPath in setArea to put printable image over and under canvas [Daniel/Morgan]
- Make canvas fill container. Use a div in FabricCanvas. Make canvas fill that.
- Move addResizeEvent to a react hook (with addListener in useEffect) used in GFXCanvas [Morgan/Daniel]
- Put addGestures in hook and maybe use new fabric methods. [Daniel]
- Upgrading fabric means rewriting fabricCustomControls... [Daniel]
- Put an icon on custom controls to remove bg?
- Edit text in place! How do we moderate the text? Does fabric provide that capability? Easily?... Do we write our own extension