@luceosports/play-rendering 2.2.8 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luceosports/play-rendering",
3
- "version": "2.2.8",
3
+ "version": "2.3.0",
4
4
  "main": "dist/play-rendering.js",
5
5
  "types": "dist/play-rendering.d.ts",
6
6
  "scripts": {
package/src/constants.ts CHANGED
@@ -2,6 +2,7 @@ export const SPORT_TYPE_BASKETBALL = 'BASKETBALL';
2
2
  export const SPORT_TYPE_VOLLEYBALL = 'VOLLEYBALL';
3
3
  export const SPORT_TYPE_FOOTBALL = 'FOOTBALL';
4
4
  export const SPORT_TYPE_LACROSSE = 'LACROSSE';
5
+ export const SPORT_TYPE_LACROSSE_BOX = 'LACROSSE_BOX';
5
6
  export const SPORT_TYPE_SOCCER = 'SOCCER';
6
7
  export const SPORT_TYPE_HOCKEY = 'HOCKEY';
7
8
  export const SPORT_TYPE_BASEBALL = 'BASEBALL';
@@ -23,6 +24,8 @@ export const COURT_TYPE_VOLLEYBALL_INDOOR = 'VOLLEYBALL_INDOOR';
23
24
  export const COURT_TYPE_LACROSSE_US_M = 'LACROSSE_US_M';
24
25
  export const COURT_TYPE_LACROSSE_US_W = 'LACROSSE_US_W';
25
26
 
27
+ export const COURT_TYPE_LACROSSE_BOX_US = 'LACROSSE_BOX_US';
28
+
26
29
  export const COURT_TYPE_SOCCER_FIFA = 'SOCCER_FIFA';
27
30
  export const COURT_TYPE_SOCCER_NCAA = 'SOCCER_NCAA';
28
31
  export const COURT_TYPE_SOCCER_NFHS = 'SOCCER_NFHS';
@@ -9,6 +9,7 @@ import {
9
9
  COURT_TYPE_HOCKEY_NHL,
10
10
  COURT_TYPE_LACROSSE_US_M,
11
11
  COURT_TYPE_LACROSSE_US_W,
12
+ COURT_TYPE_LACROSSE_BOX_US,
12
13
  COURT_TYPE_NBA,
13
14
  COURT_TYPE_NCAAM,
14
15
  COURT_TYPE_NCAAW,
@@ -28,7 +29,8 @@ import {
28
29
  SPORT_TYPE_HOCKEY,
29
30
  SPORT_TYPE_LACROSSE,
30
31
  SPORT_TYPE_SOCCER,
31
- SPORT_TYPE_VOLLEYBALL
32
+ SPORT_TYPE_VOLLEYBALL,
33
+ SPORT_TYPE_LACROSSE_BOX
32
34
  } from '../../constants';
33
35
 
34
36
  export type SportConstants = {
@@ -88,6 +90,11 @@ import * as LacrosseUsMConstants from './layers/LACROSSE/courtTypes/LACROSSE_US_
88
90
  import * as LacrosseUsWLayers from './layers/LACROSSE/courtTypes/LACROSSE_US_W/layers';
89
91
  import * as LacrosseUsWConstants from './layers/LACROSSE/courtTypes/LACROSSE_US_W/constants';
90
92
 
93
+ import * as LacrosseBoxLayers from './layers/LACROSSE_BOX/layers';
94
+ import * as LacrosseBoxConstants from './layers/LACROSSE_BOX/constants';
95
+ import * as LacrosseBoxUsLayers from './layers/LACROSSE_BOX/courtTypes/LACROSSE_BOX_US/layers';
96
+ import * as LacrosseBoxUsConstants from './layers/LACROSSE_BOX/courtTypes/LACROSSE_BOX_US/constants';
97
+
91
98
  import * as SoccerLayers from './layers/SOCCER/layers';
92
99
  import * as SoccerConstants from './layers/SOCCER/constants';
93
100
  import * as SoccerU19Constants from './layers/SOCCER/courtTypes/SOCCER_U19/constants';
@@ -111,6 +118,7 @@ const sportLayers: Record<SportType, Record<string, typeof InternalCourtLayer>>
111
118
  [SPORT_TYPE_FOOTBALL]: FootballLayers,
112
119
  [SPORT_TYPE_HOCKEY]: HockeyLayers,
113
120
  [SPORT_TYPE_LACROSSE]: LacrosseLayers,
121
+ [SPORT_TYPE_LACROSSE_BOX]: LacrosseBoxLayers,
114
122
  [SPORT_TYPE_SOCCER]: SoccerLayers,
115
123
  [SPORT_TYPE_VOLLEYBALL]: VolleyballLayers
116
124
  };
@@ -138,6 +146,9 @@ const courtTypeLayers: Record<SportType, Partial<Record<CourtType, Record<string
138
146
  [COURT_TYPE_LACROSSE_US_M]: LacrosseUsMLayers,
139
147
  [COURT_TYPE_LACROSSE_US_W]: LacrosseUsWLayers
140
148
  },
149
+ [SPORT_TYPE_LACROSSE_BOX]: {
150
+ [COURT_TYPE_LACROSSE_BOX_US]: LacrosseBoxUsLayers
151
+ },
141
152
  [SPORT_TYPE_SOCCER]: {
142
153
  [COURT_TYPE_SOCCER_NCAA]: SoccerNcaaLayers,
143
154
  [COURT_TYPE_SOCCER_NFHS]: SoccerNfhsLayers,
@@ -153,6 +164,7 @@ const sportConstants: Record<SportType, SportConstants> = {
153
164
  [SPORT_TYPE_FOOTBALL]: FootballConstants,
154
165
  [SPORT_TYPE_HOCKEY]: HockeyConstants,
155
166
  [SPORT_TYPE_LACROSSE]: LacrosseConstants,
167
+ [SPORT_TYPE_LACROSSE_BOX]: LacrosseBoxConstants,
156
168
  [SPORT_TYPE_SOCCER]: SoccerConstants,
157
169
  [SPORT_TYPE_VOLLEYBALL]: VolleyballConstants
158
170
  };
@@ -172,6 +184,7 @@ const courtTypeConstants: Record<CourtType, CourtTypeConstants> = {
172
184
  [COURT_TYPE_HOCKEY_INTERNATIONAL]: HockeyIntConstants,
173
185
  [COURT_TYPE_LACROSSE_US_M]: LacrosseUsMConstants,
174
186
  [COURT_TYPE_LACROSSE_US_W]: LacrosseUsWConstants,
187
+ [COURT_TYPE_LACROSSE_BOX_US]: LacrosseBoxUsConstants,
175
188
  [COURT_TYPE_SOCCER_FIFA]: SoccerFifaConstants,
176
189
  [COURT_TYPE_SOCCER_NCAA]: SoccerNcaaConstants,
177
190
  [COURT_TYPE_SOCCER_NFHS]: SoccerNfhsConstants,
@@ -197,6 +210,7 @@ const sportCourtTypeMap: Record<SportType, { courtTypes: CourtType[] }> = {
197
210
  [SPORT_TYPE_FOOTBALL]: { courtTypes: [COURT_TYPE_FOOTBALL_HIGH_SCHOOL] },
198
211
  [SPORT_TYPE_HOCKEY]: { courtTypes: [COURT_TYPE_HOCKEY_NHL, COURT_TYPE_HOCKEY_INTERNATIONAL] },
199
212
  [SPORT_TYPE_LACROSSE]: { courtTypes: [COURT_TYPE_LACROSSE_US_M, COURT_TYPE_LACROSSE_US_W] },
213
+ [SPORT_TYPE_LACROSSE_BOX]: { courtTypes: [COURT_TYPE_LACROSSE_BOX_US] },
200
214
  [SPORT_TYPE_SOCCER]: {
201
215
  courtTypes: [
202
216
  COURT_TYPE_SOCCER_FIFA,
@@ -0,0 +1,5 @@
1
+ export const COURT_LINE_WIDTH = 0.1667;
2
+ export const PLAYER_TOKEN_RADIUS = 1.5;
3
+ export const PLAYER_TOKEN_SCALE = 1;
4
+ export const LINE_WIDTH = 0.33;
5
+ export const LINE_MASKING = true;
@@ -0,0 +1,5 @@
1
+ export const COURT_RECT_WIDTH = 85;
2
+ export const COURT_RECT_HEIGHT = 180;
3
+ export const GOAL_LINE_Y = 12;
4
+ export const TOP_SIDE_CURVE_OFFSET = 12;
5
+ export const RESTRAINING_LINE_OFFSET_Y = 42.5;
@@ -0,0 +1,51 @@
1
+ import InternalCourtLayer from '../../../../../base/InternalCourtLayer';
2
+
3
+ const GOAL_ARC_RADIUS = 9.25;
4
+ const GOAL_LINE_CAGE_LENGTH = 4.75;
5
+ const GOAL_BACK_LINE_OFFSET_Y = 6;
6
+
7
+ export default class FanLineLayer extends InternalCourtLayer {
8
+ reflection() {
9
+ return true;
10
+ }
11
+
12
+ drawLogic() {
13
+ const goalLineCenter = {
14
+ x: this.courtCenter.x,
15
+ y: this.courtTypeConstants.GOAL_LINE_Y
16
+ };
17
+
18
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
19
+
20
+ // 1. Draw goal line
21
+ this.ctx.beginPath();
22
+ this.ctx.moveTo(goalLineCenter.x - GOAL_ARC_RADIUS, goalLineCenter.y);
23
+ this.ctx.lineTo(goalLineCenter.x + GOAL_ARC_RADIUS, goalLineCenter.y);
24
+ this.ctx.stroke();
25
+
26
+ // 2. Draw arc
27
+ const angleOffset = Math.PI / 4.5;
28
+ this.ctx.beginPath();
29
+ this.ctx.arc(goalLineCenter.x, goalLineCenter.y, GOAL_ARC_RADIUS, -angleOffset, Math.PI + angleOffset, false);
30
+ this.ctx.stroke();
31
+
32
+ // 3. Draw goal back line
33
+ const backLineOffsetX = 2;
34
+ this.ctx.beginPath();
35
+ this.ctx.moveTo(goalLineCenter.x - (GOAL_ARC_RADIUS - backLineOffsetX), goalLineCenter.y - GOAL_BACK_LINE_OFFSET_Y);
36
+ this.ctx.lineTo(goalLineCenter.x + (GOAL_ARC_RADIUS - backLineOffsetX), goalLineCenter.y - GOAL_BACK_LINE_OFFSET_Y);
37
+ this.ctx.stroke();
38
+
39
+ // 4. Draw goal line cage
40
+ const goalCageLeft = { x: goalLineCenter.x - GOAL_LINE_CAGE_LENGTH / 2, y: goalLineCenter.y };
41
+ const goalCageRight = { x: goalLineCenter.x + GOAL_LINE_CAGE_LENGTH / 2, y: goalLineCenter.y };
42
+ const goalCageTop = { x: goalLineCenter.x, y: goalLineCenter.y - GOAL_LINE_CAGE_LENGTH / 2 };
43
+
44
+ this.ctx.beginPath();
45
+ this.ctx.moveTo(goalCageLeft.x, goalCageLeft.y);
46
+ this.ctx.lineTo(goalCageRight.x, goalCageRight.y);
47
+ this.ctx.lineTo(goalCageTop.x, goalCageTop.y);
48
+ this.ctx.closePath();
49
+ this.ctx.stroke();
50
+ }
51
+ }
@@ -0,0 +1,13 @@
1
+ import InternalCourtLayer from '../../../../../base/InternalCourtLayer';
2
+
3
+ const REFEREE_CREASE_RADIUS = 10;
4
+
5
+ export default class RefereeCreaseLayer extends InternalCourtLayer {
6
+ drawLogic() {
7
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
8
+
9
+ this.ctx.beginPath();
10
+ this.ctx.arc(0, this.courtCenter.y, REFEREE_CREASE_RADIUS, Math.PI / 2, -Math.PI / 2, true);
11
+ this.ctx.stroke();
12
+ }
13
+ }
@@ -0,0 +1,21 @@
1
+ import InternalCourtLayer from '../../../../../base/InternalCourtLayer';
2
+
3
+ export default class RestrainingLineLayer extends InternalCourtLayer {
4
+ reflection() {
5
+ return true;
6
+ }
7
+
8
+ drawLogic() {
9
+ const courtOrigin = { x: 0.0, y: this.courtCenter.y - this.courtTypeConstants.RESTRAINING_LINE_OFFSET_Y };
10
+ const courtTerminus = {
11
+ x: this.courtTypeConstants.COURT_RECT_WIDTH,
12
+ y: this.courtCenter.y - this.courtTypeConstants.RESTRAINING_LINE_OFFSET_Y
13
+ };
14
+
15
+ this.ctx.beginPath();
16
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
17
+ this.ctx.moveTo(courtOrigin.x, courtOrigin.y);
18
+ this.ctx.lineTo(courtTerminus.x, courtTerminus.y);
19
+ this.ctx.stroke();
20
+ }
21
+ }
@@ -0,0 +1,5 @@
1
+ import RestrainingLineLayer from './RestrainingLineLayer';
2
+ import FanLineLayer from './FanLineLayer';
3
+ import RefereeCreaseLayer from './RefereeCreaseLayer';
4
+
5
+ export { RestrainingLineLayer, FanLineLayer, RefereeCreaseLayer };
@@ -0,0 +1,44 @@
1
+ import InternalCourtLayer from '../../../base/InternalCourtLayer';
2
+
3
+ export default class BorderRinkLayer extends InternalCourtLayer {
4
+ reflection() {
5
+ return true;
6
+ }
7
+
8
+ drawLogic() {
9
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
10
+
11
+ const sideLineLeft = [
12
+ { x: 0, y: this.courtCenter.y },
13
+ { x: 0, y: this.courtTypeConstants.GOAL_LINE_Y }
14
+ ];
15
+
16
+ const sideLineTop = [
17
+ { x: this.courtTypeConstants.TOP_SIDE_CURVE_OFFSET, y: 0 },
18
+ { x: this.courtTypeConstants.COURT_RECT_WIDTH - this.courtTypeConstants.TOP_SIDE_CURVE_OFFSET, y: 0 }
19
+ ];
20
+
21
+ const sideLineRight = [
22
+ { x: this.courtTypeConstants.COURT_RECT_WIDTH, y: this.courtCenter.y },
23
+ { x: this.courtTypeConstants.COURT_RECT_WIDTH, y: this.courtTypeConstants.GOAL_LINE_Y }
24
+ ];
25
+
26
+ this.ctx.beginPath();
27
+ this.ctx.moveTo(sideLineLeft[0].x, sideLineLeft[0].y);
28
+ this.ctx.lineTo(sideLineLeft[1].x, sideLineLeft[1].y);
29
+
30
+ this.ctx.bezierCurveTo(0, 0, 10, 0, sideLineTop[0].x, sideLineTop[0].y);
31
+ this.ctx.lineTo(sideLineTop[1].x, sideLineTop[1].y);
32
+
33
+ this.ctx.bezierCurveTo(
34
+ this.courtTypeConstants.COURT_RECT_WIDTH - 10,
35
+ 0,
36
+ this.courtTypeConstants.COURT_RECT_WIDTH,
37
+ 0,
38
+ sideLineRight[1].x,
39
+ sideLineRight[1].y
40
+ );
41
+ this.ctx.lineTo(sideLineRight[0].x, sideLineRight[0].y);
42
+ this.ctx.stroke();
43
+ }
44
+ }
@@ -0,0 +1,19 @@
1
+ import InternalCourtLayer from '../../../base/InternalCourtLayer';
2
+
3
+ const CENTER_CIRCLE_RADIUS = 11;
4
+ const CENTER_CIRCLE_INNER_RADIUS = 1.41667;
5
+
6
+ export default class CenterCircleLayer extends InternalCourtLayer {
7
+ drawLogic() {
8
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
9
+
10
+ this.ctx.beginPath();
11
+ this.ctx.arc(this.courtCenter.x, this.courtCenter.y, CENTER_CIRCLE_RADIUS, 0, Math.PI * 2, true);
12
+ this.ctx.stroke();
13
+
14
+ this.ctx.setLineDash([0.8, 0.5]);
15
+ this.ctx.beginPath();
16
+ this.ctx.arc(this.courtCenter.x, this.courtCenter.y, CENTER_CIRCLE_INNER_RADIUS, 0, Math.PI * 2, true);
17
+ this.ctx.stroke();
18
+ }
19
+ }
@@ -0,0 +1,14 @@
1
+ import InternalCourtLayer from '../../../base/InternalCourtLayer';
2
+
3
+ export default class CenterLineLayer extends InternalCourtLayer {
4
+ drawLogic() {
5
+ const courtOrigin = { x: 0.0, y: this.courtCenter.y };
6
+ const courtTerminus = { x: this.courtTypeConstants.COURT_RECT_WIDTH, y: this.courtCenter.y };
7
+
8
+ this.ctx.beginPath();
9
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
10
+ this.ctx.moveTo(courtOrigin.x, courtOrigin.y);
11
+ this.ctx.lineTo(courtTerminus.x, courtTerminus.y);
12
+ this.ctx.stroke();
13
+ }
14
+ }
@@ -0,0 +1,5 @@
1
+ import BorderRinkLayer from './BorderRinkLayer';
2
+ import CenterLineLayer from './CenterLineLayer';
3
+ import CenterCircleLayer from './CenterCircleLayer';
4
+
5
+ export { BorderRinkLayer, CenterLineLayer, CenterCircleLayer };
@@ -489,8 +489,9 @@ export default class FrameModel {
489
489
  prepareCourtPoint(courtPoint: CourtPoint) {
490
490
  const { mirror } = this.play.options;
491
491
  const { width } = this.play.playData.court.courtRect.size;
492
+ const { origin } = this.play.playData.court.courtRect;
492
493
  return {
493
- x: mirror ? width - courtPoint.x : courtPoint.x,
494
+ x: mirror ? width + origin.x - (courtPoint.x - origin.x) : courtPoint.x,
494
495
  y: courtPoint.y
495
496
  };
496
497
  }
@@ -9,6 +9,7 @@ import {
9
9
  SPORT_TYPE_FOOTBALL,
10
10
  SPORT_TYPE_HOCKEY,
11
11
  SPORT_TYPE_LACROSSE,
12
+ SPORT_TYPE_LACROSSE_BOX,
12
13
  SPORT_TYPE_SOCCER,
13
14
  SPORT_TYPE_VOLLEYBALL
14
15
  } from '../constants';
@@ -117,6 +118,7 @@ export default class PlayModel {
117
118
  [SPORT_TYPE_VOLLEYBALL]: hardwoodImage,
118
119
  [SPORT_TYPE_FOOTBALL]: grassImage,
119
120
  [SPORT_TYPE_LACROSSE]: grassImage,
121
+ [SPORT_TYPE_LACROSSE_BOX]: grassImage,
120
122
  [SPORT_TYPE_SOCCER]: grassImage,
121
123
  [SPORT_TYPE_HOCKEY]: iceImage,
122
124
  [SPORT_TYPE_BASEBALL]: grassImage
@@ -12,7 +12,15 @@ export type LineShapeType = 'LINE.CUT' | 'LINE.SCREEN' | 'LINE.DRIBBLE' | 'LINE.
12
12
 
13
13
  export type ShapeType = 'CIRCLE' | 'SQUARE' | 'TRIANGLE' | 'FOV' | 'XMARK' | 'STRAIGHT' | 'CONE' | LineShapeType;
14
14
 
15
- export type SportType = 'FOOTBALL' | 'BASKETBALL' | 'VOLLEYBALL' | 'LACROSSE' | 'SOCCER' | 'HOCKEY' | 'BASEBALL';
15
+ export type SportType =
16
+ | 'FOOTBALL'
17
+ | 'BASKETBALL'
18
+ | 'VOLLEYBALL'
19
+ | 'LACROSSE'
20
+ | 'LACROSSE_BOX'
21
+ | 'SOCCER'
22
+ | 'HOCKEY'
23
+ | 'BASEBALL';
16
24
 
17
25
  export type CourtTypeSportBasketball =
18
26
  | 'BIG3'
@@ -40,6 +48,8 @@ export type CourtTypeSportBaseball = 'BASEBALL_HIGH_SCHOOL';
40
48
 
41
49
  export type CourtTypeSportLacrosse = 'LACROSSE_US_M' | 'LACROSSE_US_W';
42
50
 
51
+ export type CourtTypeSportLacrosseBox = 'LACROSSE_BOX_US';
52
+
43
53
  export type CourtTypeSportFootball = 'FOOTBALL_HIGH_SCHOOL';
44
54
 
45
55
  export type CourtTypeSportFootballLegacy = 'FOOTBALL';
@@ -48,6 +58,7 @@ export type CourtType =
48
58
  | CourtTypeSportBasketball
49
59
  | CourtTypeSportVolleyball
50
60
  | CourtTypeSportLacrosse
61
+ | CourtTypeSportLacrosseBox
51
62
  | CourtTypeSportSoccer
52
63
  | CourtTypeSportHockey
53
64
  | CourtTypeSportBaseball