1
+ import * as React from "react"
2
+ import { canvasEvent } from "../svg/frameFunctions"
3
+
4
+ type InteractionCanvasProps = {
5
+ height : number ,
6
+ width : number ,
7
+ overlayRegions : any ,
8
+ margin : any ,
9
+ voronoiHover : Function
10
+ }
11
+
12
+ type InteractionCanvasState = {
13
+ ref : any ,
14
+ interactionContext : any ,
15
+ overlayRegions : any ,
16
+ margin : any
17
+ }
18
+
19
+ class InteractionCanvas extends React . Component < InteractionCanvasProps , InteractionCanvasState > {
20
+ constructor ( props : InteractionCanvasProps ) {
21
+ super ( props )
22
+
23
+ const {
24
+ overlayRegions,
25
+ margin } = props
26
+
27
+ this . state = {
28
+ ref : null ,
29
+ interactionContext : null ,
30
+ overlayRegions,
31
+ margin
32
+ }
33
+ }
34
+
35
+ canvasMap : Map < string , number > = new Map ( )
36
+
37
+ componentDidMount ( ) {
38
+ this . canvasRendering ( )
39
+ }
40
+
41
+ componentDidUpdate ( prevProps : InteractionCanvasProps , prevState : InteractionCanvasState ) {
42
+ if ( this . state . overlayRegions !== prevState . overlayRegions ) {
43
+ // this.canvasRendering()
44
+ }
45
+ }
46
+
47
+
48
+ canvasRendering = ( ) => {
49
+
50
+ const canvasMap = this . canvasMap
51
+ const { overlayRegions, interactionContext } = this . state
52
+ if ( interactionContext === null || ! overlayRegions ) return
53
+
54
+ const { height, width } = this . props
55
+ const { margin } = this . state
56
+
57
+ canvasMap . clear ( )
58
+
59
+ const interactionContext2D = interactionContext . getContext ( "2d" )
60
+
61
+ interactionContext2D . imageSmoothingEnabled = false
62
+ interactionContext2D . setTransform ( 1 , 0 , 0 , 1 , margin . left , margin . top )
63
+ interactionContext2D . clearRect (
64
+ - margin . left ,
65
+ - margin . top ,
66
+ width ,
67
+ height
68
+ )
69
+
70
+ interactionContext2D . lineWidth = 1
71
+
72
+ overlayRegions . forEach ( ( overlay , oi ) => {
73
+ const interactionRGBA = `rgba(${ Math . floor (
74
+ Math . random ( ) * 255
75
+ ) } ,${ Math . floor ( Math . random ( ) * 255 ) } ,${ Math . floor (
76
+ Math . random ( ) * 255
77
+ ) } ,255)`
78
+
79
+ canvasMap . set ( interactionRGBA , oi )
80
+
81
+ interactionContext2D . fillStyle = interactionRGBA
82
+ interactionContext2D . strokeStyle = interactionRGBA
83
+
84
+ const p = new Path2D ( overlay . props . d )
85
+ interactionContext2D . stroke ( p )
86
+ interactionContext2D . fill ( p )
87
+ } )
88
+ }
89
+
90
+
91
+ render ( ) {
92
+ const { width, height, voronoiHover } = this . props
93
+ const { overlayRegions } = this . state
94
+
95
+
96
+ return < canvas
97
+ className = "frame-canvas-interaction"
98
+ ref = { ( canvasContext : any ) => {
99
+ const boundCanvasEvent = canvasEvent . bind (
100
+ null ,
101
+ canvasContext ,
102
+ overlayRegions ,
103
+ this . canvasMap
104
+ )
105
+ if ( canvasContext ) {
106
+ canvasContext . onmousemove = e => {
107
+ const overlay = boundCanvasEvent ( e )
108
+ if ( overlay && overlay . props ) {
109
+ overlay . props . onMouseEnter ( )
110
+ } else {
111
+ voronoiHover ( null )
112
+ }
113
+ }
114
+ canvasContext . onclick = e => {
115
+ const overlay = boundCanvasEvent ( e )
116
+ if ( overlay && overlay . props ) {
117
+ overlay . props . onClick ( )
118
+ }
119
+ }
120
+ canvasContext . ondblclick = e => {
121
+ const overlay = boundCanvasEvent ( e )
122
+ if ( overlay && overlay . props ) {
123
+ overlay . props . onDoubleClick ( )
124
+ }
125
+ }
126
+ }
127
+ this . setState ( { interactionContext : canvasContext } )
128
+ } }
129
+ style = { {
130
+ position : "absolute" ,
131
+ left : `0px` ,
132
+ top : `0px` ,
133
+ imageRendering : "pixelated" ,
134
+ pointerEvents : "all" ,
135
+ opacity : 0
136
+ } }
137
+ width = { width }
138
+ height = { height }
139
+ />
140
+ }
141
+ }
142
+
143
+ export default InteractionCanvas
0 commit comments