@luceosports/play-rendering 2.3.0 → 2.4.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 (24) hide show
  1. package/dist/play-rendering.js +3 -3
  2. package/dist/play-rendering.js.map +1 -1
  3. package/dist/types/constants.d.ts +5 -0
  4. package/dist/types/types/index.d.ts +140 -138
  5. package/package.json +1 -1
  6. package/src/constants.ts +4 -0
  7. package/src/layers/court/index.ts +20 -1
  8. package/src/layers/court/layers/SOFTBALL/constants.ts +5 -0
  9. package/src/layers/court/layers/SOFTBALL/courtTypes/SOFTBALL_FP_COLLEGE/constants.ts +36 -0
  10. package/src/layers/court/layers/SOFTBALL/courtTypes/SOFTBALL_FP_COLLEGE/layers/ADirtLayer.ts +96 -0
  11. package/src/layers/court/layers/SOFTBALL/courtTypes/SOFTBALL_FP_COLLEGE/layers/BaseLineLayer.ts +99 -0
  12. package/src/layers/court/layers/SOFTBALL/courtTypes/SOFTBALL_FP_COLLEGE/layers/HomePlateLayer.ts +119 -0
  13. package/src/layers/court/layers/SOFTBALL/courtTypes/SOFTBALL_FP_COLLEGE/layers/PitchingMoundLayer.ts +39 -0
  14. package/src/layers/court/layers/SOFTBALL/courtTypes/SOFTBALL_FP_COLLEGE/layers/index.ts +6 -0
  15. package/src/layers/court/layers/SOFTBALL/courtTypes/SOFTBALL_FP_HIGH_SCHOOL/constants.ts +36 -0
  16. package/src/layers/court/layers/SOFTBALL/courtTypes/SOFTBALL_FP_HIGH_SCHOOL/layers/ADirtLayer.ts +96 -0
  17. package/src/layers/court/layers/SOFTBALL/courtTypes/SOFTBALL_FP_HIGH_SCHOOL/layers/BaseLineLayer.ts +99 -0
  18. package/src/layers/court/layers/SOFTBALL/courtTypes/SOFTBALL_FP_HIGH_SCHOOL/layers/HomePlateLayer.ts +119 -0
  19. package/src/layers/court/layers/SOFTBALL/courtTypes/SOFTBALL_FP_HIGH_SCHOOL/layers/PitchingMoundLayer.ts +39 -0
  20. package/src/layers/court/layers/SOFTBALL/courtTypes/SOFTBALL_FP_HIGH_SCHOOL/layers/index.ts +6 -0
  21. package/src/layers/court/layers/SOFTBALL/layers/BorderRectLayer.ts +10 -0
  22. package/src/layers/court/layers/SOFTBALL/layers/index.ts +3 -0
  23. package/src/models/PlayModel.ts +3 -1
  24. package/src/types/index.ts +5 -1
@@ -0,0 +1,119 @@
1
+ import InternalCourtLayer from '../../../../../base/InternalCourtLayer';
2
+
3
+ import {
4
+ BASE_LINE_LENGTH,
5
+ BATTERS_BOX_HEIGHT,
6
+ BATTERS_BOX_TO_CATCHERS_BACK_LINE,
7
+ BATTERS_BOX_WIDTH,
8
+ CATCHERS_BACK_LINE_LENGTH,
9
+ COACH_BOX_HEIGHT,
10
+ COACH_BOX_TO_BASE_LINE,
11
+ COACH_BOX_WIDTH,
12
+ HOME_PLATE_APEX_TO_BACKSTOP,
13
+ HOME_PLATE_CIRCLE_DIA,
14
+ HOME_PLATE_SIDE,
15
+ HOME_PLATE_SIDE_TO_BATTERS_BOX,
16
+ ON_DECK_CIRCLE_DIA,
17
+ ON_DECK_CIRCLE_DISTANCE_FROM_CENTER
18
+ } from '../constants';
19
+
20
+ export default class HomePlateLayer extends InternalCourtLayer {
21
+ original() {
22
+ return false;
23
+ }
24
+
25
+ reflection() {
26
+ return true;
27
+ }
28
+
29
+ drawLogic() {
30
+ const homePlateApex = { x: this.courtCenter.x, y: HOME_PLATE_APEX_TO_BACKSTOP };
31
+ const homePlateTopLineOrigin = { x: homePlateApex.x - HOME_PLATE_SIDE / 2, y: homePlateApex.y + HOME_PLATE_SIDE };
32
+ const homePlateTopLineTerminus = { x: homePlateApex.x + HOME_PLATE_SIDE / 2, y: homePlateApex.y + HOME_PLATE_SIDE };
33
+
34
+ // 1. Home Plate
35
+ this.ctx.beginPath();
36
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
37
+ this.ctx.moveTo(homePlateTopLineOrigin.x, homePlateTopLineOrigin.y);
38
+ this.ctx.lineTo(homePlateTopLineTerminus.x, homePlateTopLineTerminus.y);
39
+ this.ctx.lineTo(homePlateTopLineTerminus.x, homePlateTopLineTerminus.y - HOME_PLATE_SIDE / 2);
40
+ this.ctx.lineTo(homePlateApex.x, homePlateApex.y);
41
+ this.ctx.lineTo(homePlateTopLineOrigin.x, homePlateTopLineOrigin.y - HOME_PLATE_SIDE / 2);
42
+ this.ctx.lineTo(homePlateTopLineOrigin.x, homePlateTopLineOrigin.y);
43
+ this.ctx.stroke();
44
+ this.ctx.fill();
45
+
46
+ // // 2. Batters Box
47
+ // [-1, 1].forEach(sideIndex => {
48
+ // this.ctx.save();
49
+ // this.ctx.translate(homePlateApex.x, homePlateApex.y + HOME_PLATE_SIDE / 2);
50
+ // this.ctx.beginPath();
51
+ // const battersBoxClosestX = HOME_PLATE_SIDE / 2 + HOME_PLATE_SIDE_TO_BATTERS_BOX;
52
+ // this.ctx.moveTo(sideIndex * battersBoxClosestX, 0);
53
+ // this.ctx.lineTo(sideIndex * battersBoxClosestX, BATTERS_BOX_HEIGHT / 2);
54
+ // this.ctx.lineTo(sideIndex * (battersBoxClosestX + BATTERS_BOX_WIDTH), BATTERS_BOX_HEIGHT / 2);
55
+ // this.ctx.lineTo(sideIndex * (battersBoxClosestX + BATTERS_BOX_WIDTH), -BATTERS_BOX_HEIGHT / 2);
56
+ // this.ctx.lineTo(sideIndex * battersBoxClosestX, -BATTERS_BOX_HEIGHT / 2);
57
+ // this.ctx.lineTo(sideIndex * battersBoxClosestX, 0);
58
+ // this.ctx.stroke();
59
+ // this.ctx.restore();
60
+ // });
61
+
62
+ // 2. Batters Box
63
+ [-1, 1].forEach(sideIndex => {
64
+ this.ctx.save();
65
+ this.ctx.translate(homePlateApex.x, homePlateApex.y + HOME_PLATE_SIDE / 2);
66
+ this.ctx.beginPath();
67
+ const battersBoxClosestX = HOME_PLATE_SIDE / 2 + HOME_PLATE_SIDE_TO_BATTERS_BOX;
68
+ this.ctx.moveTo(sideIndex * battersBoxClosestX, 0);
69
+ this.ctx.lineTo(sideIndex * battersBoxClosestX, HOME_PLATE_SIDE / 2);
70
+ this.ctx.lineTo(sideIndex * (battersBoxClosestX + BATTERS_BOX_WIDTH), HOME_PLATE_SIDE / 2);
71
+ this.ctx.lineTo(sideIndex * (battersBoxClosestX + BATTERS_BOX_WIDTH), HOME_PLATE_SIDE / 2 - BATTERS_BOX_HEIGHT);
72
+ this.ctx.lineTo(sideIndex * battersBoxClosestX, HOME_PLATE_SIDE / 2 - BATTERS_BOX_HEIGHT);
73
+ this.ctx.lineTo(sideIndex * battersBoxClosestX, 0);
74
+ this.ctx.lineTo(sideIndex * battersBoxClosestX, 0);
75
+ this.ctx.stroke();
76
+ this.ctx.restore();
77
+ });
78
+
79
+ // 3. Catchers box
80
+ // const battersBoxNearestY = homePlateApex.y + HOME_PLATE_SIDE / 2 - BATTERS_BOX_HEIGHT / 2;
81
+ const battersBoxNearestY = homePlateApex.y + HOME_PLATE_SIDE / 2 - BATTERS_BOX_HEIGHT + HOME_PLATE_SIDE / 2;
82
+ [-1, 1].forEach(sideIndex => {
83
+ this.ctx.save();
84
+ this.ctx.translate(this.courtCenter.x, battersBoxNearestY - BATTERS_BOX_TO_CATCHERS_BACK_LINE);
85
+ this.ctx.beginPath();
86
+ this.ctx.moveTo(0, 0);
87
+ this.ctx.lineTo(sideIndex * (CATCHERS_BACK_LINE_LENGTH / 2), 0);
88
+ this.ctx.lineTo(sideIndex * (CATCHERS_BACK_LINE_LENGTH / 2), BATTERS_BOX_TO_CATCHERS_BACK_LINE);
89
+ this.ctx.stroke();
90
+ this.ctx.restore();
91
+ });
92
+
93
+ // 4. On Deck circles
94
+ [-1, 1].forEach(sideIndex => {
95
+ this.ctx.save();
96
+ this.ctx.translate(this.courtCenter.x, homePlateApex.y - HOME_PLATE_CIRCLE_DIA / 2);
97
+ this.ctx.beginPath();
98
+ this.ctx.arc(sideIndex * ON_DECK_CIRCLE_DISTANCE_FROM_CENTER, 0, ON_DECK_CIRCLE_DIA / 2, 0, Math.PI * 2, true);
99
+ this.ctx.stroke();
100
+ this.ctx.restore();
101
+ });
102
+
103
+ // 5. Coach boxes
104
+ [-1, 1].forEach(sideIndex => {
105
+ this.ctx.save();
106
+ this.ctx.translate(homePlateApex.x, homePlateApex.y);
107
+ this.ctx.rotate(sideIndex * (Math.PI / 4));
108
+
109
+ this.ctx.beginPath();
110
+ this.ctx.moveTo(sideIndex * BASE_LINE_LENGTH, -(COACH_BOX_TO_BASE_LINE + COACH_BOX_HEIGHT));
111
+ this.ctx.lineTo(sideIndex * BASE_LINE_LENGTH, -COACH_BOX_TO_BASE_LINE);
112
+ this.ctx.lineTo(sideIndex * (BASE_LINE_LENGTH - COACH_BOX_WIDTH), -COACH_BOX_TO_BASE_LINE);
113
+ this.ctx.lineTo(sideIndex * (BASE_LINE_LENGTH - COACH_BOX_WIDTH), -(COACH_BOX_TO_BASE_LINE + COACH_BOX_HEIGHT));
114
+ this.ctx.stroke();
115
+
116
+ this.ctx.restore();
117
+ });
118
+ }
119
+ }
@@ -0,0 +1,39 @@
1
+ import InternalCourtLayer from '../../../../../base/InternalCourtLayer';
2
+
3
+ import {
4
+ HOME_PLATE_APEX_TO_BACKSTOP,
5
+ HOME_PLATE_APEX_TO_PITCHERS_PLATE_FRONT,
6
+ PITCHERS_PLATE_HEIGHT,
7
+ PITCHERS_PLATE_WIDTH
8
+ } from '../constants';
9
+
10
+ export default class PitchingMoundLayer extends InternalCourtLayer {
11
+ original() {
12
+ return false;
13
+ }
14
+
15
+ reflection() {
16
+ return true;
17
+ }
18
+
19
+ drawLogic() {
20
+ const pitchersPlateFrontCenter = {
21
+ x: this.courtCenter.x,
22
+ y: HOME_PLATE_APEX_TO_BACKSTOP + HOME_PLATE_APEX_TO_PITCHERS_PLATE_FRONT - PITCHERS_PLATE_HEIGHT / 2
23
+ };
24
+
25
+ this.ctx.save();
26
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
27
+ this.ctx.beginPath();
28
+ this.ctx.translate(pitchersPlateFrontCenter.x, pitchersPlateFrontCenter.y);
29
+ this.ctx.moveTo(0, 0);
30
+ this.ctx.lineTo(PITCHERS_PLATE_WIDTH / 2, 0);
31
+ this.ctx.lineTo(PITCHERS_PLATE_WIDTH / 2, PITCHERS_PLATE_HEIGHT);
32
+ this.ctx.lineTo(-PITCHERS_PLATE_WIDTH / 2, PITCHERS_PLATE_HEIGHT);
33
+ this.ctx.lineTo(-PITCHERS_PLATE_WIDTH / 2, 0);
34
+ this.ctx.lineTo(0, 0);
35
+ this.ctx.stroke();
36
+ this.ctx.fill();
37
+ this.ctx.restore();
38
+ }
39
+ }
@@ -0,0 +1,6 @@
1
+ import ADirtLayer from './ADirtLayer';
2
+ import BaseLineLayer from './BaseLineLayer';
3
+ import HomePlateLayer from './HomePlateLayer';
4
+ import PitchingMoundLayer from './PitchingMoundLayer';
5
+
6
+ export { ADirtLayer, BaseLineLayer, HomePlateLayer, PitchingMoundLayer };
@@ -0,0 +1,36 @@
1
+ export const COURT_RECT_WIDTH = 300;
2
+ export const COURT_RECT_HEIGHT = 260;
3
+ export const COURT_DIRT_COLOR = '#C49463';
4
+ export const PITCHING_MOUND_COLOR = '#E4CCB7';
5
+
6
+ export const HOME_PLATE_APEX_TO_PITCHERS_PLATE_FRONT = 40;
7
+ export const HOME_PLATE_APEX_TO_SECOND_BASE_APEX = 127.28125;
8
+ export const HOME_PLATE_APEX_TO_BACKSTOP = 25;
9
+ export const HOME_PLATE_SIDE = 1.41667;
10
+ export const HOME_PLATE_CIRCLE_DIA = 26;
11
+
12
+ export const HOME_PLATE_SIDE_TO_BATTERS_BOX = 0.5;
13
+ export const BATTERS_BOX_WIDTH = 4;
14
+ export const BATTERS_BOX_HEIGHT = 6;
15
+ export const BATTERS_BOX_TO_CATCHERS_BACK_LINE = 5;
16
+
17
+ export const CATCHERS_BACK_LINE_LENGTH = 3.58333;
18
+ export const ON_DECK_CIRCLE_DIA = 5;
19
+ export const ON_DECK_CIRCLE_DISTANCE_FROM_CENTER = 37;
20
+
21
+ export const COACH_BOX_TO_BASE_LINE = 8;
22
+ export const COACH_BOX_WIDTH = 15;
23
+ export const COACH_BOX_HEIGHT = 3;
24
+
25
+ export const PITCHERS_PLATE_WIDTH = 5;
26
+ export const PITCHERS_PLATE_HEIGHT = 1;
27
+ export const PITCHERS_PLATE_TO_PITCHING_MOUND_CENTER = 0;
28
+ export const PITCHING_MOUND_DIA = 16;
29
+
30
+ export const PITCHERS_PLATE_GRASS_LINE_RAD = 60;
31
+
32
+ export const HOME_RUN_FENCE_CENTER_DISTANCE = 225;
33
+ export const FOUL_LINE_LENGTH = 200;
34
+ export const BASE_LINE_LENGTH = 60;
35
+ export const BASE_SQUARE_SIDE_LENGTH = 2.5;
36
+ export const BASE_DIRT_RAD = 13;
@@ -0,0 +1,96 @@
1
+ import InternalCourtLayer from '../../../../../base/InternalCourtLayer';
2
+
3
+ import {
4
+ BASE_DIRT_RAD,
5
+ BASE_LINE_LENGTH,
6
+ COURT_DIRT_COLOR,
7
+ HOME_PLATE_APEX_TO_BACKSTOP,
8
+ HOME_PLATE_APEX_TO_PITCHERS_PLATE_FRONT,
9
+ HOME_PLATE_CIRCLE_DIA,
10
+ PITCHERS_PLATE_GRASS_LINE_RAD,
11
+ PITCHERS_PLATE_TO_PITCHING_MOUND_CENTER,
12
+ PITCHING_MOUND_COLOR,
13
+ PITCHING_MOUND_DIA
14
+ } from '../constants';
15
+ import { CourtPoint } from '../../../../../../../types';
16
+
17
+ export default class ADirtLayer extends InternalCourtLayer {
18
+ original() {
19
+ return false;
20
+ }
21
+
22
+ reflection() {
23
+ return true;
24
+ }
25
+
26
+ drawLogic() {
27
+ const homePlateApex = { x: this.courtCenter.x, y: HOME_PLATE_APEX_TO_BACKSTOP };
28
+ const pitchersPlateFrontCenter = {
29
+ x: this.courtCenter.x,
30
+ y: HOME_PLATE_APEX_TO_BACKSTOP + HOME_PLATE_APEX_TO_PITCHERS_PLATE_FRONT
31
+ };
32
+
33
+ const style = this.options.lineColor === 'transparent' ? 'transparent' : COURT_DIRT_COLOR;
34
+ this.ctx.fillStyle = style;
35
+ this.ctx.strokeStyle = style;
36
+
37
+ // 1. Gras line
38
+ const arcStartAngle = Math.PI / 13;
39
+ const arcEndAngle = Math.PI - Math.PI / 13;
40
+
41
+ this.ctx.save();
42
+ this.ctx.beginPath();
43
+ this.ctx.arc(
44
+ pitchersPlateFrontCenter.x,
45
+ pitchersPlateFrontCenter.y,
46
+ PITCHERS_PLATE_GRASS_LINE_RAD,
47
+ arcStartAngle,
48
+ arcEndAngle,
49
+ false
50
+ );
51
+
52
+ const arcEdgePointLeft = getArcPointForAngle(pitchersPlateFrontCenter, PITCHERS_PLATE_GRASS_LINE_RAD, arcEndAngle);
53
+ const arcEdgePointRight = getArcPointForAngle(
54
+ pitchersPlateFrontCenter,
55
+ PITCHERS_PLATE_GRASS_LINE_RAD,
56
+ arcStartAngle
57
+ );
58
+
59
+ this.ctx.moveTo(arcEdgePointLeft.x, arcEdgePointLeft.y);
60
+ this.ctx.lineTo(homePlateApex.x, homePlateApex.y - Math.sqrt(3 * 3 + 3 * 3));
61
+ this.ctx.lineTo(arcEdgePointRight.x, arcEdgePointRight.y);
62
+ this.ctx.lineTo(arcEdgePointLeft.x, arcEdgePointLeft.y);
63
+
64
+ this.ctx.fill();
65
+ this.ctx.restore();
66
+
67
+ // 2. Pitching mound
68
+ this.ctx.save();
69
+ this.ctx.strokeStyle = this.options.lineColor === 'transparent' ? 'transparent' : '#FFFFFF';
70
+ this.ctx.fillStyle = this.options.lineColor === 'transparent' ? 'transparent' : PITCHING_MOUND_COLOR;
71
+ this.ctx.beginPath();
72
+ this.ctx.arc(
73
+ pitchersPlateFrontCenter.x,
74
+ pitchersPlateFrontCenter.y - PITCHERS_PLATE_TO_PITCHING_MOUND_CENTER,
75
+ PITCHING_MOUND_DIA / 2,
76
+ 0,
77
+ Math.PI * 2,
78
+ true
79
+ );
80
+ this.ctx.fill();
81
+ this.ctx.stroke();
82
+ this.ctx.restore();
83
+
84
+ // 3. Home plate circle
85
+ this.ctx.save();
86
+ this.ctx.beginPath();
87
+ this.ctx.arc(homePlateApex.x, homePlateApex.y, HOME_PLATE_CIRCLE_DIA / 2, 0, Math.PI * 2, true);
88
+ this.ctx.stroke();
89
+ this.ctx.fill();
90
+ this.ctx.restore();
91
+ }
92
+ }
93
+
94
+ function getArcPointForAngle(c: CourtPoint, radius: number, angle: number) {
95
+ return { x: c.x + Math.cos(angle) * radius, y: c.y + Math.sin(angle) * radius };
96
+ }
@@ -0,0 +1,99 @@
1
+ import InternalCourtLayer from '../../../../../base/InternalCourtLayer';
2
+
3
+ import {
4
+ BASE_LINE_LENGTH,
5
+ BASE_SQUARE_SIDE_LENGTH,
6
+ FOUL_LINE_LENGTH,
7
+ HOME_PLATE_APEX_TO_BACKSTOP,
8
+ HOME_RUN_FENCE_CENTER_DISTANCE,
9
+ PITCHERS_PLATE_GRASS_LINE_RAD
10
+ } from '../constants';
11
+
12
+ export default class BaseLineLayer extends InternalCourtLayer {
13
+ original() {
14
+ return false;
15
+ }
16
+
17
+ reflection() {
18
+ return true;
19
+ }
20
+
21
+ drawLogic() {
22
+ const homePlateApex = { x: this.courtCenter.x, y: HOME_PLATE_APEX_TO_BACKSTOP };
23
+
24
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 3;
25
+
26
+ this.ctx.save();
27
+ this.ctx.translate(homePlateApex.x, homePlateApex.y);
28
+ this.ctx.rotate(Math.PI / 4);
29
+
30
+ this.ctx.beginPath();
31
+ this.ctx.moveTo(0, 0);
32
+ this.ctx.lineTo(BASE_LINE_LENGTH, 0);
33
+ this.ctx.stroke();
34
+ this.drawBaseSquare(BASE_LINE_LENGTH, 0);
35
+
36
+ // line between 1st & 2nd bases
37
+ // this.ctx.beginPath();
38
+ // this.ctx.moveTo(BASE_LINE_LENGTH, 0);
39
+ // this.ctx.lineTo(BASE_LINE_LENGTH, BASE_LINE_LENGTH);
40
+ // this.ctx.stroke();
41
+ this.drawBaseSquare(BASE_LINE_LENGTH + BASE_SQUARE_SIDE_LENGTH / 2, BASE_LINE_LENGTH - BASE_SQUARE_SIDE_LENGTH / 2);
42
+
43
+ // line between 2st & 3nd bases
44
+ // this.ctx.beginPath();
45
+ // this.ctx.moveTo(BASE_LINE_LENGTH, BASE_LINE_LENGTH);
46
+ // this.ctx.lineTo(0, BASE_LINE_LENGTH);
47
+ // this.ctx.stroke();
48
+ this.drawBaseSquare(BASE_SQUARE_SIDE_LENGTH, BASE_LINE_LENGTH - BASE_SQUARE_SIDE_LENGTH);
49
+
50
+ this.ctx.beginPath();
51
+ this.ctx.lineTo(0, 0);
52
+ this.ctx.stroke();
53
+ this.ctx.restore();
54
+
55
+ // Foul lines
56
+ [-1, 1].forEach(sideIndex => {
57
+ this.ctx.save();
58
+ this.ctx.translate(homePlateApex.x, homePlateApex.y);
59
+ this.ctx.rotate(sideIndex * (Math.PI / 4));
60
+ this.ctx.beginPath();
61
+ this.ctx.moveTo(0, 0);
62
+ this.ctx.lineTo(sideIndex * FOUL_LINE_LENGTH, 0);
63
+ this.ctx.stroke();
64
+ this.ctx.restore();
65
+ });
66
+
67
+ // Home run arc
68
+ const homeRunArcCenterOffsetY = 71;
69
+ const homeRunArcStartAngle = Math.PI / 6.8;
70
+ const homeRunArcEndAngle = Math.PI - Math.PI / 6.8;
71
+ this.ctx.save();
72
+ this.ctx.beginPath();
73
+ this.ctx.arc(
74
+ homePlateApex.x,
75
+ homePlateApex.y + homeRunArcCenterOffsetY,
76
+ HOME_RUN_FENCE_CENTER_DISTANCE - homeRunArcCenterOffsetY + 4,
77
+ homeRunArcStartAngle,
78
+ homeRunArcEndAngle,
79
+ false
80
+ );
81
+ this.ctx.stroke();
82
+ this.ctx.restore();
83
+ }
84
+
85
+ drawBaseSquare(x: number, y: number) {
86
+ this.ctx.save();
87
+ this.ctx.lineCap = 'square';
88
+ this.ctx.beginPath();
89
+ this.ctx.translate(x, y);
90
+ this.ctx.moveTo(0, 0);
91
+ this.ctx.lineTo(0, BASE_SQUARE_SIDE_LENGTH);
92
+ this.ctx.lineTo(-BASE_SQUARE_SIDE_LENGTH, BASE_SQUARE_SIDE_LENGTH);
93
+ this.ctx.lineTo(-BASE_SQUARE_SIDE_LENGTH, 0);
94
+ this.ctx.lineTo(0, 0);
95
+ this.ctx.stroke();
96
+ this.ctx.fill();
97
+ this.ctx.restore();
98
+ }
99
+ }
@@ -0,0 +1,119 @@
1
+ import InternalCourtLayer from '../../../../../base/InternalCourtLayer';
2
+
3
+ import {
4
+ BASE_LINE_LENGTH,
5
+ BATTERS_BOX_HEIGHT,
6
+ BATTERS_BOX_TO_CATCHERS_BACK_LINE,
7
+ BATTERS_BOX_WIDTH,
8
+ CATCHERS_BACK_LINE_LENGTH,
9
+ COACH_BOX_HEIGHT,
10
+ COACH_BOX_TO_BASE_LINE,
11
+ COACH_BOX_WIDTH,
12
+ HOME_PLATE_APEX_TO_BACKSTOP,
13
+ HOME_PLATE_CIRCLE_DIA,
14
+ HOME_PLATE_SIDE,
15
+ HOME_PLATE_SIDE_TO_BATTERS_BOX,
16
+ ON_DECK_CIRCLE_DIA,
17
+ ON_DECK_CIRCLE_DISTANCE_FROM_CENTER
18
+ } from '../constants';
19
+
20
+ export default class HomePlateLayer extends InternalCourtLayer {
21
+ original() {
22
+ return false;
23
+ }
24
+
25
+ reflection() {
26
+ return true;
27
+ }
28
+
29
+ drawLogic() {
30
+ const homePlateApex = { x: this.courtCenter.x, y: HOME_PLATE_APEX_TO_BACKSTOP };
31
+ const homePlateTopLineOrigin = { x: homePlateApex.x - HOME_PLATE_SIDE / 2, y: homePlateApex.y + HOME_PLATE_SIDE };
32
+ const homePlateTopLineTerminus = { x: homePlateApex.x + HOME_PLATE_SIDE / 2, y: homePlateApex.y + HOME_PLATE_SIDE };
33
+
34
+ // 1. Home Plate
35
+ this.ctx.beginPath();
36
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
37
+ this.ctx.moveTo(homePlateTopLineOrigin.x, homePlateTopLineOrigin.y);
38
+ this.ctx.lineTo(homePlateTopLineTerminus.x, homePlateTopLineTerminus.y);
39
+ this.ctx.lineTo(homePlateTopLineTerminus.x, homePlateTopLineTerminus.y - HOME_PLATE_SIDE / 2);
40
+ this.ctx.lineTo(homePlateApex.x, homePlateApex.y);
41
+ this.ctx.lineTo(homePlateTopLineOrigin.x, homePlateTopLineOrigin.y - HOME_PLATE_SIDE / 2);
42
+ this.ctx.lineTo(homePlateTopLineOrigin.x, homePlateTopLineOrigin.y);
43
+ this.ctx.stroke();
44
+ this.ctx.fill();
45
+
46
+ // // 2. Batters Box
47
+ // [-1, 1].forEach(sideIndex => {
48
+ // this.ctx.save();
49
+ // this.ctx.translate(homePlateApex.x, homePlateApex.y + HOME_PLATE_SIDE / 2);
50
+ // this.ctx.beginPath();
51
+ // const battersBoxClosestX = HOME_PLATE_SIDE / 2 + HOME_PLATE_SIDE_TO_BATTERS_BOX;
52
+ // this.ctx.moveTo(sideIndex * battersBoxClosestX, 0);
53
+ // this.ctx.lineTo(sideIndex * battersBoxClosestX, BATTERS_BOX_HEIGHT / 2);
54
+ // this.ctx.lineTo(sideIndex * (battersBoxClosestX + BATTERS_BOX_WIDTH), BATTERS_BOX_HEIGHT / 2);
55
+ // this.ctx.lineTo(sideIndex * (battersBoxClosestX + BATTERS_BOX_WIDTH), -BATTERS_BOX_HEIGHT / 2);
56
+ // this.ctx.lineTo(sideIndex * battersBoxClosestX, -BATTERS_BOX_HEIGHT / 2);
57
+ // this.ctx.lineTo(sideIndex * battersBoxClosestX, 0);
58
+ // this.ctx.stroke();
59
+ // this.ctx.restore();
60
+ // });
61
+
62
+ // 2. Batters Box
63
+ [-1, 1].forEach(sideIndex => {
64
+ this.ctx.save();
65
+ this.ctx.translate(homePlateApex.x, homePlateApex.y + HOME_PLATE_SIDE / 2);
66
+ this.ctx.beginPath();
67
+ const battersBoxClosestX = HOME_PLATE_SIDE / 2 + HOME_PLATE_SIDE_TO_BATTERS_BOX;
68
+ this.ctx.moveTo(sideIndex * battersBoxClosestX, 0);
69
+ this.ctx.lineTo(sideIndex * battersBoxClosestX, HOME_PLATE_SIDE / 2);
70
+ this.ctx.lineTo(sideIndex * (battersBoxClosestX + BATTERS_BOX_WIDTH), HOME_PLATE_SIDE / 2);
71
+ this.ctx.lineTo(sideIndex * (battersBoxClosestX + BATTERS_BOX_WIDTH), HOME_PLATE_SIDE / 2 - BATTERS_BOX_HEIGHT);
72
+ this.ctx.lineTo(sideIndex * battersBoxClosestX, HOME_PLATE_SIDE / 2 - BATTERS_BOX_HEIGHT);
73
+ this.ctx.lineTo(sideIndex * battersBoxClosestX, 0);
74
+ this.ctx.lineTo(sideIndex * battersBoxClosestX, 0);
75
+ this.ctx.stroke();
76
+ this.ctx.restore();
77
+ });
78
+
79
+ // 3. Catchers box
80
+ // const battersBoxNearestY = homePlateApex.y + HOME_PLATE_SIDE / 2 - BATTERS_BOX_HEIGHT / 2;
81
+ const battersBoxNearestY = homePlateApex.y + HOME_PLATE_SIDE / 2 - BATTERS_BOX_HEIGHT + HOME_PLATE_SIDE / 2;
82
+ [-1, 1].forEach(sideIndex => {
83
+ this.ctx.save();
84
+ this.ctx.translate(this.courtCenter.x, battersBoxNearestY - BATTERS_BOX_TO_CATCHERS_BACK_LINE);
85
+ this.ctx.beginPath();
86
+ this.ctx.moveTo(0, 0);
87
+ this.ctx.lineTo(sideIndex * (CATCHERS_BACK_LINE_LENGTH / 2), 0);
88
+ this.ctx.lineTo(sideIndex * (CATCHERS_BACK_LINE_LENGTH / 2), BATTERS_BOX_TO_CATCHERS_BACK_LINE);
89
+ this.ctx.stroke();
90
+ this.ctx.restore();
91
+ });
92
+
93
+ // 4. On Deck circles
94
+ [-1, 1].forEach(sideIndex => {
95
+ this.ctx.save();
96
+ this.ctx.translate(this.courtCenter.x, homePlateApex.y - HOME_PLATE_CIRCLE_DIA / 2);
97
+ this.ctx.beginPath();
98
+ this.ctx.arc(sideIndex * ON_DECK_CIRCLE_DISTANCE_FROM_CENTER, 0, ON_DECK_CIRCLE_DIA / 2, 0, Math.PI * 2, true);
99
+ this.ctx.stroke();
100
+ this.ctx.restore();
101
+ });
102
+
103
+ // 5. Coach boxes
104
+ [-1, 1].forEach(sideIndex => {
105
+ this.ctx.save();
106
+ this.ctx.translate(homePlateApex.x, homePlateApex.y);
107
+ this.ctx.rotate(sideIndex * (Math.PI / 4));
108
+
109
+ this.ctx.beginPath();
110
+ this.ctx.moveTo(sideIndex * BASE_LINE_LENGTH, -(COACH_BOX_TO_BASE_LINE + COACH_BOX_HEIGHT));
111
+ this.ctx.lineTo(sideIndex * BASE_LINE_LENGTH, -COACH_BOX_TO_BASE_LINE);
112
+ this.ctx.lineTo(sideIndex * (BASE_LINE_LENGTH - COACH_BOX_WIDTH), -COACH_BOX_TO_BASE_LINE);
113
+ this.ctx.lineTo(sideIndex * (BASE_LINE_LENGTH - COACH_BOX_WIDTH), -(COACH_BOX_TO_BASE_LINE + COACH_BOX_HEIGHT));
114
+ this.ctx.stroke();
115
+
116
+ this.ctx.restore();
117
+ });
118
+ }
119
+ }
@@ -0,0 +1,39 @@
1
+ import InternalCourtLayer from '../../../../../base/InternalCourtLayer';
2
+
3
+ import {
4
+ HOME_PLATE_APEX_TO_BACKSTOP,
5
+ HOME_PLATE_APEX_TO_PITCHERS_PLATE_FRONT,
6
+ PITCHERS_PLATE_HEIGHT,
7
+ PITCHERS_PLATE_WIDTH
8
+ } from '../constants';
9
+
10
+ export default class PitchingMoundLayer extends InternalCourtLayer {
11
+ original() {
12
+ return false;
13
+ }
14
+
15
+ reflection() {
16
+ return true;
17
+ }
18
+
19
+ drawLogic() {
20
+ const pitchersPlateFrontCenter = {
21
+ x: this.courtCenter.x,
22
+ y: HOME_PLATE_APEX_TO_BACKSTOP + HOME_PLATE_APEX_TO_PITCHERS_PLATE_FRONT - PITCHERS_PLATE_HEIGHT / 2
23
+ };
24
+
25
+ this.ctx.save();
26
+ this.ctx.lineWidth = this.courtTypeConstants.COURT_LINE_WIDTH * 2;
27
+ this.ctx.beginPath();
28
+ this.ctx.translate(pitchersPlateFrontCenter.x, pitchersPlateFrontCenter.y);
29
+ this.ctx.moveTo(0, 0);
30
+ this.ctx.lineTo(PITCHERS_PLATE_WIDTH / 2, 0);
31
+ this.ctx.lineTo(PITCHERS_PLATE_WIDTH / 2, PITCHERS_PLATE_HEIGHT);
32
+ this.ctx.lineTo(-PITCHERS_PLATE_WIDTH / 2, PITCHERS_PLATE_HEIGHT);
33
+ this.ctx.lineTo(-PITCHERS_PLATE_WIDTH / 2, 0);
34
+ this.ctx.lineTo(0, 0);
35
+ this.ctx.stroke();
36
+ this.ctx.fill();
37
+ this.ctx.restore();
38
+ }
39
+ }
@@ -0,0 +1,6 @@
1
+ import ADirtLayer from './ADirtLayer';
2
+ import BaseLineLayer from './BaseLineLayer';
3
+ import HomePlateLayer from './HomePlateLayer';
4
+ import PitchingMoundLayer from './PitchingMoundLayer';
5
+
6
+ export { ADirtLayer, BaseLineLayer, HomePlateLayer, PitchingMoundLayer };
@@ -0,0 +1,10 @@
1
+ import InternalCourtLayer from '../../../base/InternalCourtLayer';
2
+
3
+ export default 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
+ }
@@ -0,0 +1,3 @@
1
+ import BorderRectLayer from './BorderRectLayer';
2
+
3
+ export { BorderRectLayer };
@@ -11,6 +11,7 @@ import {
11
11
  SPORT_TYPE_LACROSSE,
12
12
  SPORT_TYPE_LACROSSE_BOX,
13
13
  SPORT_TYPE_SOCCER,
14
+ SPORT_TYPE_SOFTBALL,
14
15
  SPORT_TYPE_VOLLEYBALL
15
16
  } from '../constants';
16
17
 
@@ -121,7 +122,8 @@ export default class PlayModel {
121
122
  [SPORT_TYPE_LACROSSE_BOX]: grassImage,
122
123
  [SPORT_TYPE_SOCCER]: grassImage,
123
124
  [SPORT_TYPE_HOCKEY]: iceImage,
124
- [SPORT_TYPE_BASEBALL]: grassImage
125
+ [SPORT_TYPE_BASEBALL]: grassImage,
126
+ [SPORT_TYPE_SOFTBALL]: grassImage
125
127
  };
126
128
 
127
129
  const luceoSportsWatermark = await loadImage(`${STORAGE_URL}/${LUCEOSPORTS_WATERMARK_PATH}`);
@@ -20,7 +20,8 @@ export type SportType =
20
20
  | 'LACROSSE_BOX'
21
21
  | 'SOCCER'
22
22
  | 'HOCKEY'
23
- | 'BASEBALL';
23
+ | 'BASEBALL'
24
+ | 'SOFTBALL';
24
25
 
25
26
  export type CourtTypeSportBasketball =
26
27
  | 'BIG3'
@@ -46,6 +47,8 @@ export type CourtTypeSportHockey = 'HOCKEY_NHL' | 'HOCKEY_INTERNATIONAL';
46
47
 
47
48
  export type CourtTypeSportBaseball = 'BASEBALL_HIGH_SCHOOL';
48
49
 
50
+ export type CourtTypeSportSoftball = 'SOFTBALL_FP_COLLEGE' | 'SOFTBALL_FP_HS';
51
+
49
52
  export type CourtTypeSportLacrosse = 'LACROSSE_US_M' | 'LACROSSE_US_W';
50
53
 
51
54
  export type CourtTypeSportLacrosseBox = 'LACROSSE_BOX_US';
@@ -62,6 +65,7 @@ export type CourtType =
62
65
  | CourtTypeSportSoccer
63
66
  | CourtTypeSportHockey
64
67
  | CourtTypeSportBaseball
68
+ | CourtTypeSportSoftball
65
69
  | CourtTypeSportFootball
66
70
  | CourtTypeSportFootballLegacy;
67
71