Last active
October 5, 2020 20:10
-
-
Save ljmotta/89dc701fc7f8007649a763e50b20a2ec to your computer and use it in GitHub Desktop.
Base64Png Editor examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
useEffect(() => { | |
const ctx = canvasRef.current?.getContext("2d")!; | |
ctx.filter = `invert(${invert}%)`; | |
ctx.drawImage(imageRef.current!, 0, 0); | |
setEditorContent(canvasRef.current!.toDataURL().split(",")[1]); | |
}, [invert]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const [originalContent, setOriginalContent] = useState(""); | |
const [editorContent, setEditorContent] = useState(""); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class Base64PngEditorFactory implements EditorFactory { | |
public supports(fileExtension: string) { | |
return fileExtension === "base64png"; | |
} | |
public createEditor(envelopeContext: KogitoEditorEnvelopeContextType, initArgs: EditorInitArgs) { | |
return Promise.resolve(new Base64PngEditorInterface(envelopeContext, initArgs)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const INITIAL_INVERT = "0"; | |
interface Props { | |
envelopeContext: KogitoEditorEnvelopeContextType; | |
} | |
export const Base64PngEditor = React.forwardRef<EditorApi, Props>((props, forwardedRef) => { | |
const [editorContent, setEditorContent] = useState(""); | |
const [originalContent, setOriginalContent] = useState(""); | |
const stateControl = useMemo(() => new Base64PngStateControl(), [originalContent]); | |
const getContent = useCallback(() => { | |
return editorContent; | |
}, [editorContent]); | |
const getPreview = useCallback(() => { | |
const width = imageRef.current!.width; | |
const height = imageRef.current!.height; | |
return ` | |
<svg version="1.1" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" | |
xmlns="http://www.w3.org/2000/svg" | |
xmlns:xlink="http://www.w3.org/1999/xlink"> | |
<image width="${width}" height="${height}" xlink:href="data:image/png;base64,${editorContent}" /> | |
</svg>`; | |
}, [editorContent]); | |
const setContent = useCallback((path: string, content: string) => { | |
setOriginalContent(content); | |
stateControl.clearStateControl(); | |
updateEditorToInitialState(); | |
}, [stateControl]); | |
const undo = useCallback(() => { | |
stateControl.undo(); | |
updateEditorStateWithCurrentEdit(stateControl.getCurrentBase64PngEdit()); | |
}, [stateControl]); | |
const redo = useCallback(() => { | |
stateControl.redo(); | |
updateEditorStateWithCurrentEdit(stateControl.getCurrentBase64PngEdit()); | |
}, [stateControl]); | |
const updateEditorStateWithCurrentEdit = useCallback((edit?: Base64PngEdit) => { | |
if (edit) { | |
setInvert(edit.invert); | |
} else { | |
updateEditorToInitialState(); | |
} | |
}, []); | |
const updateEditorToInitialState = useCallback(() => { | |
setInvert(INITIAL_INVERT); | |
}, []); | |
useEffect(() => { | |
props.envelopeContext.channelApi.notify("receive_ready"); | |
}, []); | |
useImperativeHandle(forwardedRef, () => { | |
return { | |
getContent: () => Promise.resolve(getContent()), | |
setContent: (path: string, content: string) => Promise.resolve(setContent(path, content)), | |
getPreview: () => Promise.resolve(getPreview()), | |
undo: () => Promise.resolve(undo()), | |
redo: () => Promise.resolve(redo()), | |
getElementPosition: (selector: string) => Promise.resolve(DEFAULT_RECT), | |
}; | |
}); | |
const imageRef = useRef<HTMLImageElement>(null); | |
const canvasRef = useRef<HTMLCanvasElement>(null); | |
const [disabled, setDisabled] = useState(true); | |
const [invert, setInvert] = useState(INITIAL_INVERT); | |
const tweakInvert = useCallback((value: string) => { | |
setInvert(value); | |
const command: Base64PngEdit = { | |
id: new Date().getTime().toString(), | |
filter: `invert(${value})`, | |
invert: value, | |
}; | |
stateControl.updateCommandStack(JSON.stringify(command)); | |
props.envelopeContext.channelApi.notify("receive_newEdit", command); | |
}, [invert, stateControl]); | |
useEffect(() => { | |
const invertId = props.envelopeContext.services.keyboardShortcuts.registerKeyPress( | |
"i", | |
`Edit | Invert Image`, | |
async () => { | |
if (!disabled && invert === "100") { | |
tweakInvert("0"); | |
} else if (!disabled && invert === "0") { | |
tweakInvert("100"); | |
} | |
} | |
); | |
return () => { | |
props.envelopeContext.services.keyboardShortcuts.deregister(invertId); | |
}; | |
}, [disabled, invert]); | |
useEffect(() => { | |
const ctx = canvasRef.current?.getContext("2d")!; | |
ctx.filter = stateControl.getCurrentBase64PngEdit()?.filter ?? `invert(${invert}%)`; | |
ctx.drawImage(imageRef.current!, 0, 0); | |
setEditorContent(canvasRef.current!.toDataURL().split(",")[1]); | |
}, [invert, stateControl]); | |
useEffect(() => { | |
const ctx = canvasRef.current?.getContext("2d")!; | |
canvasRef.current!.width = 0; | |
canvasRef.current!.height = 0; | |
imageRef.current!.onload = () => { | |
canvasRef.current!.width = imageRef.current!.width; | |
canvasRef.current!.height = imageRef.current!.height; | |
ctx.drawImage(imageRef.current!, 0, 0); | |
setEditorContent(canvasRef.current!.toDataURL().split(",")[1]); | |
setDisabled(false); | |
}; | |
return () => { | |
imageRef.current!.onload = null; | |
}; | |
}, []); | |
return ( | |
<div className={"base64png-editor--main"}> | |
<div className={"base64png-editor--viewport"}> | |
<img | |
ref={imageRef} | |
className={"base64png-editor--image"} | |
src={`data:image/png;base64,${originalContent}`} | |
alt={"Original"} | |
/> | |
{disabled && ( | |
<EmptyState> | |
<EmptyStateIcon icon={CubesIcon} /> | |
<Title headingLevel="h5" size="4xl"> | |
Empty image | |
</Title> | |
</EmptyState> | |
)} | |
<canvas ref={canvasRef} className={"base64png-editor--canvas"} /> | |
</div> | |
<div className={"base64png-editor--tweaks"}> | |
<Nav aria-label="Image tweaker"> | |
<NavList> | |
<NavItem itemId={0}> | |
<div className={"base64png-editor--tweaks-nav-item"}> | |
<p>Invert</p> | |
<Switch | |
id="invert-switch" | |
isDisabled={disabled} | |
isChecked={invert === "100"} | |
onChange={(value) => tweakInvert(value ? "100" : "0")} | |
/> | |
</div> | |
</NavItem> | |
{stateControl.isDirty() && ( | |
<div style={{ display: "flex", alignItems: "center", padding: "20px" }}> | |
<p style={{ color: "red" }}>Image was Edited!</p> | |
</div> | |
)} | |
</NavList> | |
</Nav> | |
</div> | |
</div> | |
); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Props { | |
envelopeContext: KogitoEditorEnvelopeContextType; | |
} | |
/** | |
* The forwardRef parameter is a RefForwardingComponent, which has its props and the forwardedRef which is | |
* utlized by the useImperativeHandle hook to expose the methods defined on the EditorApi type. | |
*/ | |
export const Base64PngEditor = React.forwardRef<EditorApi, Props>((props, forwardedRef) => { | |
// All the editor code is here. | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.base64png-editor--div-viewport { | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
height: 100%; | |
width: 100%; | |
} | |
.base64png-editor--image { | |
display: none; | |
} | |
.base64png-editor--canvas { | |
max-width: 600px; | |
max-height: 600px; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
return ( | |
<div className={"base64png-editor--viewport"}> | |
<img | |
ref={imageRef} | |
className={"base64png-editor--image"} | |
src={`data:image/png;base64,${originalContent}`} | |
alt={"Original"} | |
/> | |
<canvas | |
ref={canvasRef} | |
className={"base64png-editor--canvas"} | |
/> | |
</div> | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
useEffect(() => { | |
const ctx = canvasRef.current?.getContext("2d")!; | |
/** | |
* Set the initial canvas size | |
*/ | |
canvasRef.current!.width = 0; | |
canvasRef.current!.height = 0; | |
imageRef.current!.onload = () => { | |
/** | |
* Update the canvas size | |
*/ | |
canvasRef.current!.width = imageRef.current!.width; | |
canvasRef.current!.height = imageRef.current!.height; | |
/** | |
* Draw the image on the canvas | |
*/ | |
ctx.drawImage(imageRef.current!, 0, 0); | |
/** | |
* The toDataUrl() returns the base64 information in the format: "<base64 header>,<base64 data>" | |
* We just need the base64 data. | |
*/ | |
setEditorContent(canvasRef.current!.toDataURL().split(",")[1]); | |
}; | |
return () => { | |
imageRef.current!.onload = null; | |
}; | |
}, []); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
useEffect(() => { | |
const ctx = canvasRef.current?.getContext("2d")!; | |
canvasRef.current!.width = 0; | |
canvasRef.current!.height = 0; | |
imageRef.current!.onload = () => { | |
canvasRef.current!.width = imageRef.current!.width; | |
canvasRef.current!.height = imageRef.current!.height; | |
ctx.drawImage(imageRef.current!, 0, 0); | |
setEditorContent(canvasRef.current!.toDataURL().split(",")[1]); | |
/** | |
* When the image finishes to load, the tweakers can properly work | |
*/ | |
setDisabled(false); | |
}; | |
return () => { | |
imageRef.current!.onload = null; | |
}; | |
}, []); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const imageRef = useRef<HTMLImageElement>(null); | |
const canvasRef = useRef<HTMLCanvasElement>(null); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Props { | |
envelopeContext: KogitoEditorEnvelopeContextType; | |
} | |
export const Base64PngEditor = React.forwardRef<EditorApi, Props>((props, forwardedRef) => { | |
const [originalContent, setOriginalContent] = useState(""); | |
const [editorContent, setEditorContent] = useState(""); | |
const imageRef = useRef<HTMLImageElement>(null); | |
const canvasRef = useRef<HTMLCanvasElement>(null); | |
useEffect(() => { | |
props.envelopeContext.channelApi.notify("receive_ready"); | |
}, []); | |
const getContent = useCallback(() => { | |
return editorContent; | |
}, [editorContent]); | |
const getPreview = useCallback(() => { | |
const width = imageRef.current!.width; | |
const height = imageRef.current!.height; | |
return ` | |
<svg version="1.1" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" | |
xmlns="http://www.w3.org/2000/svg" | |
xmlns:xlink="http://www.w3.org/1999/xlink"> | |
<image width="${width}" height="${height}" xlink:href="data:image/png;base64,${editorContent}" /> | |
</svg>`; | |
}, [editorContent]); | |
const setContent = useCallback((path: string, content: string) => { | |
setOriginalContent(content); | |
}, []); | |
useImperativeHandle(forwardedRef, () => { | |
return { | |
getContent: () => Promise.resolve(getContent()), | |
getPreview: () => Promise.resolve(getPreview()), | |
setContent: (path: string, content: string) => Promise.resolve(setContent(path, content)), | |
undo: () => Promise.resolve(), | |
redo: () => Promise.resolve(), | |
getElementPosition: (selector: string) => Promise.resolve(DEFAULT_RECT), | |
}; | |
}); | |
useEffect(() => { | |
const ctx = canvasRef.current?.getContext("2d")!; | |
canvasRef.current!.width = 0; | |
canvasRef.current!.height = 0; | |
imageRef.current!.onload = () => { | |
canvasRef.current!.width = imageRef.current!.width; | |
canvasRef.current!.height = imageRef.current!.height; | |
ctx.drawImage(imageRef.current!, 0, 0); | |
setEditorContent(canvasRef.current!.toDataURL().split(",")[1]); | |
}; | |
return () => { | |
imageRef.current!.onload = null; | |
}; | |
}, []); | |
return ( | |
<div className={"base64png-editor--viewport"}> | |
<img | |
ref={imageRef} | |
className={"base64png-editor--image"} | |
src={`data:image/png;base64,${originalContent}`} | |
alt={"Original"} | |
/> | |
<canvas ref={canvasRef} className={"base64png-editor--canvas"} /> | |
</div> | |
); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class Base64PngEditorInterface implements Editor { | |
/** | |
* The Editor ref so its possible to access its methods imperactivily | |
*/ | |
private editorRef: React.RefObject<EditorApi>; | |
/** | |
* Additional information used by the Channel. | |
*/ | |
public af_isReact = true; | |
public af_componentId: "base64png-editor"; | |
public af_componentTitle: "Base64 PNG Editor"; | |
constructor( | |
private readonly envelopeContext: KogitoEditorEnvelopeContextType, | |
private readonly initArgs: EditorInitArgs | |
) { | |
this.editorRef = React.createRef<EditorApi>(); | |
} | |
/** | |
* Retrieve the Editor content. | |
*/ | |
public getContent(): Promise<string> { | |
return this.editorRef.current?.getContent()!; | |
} | |
/** | |
* Retrieve the Guided Tour current position. The Editor implements a getElementPosition method, but it always return a | |
* the DEFAULT_RECT because the Editor dosn't support a Guided Tour. | |
*/ | |
public getElementPosition(selector: string): Promise<Rect | undefined> { | |
return this.editorRef.current?.getElementPosition(selector)!; | |
} | |
/** | |
* Set the Editor content. | |
* @param path The file path that is being open. | |
* @param content The file content in a string format. | |
*/ | |
public setContent(path: string, content: string): Promise<void> { | |
return this.editorRef.current?.setContent(path, content)!; | |
} | |
/** | |
* Get the content preview which is a SVG. | |
*/ | |
public getPreview(): Promise<string | undefined> { | |
return this.editorRef.current?.getPreview()!; | |
} | |
/** | |
* Calls the Editor undo method. | |
*/ | |
public undo(): Promise<void> { | |
return this.editorRef.current?.undo()!; | |
} | |
/** | |
* Calls the Editor redo method. | |
*/ | |
public redo(): Promise<void> { | |
return this.editorRef.current?.redo()!; | |
} | |
/** | |
* Retrieve the root component of the Editor. Here the Editor is going to be initialized with its props. | |
*/ | |
public af_componentRoot() { | |
return <Base64PngEditor ref={this.editorRef} envelopeContext={this.envelopeContext} />; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Props { | |
envelopeContext: KogitoEditorEnvelopeContextType; | |
} | |
export const Base64PngEditor = React.forwardRef<EditorApi, Props>((props, forwardedRef) => { | |
const [originalContent, setOriginalContent] = useState(""); | |
const [editorContent, setEditorContent] = useState(""); | |
const imageRef = useRef<HTMLImageElement>(null); | |
const canvasRef = useRef<HTMLCanvasElement>(null); | |
useEffect(() => { | |
props.envelopeContext.channelApi.notify("receive_ready"); | |
}, []); | |
const getContent = useCallback(() => { | |
return editorContent; | |
}, [editorContent]); | |
const getPreview = useCallback(() => { | |
const width = imageRef.current!.width; | |
const height = imageRef.current!.height; | |
return ` | |
<svg version="1.1" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" | |
xmlns="http://www.w3.org/2000/svg" | |
xmlns:xlink="http://www.w3.org/1999/xlink"> | |
<image width="${width}" height="${height}" xlink:href="data:image/png;base64,${editorContent}" /> | |
</svg>`; | |
}, [editorContent]); | |
const setContent = useCallback((path: string, content: string) => { | |
setOriginalContent(content); | |
}, []); | |
useImperativeHandle(forwardedRef, () => { | |
return { | |
getContent: () => Promise.resolve(getContent()), | |
getPreview: () => Promise.resolve(getPreview()), | |
setContent: (path: string, content: string) => Promise.resolve(setContent(path, content)), | |
undo: () => Promise.resolve(), | |
redo: () => Promise.resolve(), | |
getElementPosition: (selector: string) => Promise.resolve(DEFAULT_RECT), | |
}; | |
}); | |
const [disabled, setDisabled] = useState(true); | |
const [invert, setInvert] = useState("0"); | |
const tweakInvert = useCallback((value: string) => { | |
setInvert(value); | |
props.envelopeContext.channelApi.notify("receive_newEdit", { id: new Date().getTime().toString() }); | |
}, [invert]); | |
useEffect(() => { | |
const ctx = canvasRef.current?.getContext("2d")!; | |
ctx.filter = `invert(${invert}%)`; | |
ctx.drawImage(imageRef.current!, 0, 0); | |
setEditorContent(canvasRef.current!.toDataURL().split(",")[1]); | |
}, [invert]); | |
useEffect(() => { | |
const ctx = canvasRef.current?.getContext("2d")!; | |
canvasRef.current!.width = 0; | |
canvasRef.current!.height = 0; | |
imageRef.current!.onload = () => { | |
canvasRef.current!.width = imageRef.current!.width; | |
canvasRef.current!.height = imageRef.current!.height; | |
ctx.drawImage(imageRef.current!, 0, 0); | |
setEditorContent(canvasRef.current!.toDataURL().split(",")[1]); | |
setDisabled(false); | |
}; | |
return () => { | |
imageRef.current!.onload = null; | |
}; | |
}, []); | |
return ( | |
<Page className={"base64png-editor--page"}> | |
<div className={"base64png-editor--main"}> | |
<div className={"base64png-editor--viewport"}> | |
<img | |
ref={imageRef} | |
className={"base64png-editor--image"} | |
src={`data:image/png;base64,${originalContent}`} | |
alt={"Original"} | |
/> | |
{disabled && ( | |
<EmptyState> | |
<EmptyStateIcon icon={CubesIcon} /> | |
<Title headingLevel="h5" size="4xl"> | |
Empty image | |
</Title> | |
</EmptyState> | |
)} | |
<canvas ref={canvasRef} className={"base64png-editor--canvas"} /> | |
</div> | |
<div className={"base64png-editor--tweaks"}> | |
<Nav aria-label="Image tweaker"> | |
<NavList> | |
<NavItem itemId={0}> | |
<div className={"base64png-editor--tweaks-nav-item"}> | |
<p>Invert</p> | |
<Switch | |
id="invert-switch" | |
isDisabled={disabled} | |
isChecked={invert === "100"} | |
onChange={(value) => tweakInvert(value ? "100" : "0")} | |
/> | |
</div> | |
</NavItem> | |
</NavList> | |
</Nav> | |
</div> | |
</div> | |
</Page> | |
); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
return ( | |
<div className={"base64png-editor--main"}> | |
<div className={"base64png-editor--viewport"}> | |
<img | |
ref={imageRef} | |
className={"base64png-editor--image"} | |
src={`data:image/png;base64,${originalContent}`} | |
alt={"Original"} | |
/> | |
{disabled && ( | |
<EmptyState> | |
<EmptyStateIcon icon={CubesIcon} /> | |
<Title headingLevel="h5" size="4xl"> | |
Empty image | |
</Title> | |
</EmptyState> | |
)} | |
<canvas ref={canvasRef} className={"base64png-editor--canvas"} /> | |
</div> | |
<div className={"base64png-editor--tweaks"}> | |
<Nav aria-label="Image tweaker"> | |
<NavList> | |
<NavItem itemId={0}> | |
<div className={"base64png-editor--tweaks-nav-item"}> | |
<p>Invert</p> | |
<Switch | |
id="invert-switch" | |
isDisabled={disabled} | |
isChecked={invert === "100"} | |
onChange={(value) => tweakInvert(value ? "100" : "0")} | |
/> | |
</div> | |
</NavItem> | |
</NavList> | |
</Nav> | |
</div> | |
</div> | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const [invert, setInvert] = useState("0"); | |
const tweakInvert = useCallback((value: string) => { | |
setInvert(value); | |
props.envelopeContext.channelApi.notify("receive_newEdit", { id: new Date().getTime().toString() }); | |
}, [invert]); | |
const [disabled, setDisabled] = useState(true); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
useEffect(() => { | |
const invertId = props.envelopeContext.services.keyboardShortcuts.registerKeyPress( | |
"i", | |
`Edit | Invert Image`, | |
async () => { | |
if (!disabled && invert === "100") { | |
tweakInvert("0"); | |
} else if (!disabled && invert === "0") { | |
tweakInvert("100"); | |
} | |
} | |
); | |
return () => { | |
props.envelopeContext.services.keyboardShortcuts.deregister(invertId); | |
}; | |
}, [disabled, invert]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
useEffect(() => { | |
props.envelopeContext.channelApi.notifications.receive_ready(); | |
}, []); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const getContent = useCallback(() => { | |
return editorContent; | |
}, [editorContent]); | |
const getPreview = useCallback(() => { | |
const width = imageRef.current!.width; | |
const height = imageRef.current!.height; | |
return ` | |
<svg version="1.1" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" | |
xmlns="http://www.w3.org/2000/svg" | |
xmlns:xlink="http://www.w3.org/1999/xlink"> | |
<image width="${width}" height="${height}" xlink:href="data:image/png;base64,${editorContent}" /> | |
</svg>`; | |
}, [editorContent]); | |
const setContent = useCallback((path: string, content: string) => { | |
setOriginalContent(content); | |
}, []); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { StateControl } from "@kogito-tooling/editor/dist/embedded"; | |
import { KogitoEdit } from "@kogito-tooling/channel-common-api"; | |
export interface Base64PngEdit extends KogitoEdit { | |
id: string; | |
filter: string; | |
invert: string; | |
} | |
export class Base64PngStateControl extends StateControl { | |
/** | |
* The command stack on the Kogito State Control accepts only strings, this method parses the string into a Base64PngEdit object. | |
*/ | |
getCurrentBase64PngEdit(): Base64PngEdit | undefined { | |
const command = super.getCurrentCommand(); | |
if (command) { | |
return JSON.parse(command) as Base64PngEdit; | |
} | |
return; | |
} | |
clearStateControl() { | |
super.setCurrentCommand(undefined); | |
super.setCommandStack([]); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Added on the end of the NavList an isDirty indicator. | |
*/ | |
<NavItem itemId={0}> | |
<div className={"base64png-editor--tweaks-nav-item"}> | |
<p>Invert</p> | |
<Switch | |
id="invert-switch" | |
isDisabled={disabled} | |
isChecked={invert === "100"} | |
onChange={(value) => tweakInvert(value ? "100" : "0")} | |
/> | |
</div> | |
</NavItem> | |
{stateControl.isDirty() && ( | |
<div style={{ display: "flex", alignItems: "center", padding: "20px" }}> | |
<p style={{ color: "red" }}>Image was Edited!</p> | |
</div> | |
)} | |
</NavList> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Clear the state control stack, and rollback the Editor tweak states to the initial values. | |
*/ | |
const setContent = useCallback((path: string, content: string) => { | |
setOriginalContent(content); | |
stateControl.clearStateControl(); | |
updateEditorToInitialState(); | |
}, [stateControl]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const stateControl = useMemo(() => new Base64PngStateControl(), [originalContent]); | |
const undo = useCallback(() => { | |
stateControl.undo(); | |
updateEditorStateWithCurrentEdit(stateControl.getCurrentBase64PngEdit()); | |
}, [stateControl]); | |
const redo = useCallback(() => { | |
stateControl.redo(); | |
updateEditorStateWithCurrentEdit(stateControl.getCurrentBase64PngEdit()); | |
}, [stateControl]); | |
const updateEditorStateWithCurrentEdit = useCallback((edit?: Base64PngEdit) => { | |
if (edit) { | |
setInvert(edit.invert); | |
} else { | |
updateEditorToInitialState(); | |
} | |
}, []); | |
const updateEditorToInitialState = useCallback(() => { | |
setInvert(INITIAL_INVERT); | |
}, []); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Create a Base64PngEdit and update the state control stack with it. We've updated the receive_newEdit notification with the Base64Edit in case the needs any additional information. | |
*/ | |
const tweakInvert = useCallback((value: string) => { | |
setInvert(value); | |
const command: Base64PngEdit = { | |
id: new Date().getTime().toString(), | |
filter: `invert(${value})`, | |
invert: value, | |
}; | |
stateControl.updateCommandStack(JSON.stringify(command)); | |
props.envelopeContext.channelApi.notify("receive_newEdit", command); | |
}, [invert, stateControl]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Preferable use the state control current edit values. | |
*/ | |
useEffect(() => { | |
const ctx = canvasRef.current?.getContext("2d")!; | |
ctx.filter = stateControl.getCurrentBase64PngEdit()?.filter ?? `invert(${invert}%)`; | |
ctx.drawImage(imageRef.current!, 0, 0); | |
setEditorContent(canvasRef.current!.toDataURL().split(",")[1]); | |
}, [invert, stateControl]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
useImperativeHandle(forwardedRef, () => { | |
return { | |
/** | |
* We are going to pass through on each of the method here. | |
*/ | |
getContent: () => Promise.resolve(getContent()), | |
getPreview: () => Promise.resolve(getPreview()), | |
setContent: (path: string, content: string) => Promise.resolve(setContent(path, content)), | |
/** | |
* We're going to implement this methods further in the tutorial | |
*/ | |
undo: () => Promise.resolve(), | |
redo: () => Promise.resolve(), | |
/** | |
* This method is not going to be implemented on this example, so it always resolve a DEFAULT_RECT. | |
*/ | |
getElementPosition: (selector: string) => Promise.resolve(DEFAULT_RECT), | |
}; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment