Last active
May 29, 2019 07:34
-
-
Save Deraen/0dd99e0157fd8119ac6b3557ff11fa2c to your computer and use it in GitHub Desktop.
React Konva example with Reagent
This file contains hidden or 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
(ns example.react-konva-image | |
(:require [reagent.core :as r] | |
;; This presumes Shadow-cljs (or cljsjs packages with correct definitions) | |
[react-konva :refer [Stage Layer Image]] | |
[use-image :as use-image])) | |
(defn lion-image [] | |
(let [[image] (use-image "https://konvajs.org/assets/lion.png")] | |
(r/as-element [:> Image {:image image}]))) | |
;; or, without Reagent hiccup -> React elements step, directly creating React element: | |
(r/create-element Image #js {:image image}) | |
(defn url-image [_] | |
(let [image (r/atom nil) | |
loaded (r/atom false) | |
handle-load (fn [] | |
(reset! loaded true)) | |
load-image (fn [src] | |
(let [i (new js/window.Image)] | |
(reset! image i) | |
(set! (.-src i) src) | |
(.addEventListener i "load" handle-load))) | |
;; Unused | |
image-node (atom nil) | |
ref-fn #(reset! image-node %)] | |
(r/create-class | |
{:component-did-mount (fn [this] (load-image (:src (r/props this)))) | |
:component-did-update (fn [this [_ old-props]] | |
(if (not= (:src old-props) (:src (r/props this))) | |
(load-image (:src (r/props this))))) | |
:component-will-unmount (fn [this] | |
(.removeEventListener @image "load" handle-load)) | |
:reagent-render (fn [{:keys [x y]}] | |
(if @loaded | |
[:> Image | |
{:x x | |
:y y | |
:image @image | |
:ref ref-fn}]))}))) | |
(defn app [] | |
[:> Stage | |
{:width (.-innerWidth js/window) | |
:height (.-innerHeight js/window)} | |
[:> Layer | |
[url-image {:src "https://konvajs.org/assets/yoda.jpg" x: 150}] | |
;; Use as React component! | |
[:> lion-image]]]) |
This file contains hidden or 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 React, { Component } from 'react'; | |
import { render } from 'react-dom'; | |
import { Stage, Layer, Image } from 'react-konva'; | |
import useImage from 'use-image'; | |
// the first very simple and recommended way: | |
const LionImage = () => { | |
const [image] = useImage('https://konvajs.org/assets/lion.png'); | |
return <Image image={image} />; | |
}; | |
// custom component that will handle loading image from url | |
// you may add more logic here to handle "loading" state | |
// or if loading is failed | |
// VERY IMPORTANT NOTES: | |
// at first we will set image state to null | |
// and then we will set it to native image instance when it is loaded | |
class URLImage extends React.Component { | |
state = { | |
image: null | |
}; | |
componentDidMount() { | |
this.loadImage(); | |
} | |
componentDidUpdate(oldProps) { | |
if (oldProps.src !== this.props.src) { | |
this.loadImage(); | |
} | |
} | |
componentWillUnmount() { | |
this.image.removeEventListener('load', this.handleLoad); | |
} | |
loadImage() { | |
// save to "this" to remove "load" handler on unmount | |
this.image = new window.Image(); | |
this.image.src = this.props.src; | |
this.image.addEventListener('load', this.handleLoad); | |
} | |
handleLoad = () => { | |
// after setState react-konva will update canvas and redraw the layer | |
// because "image" property is changed | |
this.setState({ | |
image: this.image | |
}); | |
// if you keep same image object during source updates | |
// you will have to update layer manually: | |
// this.imageNode.getLayer().batchDraw(); | |
}; | |
render() { | |
return ( | |
<Image | |
x={this.props.x} | |
y={this.props.y} | |
image={this.state.image} | |
ref={node => { | |
this.imageNode = node; | |
}} | |
/> | |
); | |
} | |
} | |
class App extends Component { | |
render() { | |
return ( | |
<Stage width={window.innerWidth} height={window.innerHeight}> | |
<Layer> | |
<URLImage src="https://konvajs.org/assets/yoda.jpg" x={150} /> | |
<LionImage /> | |
</Layer> | |
</Stage> | |
); | |
} | |
} | |
render(<App />, document.getElementById('root')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment