@luceosports/play-rendering 1.14.0 → 1.16.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.
Files changed (22) hide show
  1. package/dist/play-rendering.js +3 -3
  2. package/dist/play-rendering.js.map +1 -1
  3. package/package.json +1 -1
  4. package/src/constants.js +7 -0
  5. package/src/layers/court/layers/LACROSSE/constants.js +7 -0
  6. package/src/layers/court/layers/LACROSSE/courtTypes/US_LACROSSE_M/constants.js +6 -0
  7. package/src/layers/court/layers/LACROSSE/courtTypes/US_LACROSSE_M/layers/CenterLineLayer.js +33 -0
  8. package/src/layers/court/layers/LACROSSE/courtTypes/US_LACROSSE_M/layers/GoalAreaLineLayer.js +57 -0
  9. package/src/layers/court/layers/LACROSSE/courtTypes/US_LACROSSE_M/layers/WingAreaLineLayer.js +43 -0
  10. package/src/layers/court/layers/LACROSSE/courtTypes/US_LACROSSE_W/constants.js +5 -0
  11. package/src/layers/court/layers/LACROSSE/courtTypes/US_LACROSSE_W/layers/CenterLineLayer.js +23 -0
  12. package/src/layers/court/layers/LACROSSE/courtTypes/US_LACROSSE_W/layers/FanLineLayer.js +147 -0
  13. package/src/layers/court/layers/LACROSSE/layers/BorderRectLayer.js +12 -0
  14. package/src/layers/court/layers/LACROSSE/layers/RestrainingLineLayer.js +23 -0
  15. package/src/layers/court/layers/SOCCER/constants.js +7 -0
  16. package/src/layers/court/layers/SOCCER/courtTypes/SOCCER_FIFA/constants.js +4 -0
  17. package/src/layers/court/layers/SOCCER/layers/BorderRectLayer.js +12 -0
  18. package/src/layers/court/layers/SOCCER/layers/CenterCircleLayer.js +20 -0
  19. package/src/layers/court/layers/SOCCER/layers/CenterLineLayer.js +16 -0
  20. package/src/layers/court/layers/SOCCER/layers/CornerLayer.js +25 -0
  21. package/src/layers/court/layers/SOCCER/layers/PenaltyAreaLayer.js +52 -0
  22. package/src/models/Play.js +10 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luceosports/play-rendering",
3
- "version": "1.14.0",
3
+ "version": "1.16.0",
4
4
  "description": "",
5
5
  "main": "dist/play-rendering.js",
6
6
  "scripts": {
package/src/constants.js CHANGED
@@ -2,6 +2,8 @@ module.exports = Object.freeze({
2
2
  SPORT_TYPE_BASKETBALL: 'BASKETBALL',
3
3
  SPORT_TYPE_VOLLEYBALL: 'VOLLEYBALL',
4
4
  SPORT_TYPE_FOOTBALL: 'FOOTBALL',
5
+ SPORT_TYPE_LACROSSE: 'LACROSSE',
6
+ SPORT_TYPE_SOCCER: 'SOCCER',
5
7
 
6
8
  COURT_TYPE_BIG3: 'BIG3',
7
9
  COURT_TYPE_FIBA: 'FIBA',
@@ -17,6 +19,11 @@ module.exports = Object.freeze({
17
19
 
18
20
  COURT_TYPE_INDOOR: 'INDOOR',
19
21
 
22
+ COURT_TYPE_US_LACROSSE_M: 'US_LACROSSE_M',
23
+ COURT_TYPE_US_LACROSSE_W: 'US_LACROSSE_W',
24
+
25
+ COURT_TYPE_SOCCER_FIFA: 'SOCCER_FIFA',
26
+
20
27
  SHAPE_TYPE_CIRCLE: 'CIRCLE',
21
28
  SHAPE_TYPE_SQUARE: 'SQUARE',
22
29
  SHAPE_TYPE_TRIANGLE: 'TRIANGLE',
@@ -0,0 +1,7 @@
1
+ module.exports = Object.freeze({
2
+ COURT_LINE_WIDTH: 0.1667,
3
+ PLAYER_TOKEN_RADIUS: 1.5,
4
+ PLAYER_TOKEN_SCALE: 1,
5
+ LINE_WIDTH: 0.33,
6
+ LINE_MASKING: true
7
+ });
@@ -0,0 +1,6 @@
1
+ module.exports = Object.freeze({
2
+ COURT_RECT_WIDTH: 60,
3
+ COURT_RECT_HEIGHT: 110,
4
+ WING_OFFSET_X: 10,
5
+ RESTRAINING_CENTER_OFFSET_Y: 20
6
+ });
@@ -0,0 +1,33 @@
1
+ const InternalCourtLayer = require('../../../../../base/InternalCourtLayer');
2
+
3
+ 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
+ const xAsRectangle = [
15
+ { x: this.courtCenter.x - 1, y: this.courtCenter.y - 1 },
16
+ { x: this.courtCenter.x + 1, y: this.courtCenter.y - 1 },
17
+ { x: this.courtCenter.x + 1, y: this.courtCenter.y + 1 },
18
+ { x: this.courtCenter.x - 1, y: this.courtCenter.y + 1 }
19
+ ];
20
+
21
+ this.ctx.beginPath();
22
+
23
+ this.ctx.moveTo(xAsRectangle[0].x, xAsRectangle[0].y);
24
+ this.ctx.lineTo(xAsRectangle[2].x, xAsRectangle[2].y);
25
+
26
+ this.ctx.moveTo(xAsRectangle[1].x, xAsRectangle[1].y);
27
+ this.ctx.lineTo(xAsRectangle[3].x, xAsRectangle[3].y);
28
+
29
+ this.ctx.stroke();
30
+ }
31
+ }
32
+
33
+ module.exports = CenterLineLayer;
@@ -0,0 +1,57 @@
1
+ const InternalCourtLayer = require('../../../../../base/InternalCourtLayer');
2
+
3
+ const GOAL_LINE_WIDTH = 2;
4
+ const GOAL_LINE_OFFSET_Y = 15;
5
+ const GOAL_LINE_RADIUS = 3;
6
+
7
+ class GoalAreaLineLayer extends InternalCourtLayer {
8
+ reflection() {
9
+ return true;
10
+ }
11
+
12
+ drawLogic() {
13
+ const sideLineLeftOrigin = { x: this.courtTypeConstants.WING_OFFSET_X, y: 0 };
14
+ const sideLineLeftTerminus = {
15
+ x: this.courtTypeConstants.WING_OFFSET_X,
16
+ y: this.courtCenter.y - this.courtTypeConstants.RESTRAINING_CENTER_OFFSET_Y
17
+ };
18
+
19
+ this.ctx.beginPath();
20
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
21
+ this.ctx.moveTo(sideLineLeftOrigin.x, sideLineLeftOrigin.y);
22
+ this.ctx.lineTo(sideLineLeftTerminus.x, sideLineLeftTerminus.y);
23
+ this.ctx.stroke();
24
+
25
+ const sideLineRightOrigin = {
26
+ x: this.courtTypeConstants.COURT_RECT_WIDTH - this.courtTypeConstants.WING_OFFSET_X,
27
+ y: 0
28
+ };
29
+ const sideLineRightTerminus = {
30
+ x: this.courtTypeConstants.COURT_RECT_WIDTH - this.courtTypeConstants.WING_OFFSET_X,
31
+ y: this.courtCenter.y - this.courtTypeConstants.RESTRAINING_CENTER_OFFSET_Y
32
+ };
33
+
34
+ this.ctx.beginPath();
35
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
36
+ this.ctx.moveTo(sideLineRightOrigin.x, sideLineRightOrigin.y);
37
+ this.ctx.lineTo(sideLineRightTerminus.x, sideLineRightTerminus.y);
38
+ this.ctx.stroke();
39
+
40
+ const goalLineCenter = {
41
+ x: this.courtCenter.x,
42
+ y: GOAL_LINE_OFFSET_Y
43
+ };
44
+
45
+ this.ctx.beginPath();
46
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
47
+ this.ctx.moveTo(goalLineCenter.x - GOAL_LINE_WIDTH / 2, goalLineCenter.y);
48
+ this.ctx.lineTo(goalLineCenter.x + GOAL_LINE_WIDTH / 2, goalLineCenter.y);
49
+ this.ctx.stroke();
50
+
51
+ this.ctx.beginPath();
52
+ this.ctx.arc(goalLineCenter.x, goalLineCenter.y, GOAL_LINE_RADIUS, 0, Math.PI * 2, true);
53
+ this.ctx.stroke();
54
+ }
55
+ }
56
+
57
+ module.exports = GoalAreaLineLayer;
@@ -0,0 +1,43 @@
1
+ const InternalCourtLayer = require('../../../../../base/InternalCourtLayer');
2
+
3
+ const WING_LINE_CENTER_OFFSET_Y = 10;
4
+
5
+ class WingAreaLineLayer extends InternalCourtLayer {
6
+ reflection() {
7
+ return true;
8
+ }
9
+
10
+ drawLogic() {
11
+ const wingLineLeftOrigin = {
12
+ x: this.courtTypeConstants.WING_OFFSET_X,
13
+ y: this.courtCenter.y - WING_LINE_CENTER_OFFSET_Y
14
+ };
15
+ const wingLineLeftTerminus = {
16
+ x: this.courtTypeConstants.WING_OFFSET_X,
17
+ y: this.courtCenter.y
18
+ };
19
+
20
+ this.ctx.beginPath();
21
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
22
+ this.ctx.moveTo(wingLineLeftOrigin.x, wingLineLeftOrigin.y);
23
+ this.ctx.lineTo(wingLineLeftTerminus.x, wingLineLeftTerminus.y);
24
+ this.ctx.stroke();
25
+
26
+ const wingLineRightOrigin = {
27
+ x: this.courtTypeConstants.COURT_RECT_WIDTH - this.courtTypeConstants.WING_OFFSET_X,
28
+ y: this.courtCenter.y - WING_LINE_CENTER_OFFSET_Y
29
+ };
30
+ const wingLineRightTerminus = {
31
+ x: this.courtTypeConstants.COURT_RECT_WIDTH - this.courtTypeConstants.WING_OFFSET_X,
32
+ y: this.courtCenter.y
33
+ };
34
+
35
+ this.ctx.beginPath();
36
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
37
+ this.ctx.moveTo(wingLineRightOrigin.x, wingLineRightOrigin.y);
38
+ this.ctx.lineTo(wingLineRightTerminus.x, wingLineRightTerminus.y);
39
+ this.ctx.stroke();
40
+ }
41
+ }
42
+
43
+ module.exports = WingAreaLineLayer;
@@ -0,0 +1,5 @@
1
+ module.exports = Object.freeze({
2
+ COURT_RECT_WIDTH: 60,
3
+ COURT_RECT_HEIGHT: 130,
4
+ RESTRAINING_CENTER_OFFSET_Y: 20
5
+ });
@@ -0,0 +1,23 @@
1
+ const InternalCourtLayer = require('../../../../../base/InternalCourtLayer');
2
+
3
+ const CENTER_DASH_WIDTH = 3;
4
+ const CENTER_CIRCLE_RADIUS = 10;
5
+
6
+ class CenterLineLayer extends InternalCourtLayer {
7
+ drawLogic() {
8
+ const centerDashOrigin = { x: this.courtCenter.x - CENTER_DASH_WIDTH / 2, y: this.courtCenter.y };
9
+ const centerDashTerminus = { x: this.courtCenter.x + CENTER_DASH_WIDTH / 2, y: this.courtCenter.y };
10
+
11
+ this.ctx.beginPath();
12
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
13
+ this.ctx.moveTo(centerDashOrigin.x, centerDashOrigin.y);
14
+ this.ctx.lineTo(centerDashTerminus.x, centerDashTerminus.y);
15
+ this.ctx.stroke();
16
+
17
+ this.ctx.beginPath();
18
+ this.ctx.arc(this.courtCenter.x, this.courtCenter.y, CENTER_CIRCLE_RADIUS, 0, Math.PI * 2, true);
19
+ this.ctx.stroke();
20
+ }
21
+ }
22
+
23
+ module.exports = CenterLineLayer;
@@ -0,0 +1,147 @@
1
+ const InternalCourtLayer = require('../../../../../base/InternalCourtLayer');
2
+
3
+ const ARC_8M_RADIUS = 11.59;
4
+ const ARC_12M_RADIUS = 15.97;
5
+ const GOAL_CIRCLE_RADIUS = 2.84;
6
+ const GOAL_LINE_RESTRAINING_OFFSET_Y = 30;
7
+ const GOAL_LINE_CIRCLE_HASH_MARK_OFFSET = 8.75;
8
+ const GOAL_LINE_BACK_CIRCLES_OFFSET_Y = 5;
9
+ const GOAL_LINE_BACK_CIRCLES_RADIUS = 0.5;
10
+ const GOAL_LINE_CAGE_LENGTH = 2;
11
+ const HASH_MARK_LENGTH = 1;
12
+
13
+ class CenterLineLayer extends InternalCourtLayer {
14
+ reflection() {
15
+ return true;
16
+ }
17
+
18
+ drawLogic() {
19
+ const goalLineCenter = {
20
+ x: this.courtCenter.x,
21
+ y: this.courtCenter.y - this.courtTypeConstants.RESTRAINING_CENTER_OFFSET_Y - GOAL_LINE_RESTRAINING_OFFSET_Y
22
+ };
23
+
24
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
25
+
26
+ // 1. Draw goal circle
27
+ this.ctx.beginPath();
28
+ this.ctx.arc(goalLineCenter.x, goalLineCenter.y, GOAL_CIRCLE_RADIUS, 0, Math.PI * 2, false);
29
+ this.ctx.stroke();
30
+
31
+ // 2. Draw 12 meter arc
32
+ this.ctx.beginPath();
33
+ this.ctx.arc(goalLineCenter.x, goalLineCenter.y, ARC_12M_RADIUS, 0, Math.PI, false);
34
+ this.ctx.stroke();
35
+
36
+ // 3. Draw 12 meter arc semi-circle flat side
37
+ const leftFlatOrigin = { x: goalLineCenter.x - ARC_12M_RADIUS, y: goalLineCenter.y };
38
+ const leftFlatTerminus = { x: goalLineCenter.x - GOAL_CIRCLE_RADIUS, y: goalLineCenter.y };
39
+ const rightFlatOrigin = { x: goalLineCenter.x + ARC_12M_RADIUS, y: goalLineCenter.y };
40
+ const rightFlatTerminus = { x: goalLineCenter.x + GOAL_CIRCLE_RADIUS, y: goalLineCenter.y };
41
+ this.ctx.beginPath();
42
+ this.ctx.moveTo(leftFlatOrigin.x, leftFlatOrigin.y);
43
+ this.ctx.lineTo(leftFlatTerminus.x, leftFlatTerminus.y);
44
+ this.ctx.moveTo(rightFlatOrigin.x, rightFlatOrigin.y);
45
+ this.ctx.lineTo(rightFlatTerminus.x, rightFlatTerminus.y);
46
+ this.ctx.stroke();
47
+
48
+ // 4. Draw 8 meter arc
49
+ const goalCircleBackCenter = { x: goalLineCenter.x, y: goalLineCenter.y - GOAL_CIRCLE_RADIUS };
50
+ const goalCircleBackCenterRadius = ARC_8M_RADIUS + GOAL_CIRCLE_RADIUS;
51
+ const arcStartAngle = Math.PI / 4;
52
+ const arcEndAngle = Math.PI / 2 + Math.PI / 4;
53
+
54
+ this.ctx.beginPath();
55
+ this.ctx.arc(
56
+ goalCircleBackCenter.x,
57
+ goalCircleBackCenter.y,
58
+ goalCircleBackCenterRadius,
59
+ arcStartAngle,
60
+ arcEndAngle,
61
+ false
62
+ );
63
+ this.ctx.stroke();
64
+
65
+ // 5. Connect 8 meter arc edge points with goal circle
66
+ const arcEdgePointLeft = getArcPointForAngle(goalCircleBackCenter, goalCircleBackCenterRadius, arcEndAngle);
67
+ const arcEdgePointRight = getArcPointForAngle(goalCircleBackCenter, goalCircleBackCenterRadius, arcStartAngle);
68
+
69
+ const goalCircleLeftX = goalLineCenter.x - GOAL_CIRCLE_RADIUS;
70
+ const goalCircleRightX = goalLineCenter.x + GOAL_CIRCLE_RADIUS;
71
+
72
+ this.ctx.beginPath();
73
+ this.ctx.moveTo(arcEdgePointLeft.x, arcEdgePointLeft.y);
74
+ this.ctx.lineTo(goalCircleLeftX, goalLineCenter.y);
75
+ this.ctx.stroke();
76
+
77
+ this.ctx.beginPath();
78
+ this.ctx.moveTo(arcEdgePointRight.x, arcEdgePointRight.y);
79
+ this.ctx.lineTo(goalCircleRightX, goalLineCenter.y);
80
+ this.ctx.stroke();
81
+
82
+ // 6. Add 2 additional hash marks on the sides of goal circle
83
+ const hashMarkLeft = { x: goalCircleLeftX - GOAL_LINE_CIRCLE_HASH_MARK_OFFSET, y: goalLineCenter.y };
84
+ const hashMarkRight = { x: goalCircleRightX + GOAL_LINE_CIRCLE_HASH_MARK_OFFSET, y: goalLineCenter.y };
85
+ this.ctx.beginPath();
86
+ this.ctx.moveTo(hashMarkLeft.x, hashMarkLeft.y);
87
+ this.ctx.lineTo(hashMarkLeft.x, hashMarkLeft.y + HASH_MARK_LENGTH);
88
+ this.ctx.stroke();
89
+
90
+ this.ctx.beginPath();
91
+ this.ctx.moveTo(hashMarkRight.x, hashMarkRight.y);
92
+ this.ctx.lineTo(hashMarkRight.x, hashMarkRight.y + HASH_MARK_LENGTH);
93
+ this.ctx.stroke();
94
+
95
+ // 9. Draw hash marks 8 meter arc
96
+ const hashMarkMidPoint = getArcPointForAngle(goalCircleBackCenter, goalCircleBackCenterRadius, Math.PI / 2);
97
+ this.ctx.beginPath();
98
+ this.ctx.moveTo(hashMarkMidPoint.x, hashMarkMidPoint.y - HASH_MARK_LENGTH);
99
+ this.ctx.lineTo(hashMarkMidPoint.x, hashMarkMidPoint.y + HASH_MARK_LENGTH);
100
+ this.ctx.stroke();
101
+
102
+ for (let i = 1; i <= 3; i++) {
103
+ [1, -1].forEach(signChanger => {
104
+ const arcHashAngle = Math.PI / 2 + (Math.PI / 10) * signChanger * i;
105
+ const hashMarkPointForAngle = getArcPointForAngle(
106
+ goalCircleBackCenter,
107
+ goalCircleBackCenterRadius,
108
+ arcHashAngle
109
+ );
110
+ this.ctx.save();
111
+ this.ctx.translate(hashMarkPointForAngle.x, hashMarkPointForAngle.y);
112
+ this.ctx.rotate((Math.PI / 10) * signChanger * i);
113
+ this.ctx.beginPath();
114
+ this.ctx.moveTo(0, -HASH_MARK_LENGTH);
115
+ this.ctx.lineTo(0, HASH_MARK_LENGTH);
116
+ this.ctx.stroke();
117
+ this.ctx.restore();
118
+ });
119
+ }
120
+
121
+ // 8. Draw goal line back circles
122
+ const goalBackCircleLeft = { x: hashMarkLeft.x, y: hashMarkLeft.y - GOAL_LINE_BACK_CIRCLES_OFFSET_Y };
123
+ const goalBackCircleRight = { x: hashMarkRight.x, y: hashMarkRight.y - GOAL_LINE_BACK_CIRCLES_OFFSET_Y };
124
+ this.ctx.beginPath();
125
+ this.ctx.arc(goalBackCircleLeft.x, goalBackCircleLeft.y, GOAL_LINE_BACK_CIRCLES_RADIUS, 0, Math.PI * 2, false);
126
+ this.ctx.arc(goalBackCircleRight.x, goalBackCircleRight.y, GOAL_LINE_BACK_CIRCLES_RADIUS, 0, Math.PI * 2, false);
127
+ this.ctx.fill();
128
+
129
+ // 9. Draw goal line cage
130
+ const goalCageLeft = { x: goalLineCenter.x - GOAL_LINE_CAGE_LENGTH / 2, y: goalLineCenter.y };
131
+ const goalCageRight = { x: goalLineCenter.x + GOAL_LINE_CAGE_LENGTH / 2, y: goalLineCenter.y };
132
+ const goalCageTop = { x: goalLineCenter.x, y: goalLineCenter.y - GOAL_LINE_CAGE_LENGTH / 2 };
133
+
134
+ this.ctx.beginPath();
135
+ this.ctx.moveTo(goalCageLeft.x, goalCageLeft.y);
136
+ this.ctx.lineTo(goalCageRight.x, goalCageRight.y);
137
+ this.ctx.lineTo(goalCageTop.x, goalCageTop.y);
138
+ this.ctx.closePath();
139
+ this.ctx.stroke();
140
+ }
141
+ }
142
+
143
+ function getArcPointForAngle(c, radius, angle) {
144
+ return { x: c.x + Math.cos(angle) * radius, y: c.y + Math.sin(angle) * radius };
145
+ }
146
+
147
+ module.exports = CenterLineLayer;
@@ -0,0 +1,12 @@
1
+ const InternalCourtLayer = require('../../../base/InternalCourtLayer');
2
+
3
+ class BorderRectLayer extends InternalCourtLayer {
4
+ drawLogic() {
5
+ this.ctx.beginPath();
6
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
7
+ this.ctx.rect(0, 0, this.courtTypeConstants.COURT_RECT_WIDTH, this.courtTypeConstants.COURT_RECT_HEIGHT);
8
+ this.ctx.stroke();
9
+ }
10
+ }
11
+
12
+ module.exports = BorderRectLayer;
@@ -0,0 +1,23 @@
1
+ const InternalCourtLayer = require('../../../base/InternalCourtLayer');
2
+
3
+ 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_CENTER_OFFSET_Y };
10
+ const courtTerminus = {
11
+ x: this.courtTypeConstants.COURT_RECT_WIDTH,
12
+ y: this.courtCenter.y - this.courtTypeConstants.RESTRAINING_CENTER_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
+ }
22
+
23
+ module.exports = RestrainingLineLayer;
@@ -0,0 +1,7 @@
1
+ module.exports = Object.freeze({
2
+ COURT_LINE_WIDTH: 0.1667,
3
+ PLAYER_TOKEN_RADIUS: 1.5,
4
+ PLAYER_TOKEN_SCALE: 1,
5
+ LINE_WIDTH: 0.33,
6
+ LINE_MASKING: true
7
+ });
@@ -0,0 +1,4 @@
1
+ module.exports = Object.freeze({
2
+ COURT_RECT_WIDTH: 60,
3
+ COURT_RECT_HEIGHT: 110
4
+ });
@@ -0,0 +1,12 @@
1
+ const InternalCourtLayer = require('../../../base/InternalCourtLayer');
2
+
3
+ class BorderRectLayer extends InternalCourtLayer {
4
+ drawLogic() {
5
+ this.ctx.beginPath();
6
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
7
+ this.ctx.rect(0, 0, this.courtTypeConstants.COURT_RECT_WIDTH, this.courtTypeConstants.COURT_RECT_HEIGHT);
8
+ this.ctx.stroke();
9
+ }
10
+ }
11
+
12
+ module.exports = BorderRectLayer;
@@ -0,0 +1,20 @@
1
+ const InternalCourtLayer = require('../../../base/InternalCourtLayer');
2
+
3
+ class CenterCircleLayer extends InternalCourtLayer {
4
+ drawLogic() {
5
+ const circleOuterRadius = 10.0;
6
+ const circleInnerRadius = 0.5;
7
+
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, circleOuterRadius, 0, Math.PI * 2, true);
12
+ this.ctx.stroke();
13
+
14
+ this.ctx.beginPath();
15
+ this.ctx.arc(this.courtCenter.x, this.courtCenter.y, circleInnerRadius, 0, Math.PI * 2, true);
16
+ this.ctx.fill();
17
+ }
18
+ }
19
+
20
+ module.exports = CenterCircleLayer;
@@ -0,0 +1,16 @@
1
+ const InternalCourtLayer = require('../../../base/InternalCourtLayer');
2
+
3
+ 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
+ }
15
+
16
+ module.exports = CenterLineLayer;
@@ -0,0 +1,25 @@
1
+ const InternalCourtLayer = require('../../../base/InternalCourtLayer');
2
+
3
+ const CORNER_RADIUS = 1;
4
+ class CornerLayer extends InternalCourtLayer {
5
+ reflection() {
6
+ return true;
7
+ }
8
+
9
+ drawLogic() {
10
+ const leftCorner = { x: 0, y: 0 };
11
+ const rightCorner = { x: this.courtTypeConstants.COURT_RECT_WIDTH, y: 0 };
12
+
13
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
14
+
15
+ this.ctx.beginPath();
16
+ this.ctx.arc(leftCorner.x, leftCorner.y, CORNER_RADIUS, 0, Math.PI / 2, false);
17
+ this.ctx.stroke();
18
+
19
+ this.ctx.beginPath();
20
+ this.ctx.arc(rightCorner.x, rightCorner.y, CORNER_RADIUS, Math.PI, Math.PI / 2, true);
21
+ this.ctx.stroke();
22
+ }
23
+ }
24
+
25
+ module.exports = CornerLayer;
@@ -0,0 +1,52 @@
1
+ const InternalCourtLayer = require('../../../base/InternalCourtLayer');
2
+
3
+ const GOAL = { width: 8, height: 2.66 };
4
+ const GOAL_AREA = { width: 20, height: 6 };
5
+ const PENALTY_AREA = { width: 44, height: 18 };
6
+ const PENALTY_SPOT_OFFSET_Y = 12;
7
+ const PENALTY_SPOT_RADIUS = 0.5;
8
+ const PENALTY_ARC_RADIUS = 10;
9
+
10
+ class PenaltyAreaLayer extends InternalCourtLayer {
11
+ reflection() {
12
+ return true;
13
+ }
14
+
15
+ drawLogic() {
16
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
17
+
18
+ // 1. Draw penalty area rect
19
+ this.ctx.beginPath();
20
+ this.ctx.rect(this.courtCenter.x - PENALTY_AREA.width / 2, 0, PENALTY_AREA.width, PENALTY_AREA.height);
21
+ this.ctx.stroke();
22
+
23
+ // 2. Draw penalty spot
24
+ this.ctx.beginPath();
25
+ this.ctx.arc(this.courtCenter.x, PENALTY_SPOT_OFFSET_Y, PENALTY_SPOT_RADIUS, 0, Math.PI * 2, false);
26
+ this.ctx.fill();
27
+
28
+ // 3. Draw penalty area arc
29
+ this.ctx.beginPath();
30
+ this.ctx.arc(
31
+ this.courtCenter.x,
32
+ PENALTY_SPOT_OFFSET_Y,
33
+ PENALTY_ARC_RADIUS,
34
+ Math.PI / 5,
35
+ Math.PI - Math.PI / 5,
36
+ false
37
+ );
38
+ this.ctx.stroke();
39
+
40
+ // 4. Draw goal area rect
41
+ this.ctx.beginPath();
42
+ this.ctx.rect(this.courtCenter.x - GOAL_AREA.width / 2, 0, GOAL_AREA.width, GOAL_AREA.height);
43
+ this.ctx.stroke();
44
+
45
+ // 5. Draw goal rect
46
+ this.ctx.beginPath();
47
+ this.ctx.rect(this.courtCenter.x - GOAL.width / 2, -GOAL.height, GOAL.width, GOAL.height);
48
+ this.ctx.stroke();
49
+ }
50
+ }
51
+
52
+ module.exports = PenaltyAreaLayer;
@@ -3,7 +3,13 @@ const { loadImage } = require('canvas');
3
3
  const playerHatsConfig = require('../playerHatsConfig');
4
4
  const shapesConfig = require('../shapesConfig');
5
5
  const { useDefaults } = require('./Play/Options');
6
- const { SPORT_TYPE_BASKETBALL, SPORT_TYPE_VOLLEYBALL, SPORT_TYPE_FOOTBALL } = require('../constants');
6
+ const {
7
+ SPORT_TYPE_BASKETBALL,
8
+ SPORT_TYPE_VOLLEYBALL,
9
+ SPORT_TYPE_FOOTBALL,
10
+ SPORT_TYPE_LACROSSE,
11
+ SPORT_TYPE_SOCCER
12
+ } = require('../constants');
7
13
 
8
14
  const STORAGE_URL = 'https://playbooksstore.blob.core.windows.net/public';
9
15
  const LUCEOSPORTS_WATERMARK_PATH = 'partners/LuceoSports/luceo-sports-logo-powered-by-sm.png';
@@ -28,7 +34,9 @@ class Play {
28
34
  Hardwood: hardwoodImage,
29
35
  [SPORT_TYPE_BASKETBALL]: hardwoodImage,
30
36
  [SPORT_TYPE_VOLLEYBALL]: hardwoodImage,
31
- [SPORT_TYPE_FOOTBALL]: grassImage
37
+ [SPORT_TYPE_FOOTBALL]: grassImage,
38
+ [SPORT_TYPE_LACROSSE]: grassImage,
39
+ [SPORT_TYPE_SOCCER]: grassImage
32
40
  };
33
41
 
34
42
  const luceoSportsWatermark = await loadImage(`${STORAGE_URL}/${LUCEOSPORTS_WATERMARK_PATH}`);