@jpedro002/react-body-highlighter
Version:
React.js component for highlighting muscles on a body model
436 lines (431 loc) • 19.7 kB
JavaScript
// src/component/metadata.ts
var MuscleType = {
TRAPEZIUS: "trapezius",
UPPER_BACK: "upper-back",
LOWER_BACK: "lower-back",
CHEST: "chest",
BICEPS: "biceps",
TRICEPS: "triceps",
FOREARM: "forearm",
BACK_DELTOIDS: "back-deltoids",
FRONT_DELTOIDS: "front-deltoids",
ABS: "abs",
OBLIQUES: "obliques",
ABDUCTOR: "adductor",
ABDUCTORS: "abductors",
HAMSTRING: "hamstring",
QUADRICEPS: "quadriceps",
CALVES: "calves",
GLUTEAL: "gluteal",
HEAD: "head",
NECK: "neck",
KNEES: "knees",
LEFT_SOLEUS: "left-soleus",
RIGHT_SOLEUS: "right-soleus",
LEFT_HAND: "left-hand",
RIGHT_HAND: "right-hand",
LEFT_FOOT: "left-foot",
RIGHT_FOOT: "right-foot",
LEFT_EAR: "left-ear",
RIGHT_EAR: "right-ear"
};
var ModelType = {
POSTERIOR: "posterior",
ANTERIOR: "anterior"
};
// src/component/Model.tsx
import { memo } from "react";
// src/assets/index.ts
var anteriorData = [
{
muscle: MuscleType.CHEST,
svgPoints: [
"51.8367347 41.6326531 51.0204082 55.1020408 57.9591837 57.9591837 67.755102 55.5102041 70.6122449 47.3469388 62.0408163 41.6326531 ",
"29.7959184 46.5306122 31.4285714 55.5102041 40.8163265 57.9591837 48.1632653 55.1020408 47.755102 42.0408163 37.5510204 42.0408163"
]
},
{
muscle: MuscleType.OBLIQUES,
svgPoints: [
"68.5714286 63.2653061 67.3469388 57.1428571 58.7755102 59.5918367 60 64.0816327 60.4081633 83.2653061 65.7142857 78.7755102 66.5306122 69.7959184",
"33.877551 78.3673469 33.0612245 71.8367347 31.0204082 63.2653061 32.244898 57.1428571 40.8163265 59.1836735 39.1836735 63.2653061 39.1836735 83.6734694"
]
},
{
muscle: MuscleType.ABS,
svgPoints: [
"56.3265306 59.1836735 57.9591837 64.0816327 58.3673469 77.9591837 58.3673469 92.6530612 56.3265306 98.3673469 55.1020408 104.081633 51.4285714 107.755102 51.0204082 84.4897959 50.6122449 67.3469388 51.0204082 57.1428571",
"43.6734694 58.7755102 48.5714286 57.1428571 48.9795918 67.3469388 48.5714286 84.4897959 48.1632653 107.346939 44.4897959 103.673469 40.8163265 91.4285714 40.8163265 78.3673469 41.2244898 64.4897959"
]
},
{
muscle: MuscleType.BICEPS,
svgPoints: [
"16.7346939 68.1632653 17.9591837 71.4285714 22.8571429 66.122449 28.9795918 53.877551 27.755102 49.3877551 20.4081633 55.9183673",
"71.4285714 49.3877551 70.2040816 54.6938776 76.3265306 66.122449 81.6326531 71.8367347 82.8571429 68.9795918 78.7755102 55.5102041"
]
},
{
muscle: MuscleType.TRICEPS,
svgPoints: [
"69.3877551 55.5102041 69.3877551 61.6326531 75.9183673 72.6530612 77.5510204 70.2040816 75.5102041 67.3469388",
"22.4489796 69.3877551 29.7959184 55.5102041 29.7959184 60.8163265 22.8571429 73.0612245"
]
},
{
muscle: MuscleType.NECK,
svgPoints: [
"55.5102041 23.6734694 50.6122449 33.4693878 50.6122449 39.1836735 61.6326531 40 70.6122449 44.8979592 69.3877551 36.7346939 63.2653061 35.1020408 58.3673469 30.6122449",
"28.9795918 44.8979592 30.2040816 37.1428571 36.3265306 35.1020408 41.2244898 30.2040816 44.4897959 24.4897959 48.9795918 33.877551 48.5714286 39.1836735 37.9591837 39.5918367"
]
},
{
muscle: MuscleType.FRONT_DELTOIDS,
svgPoints: [
"78.3673469 53.0612245 79.5918367 47.755102 79.1836735 41.2244898 75.9183673 37.9591837 71.0204082 36.3265306 72.244898 42.8571429 71.4285714 47.3469388",
"28.1632653 47.3469388 21.2244898 53.0612245 20 47.755102 20.4081633 40.8163265 24.4897959 37.1428571 28.5714286 37.1428571 26.9387755 43.2653061"
]
},
{
muscle: MuscleType.HEAD,
svgPoints: [
"42.4489796 2.85714286 40 11.8367347 42.0408163 19.5918367 46.122449 23.2653061 49.7959184 25.3061224 54.6938776 22.4489796 57.5510204 19.1836735 59.1836735 10.2040816 57.1428571 2.44897959 49.7959184 0"
]
},
{
muscle: MuscleType.ABDUCTORS,
svgPoints: [
"52.6530612 110.204082 54.2857143 124.897959 60 110.204082 62.0408163 100 64.8979592 94.2857143 60 92.6530612 56.7346939 104.489796",
"47.755102 110.612245 44.8979592 125.306122 42.0408163 115.918367 40.4081633 113.061224 39.5918367 107.346939 37.9591837 102.44898 34.6938776 93.877551 39.5918367 92.244898 41.6326531 99.1836735 43.6734694 105.306122"
]
},
{
muscle: MuscleType.QUADRICEPS,
svgPoints: [
"34.6938776 98.7755102 37.1428571 108.163265 37.1428571 127.755102 34.2857143 137.142857 31.0204082 132.653061 29.3877551 120 28.1632653 111.428571 29.3877551 100.816327 32.244898 94.6938776",
"63.2653061 105.714286 64.4897959 100 66.9387755 94.6938776 70.2040816 101.22449 71.0204082 111.836735 68.1632653 133.061224 65.3061224 137.55102 62.4489796 128.571429 62.0408163 111.428571",
"38.7755102 129.387755 38.3673469 112.244898 41.2244898 118.367347 44.4897959 129.387755 42.8571429 135.102041 40 146.122449 36.3265306 146.530612 35.5102041 140",
"59.5918367 145.714286 55.5102041 128.979592 60.8163265 113.877551 61.2244898 130.204082 64.0816327 139.591837 62.8571429 146.530612",
"32.6530612 138.367347 26.5306122 145.714286 25.7142857 136.734694 25.7142857 127.346939 26.9387755 114.285714 29.3877551 133.469388",
"71.8367347 113.061224 73.877551 124.081633 73.877551 140.408163 72.6530612 145.714286 66.5306122 138.367347 70.2040816 133.469388"
]
},
{
muscle: MuscleType.KNEES,
svgPoints: [
"33.877551 140 34.6938776 143.265306 35.5102041 147.346939 36.3265306 151.020408 35.1020408 156.734694 29.7959184 156.734694 27.3469388 152.653061 27.3469388 147.346939 30.2040816 144.081633",
"65.7142857 140 72.244898 147.755102 72.244898 152.244898 69.7959184 157.142857 64.8979592 156.734694 62.8571429 151.020408"
]
},
{
muscle: MuscleType.CALVES,
svgPoints: [
"71.4285714 160.408163 73.4693878 153.469388 76.7346939 161.22449 79.5918367 167.755102 78.3673469 187.755102 79.5918367 195.510204 74.6938776 195.510204",
"24.8979592 194.693878 27.755102 164.897959 28.1632653 160.408163 26.122449 154.285714 24.8979592 157.55102 22.4489796 161.632653 20.8163265 167.755102 22.0408163 188.163265 20.8163265 195.510204",
"72.6530612 195.102041 69.7959184 159.183673 65.3061224 158.367347 64.0816327 162.44898 64.0816327 165.306122 65.7142857 177.142857",
"35.5102041 158.367347 35.9183673 162.44898 35.9183673 166.938776 35.1020408 172.244898 35.1020408 176.734694 32.244898 182.040816 30.6122449 187.346939 26.9387755 194.693878 27.3469388 187.755102 28.1632653 180.408163 28.5714286 175.510204 28.9795918 169.795918 29.7959184 164.081633 30.2040816 158.77551"
]
},
{
muscle: MuscleType.FOREARM,
svgPoints: [
"6.12244898 88.5714286 10.2040816 75.1020408 14.6938776 70.2040816 16.3265306 74.2857143 19.1836735 73.4693878 4.48979592 97.5510204 0 100",
"84.4897959 69.7959184 83.2653061 73.4693878 80 73.0612245 95.1020408 98.3673469 100 100.408163 93.4693878 89.3877551 89.7959184 76.3265306",
"77.5510204 72.244898 77.5510204 77.5510204 80.4081633 84.0816327 85.3061224 89.7959184 92.244898 101.22449 94.6938776 99.5918367",
"6.93877551 101.22449 13.4693878 90.6122449 18.7755102 84.0816327 21.6326531 77.1428571 21.2244898 71.8367347 4.89795918 98.7755102"
]
},
// Mãos removidas em favor dos tipos unilaterais
{
muscle: MuscleType.LEFT_HAND,
svgPoints: ["0 95 4 93 8 94 12 96 14 98 15 100 14 103 12 105 8 106 4 105 0 103 -2 100"]
},
{
muscle: MuscleType.RIGHT_HAND,
svgPoints: ["85 95 89 93 93 94 97 96 99 98 100 100 99 103 97 105 93 106 89 105 85 103 83 100"]
},
// Pés removidos em favor dos tipos unilaterais
{
muscle: MuscleType.LEFT_FOOT,
svgPoints: ["20 188 24 187 28 188 32 190 35 193 36 196 35 200 32 203 28 205 24 204 20 202 18 198 17 194 18 190"]
},
{
muscle: MuscleType.RIGHT_FOOT,
svgPoints: ["64 188 68 187 72 188 76 190 79 193 80 196 79 200 76 203 72 205 68 204 64 202 62 198 61 194 62 190"]
},
// Orelhas removidas em favor dos tipos unilaterais
{
muscle: MuscleType.LEFT_EAR,
svgPoints: ["34 12 36 10 38 11 39 14 40 17 39 20 37 22 35 21 34 19 33 16 34 12"]
},
{
muscle: MuscleType.RIGHT_EAR,
svgPoints: ["60 12 62 10 64 11 65 14 66 17 65 20 63 22 61 21 60 19 59 16 60 12"]
}
];
var posteriorData = [
{
muscle: MuscleType.HEAD,
svgPoints: [
"50.6382979 0 45.9574468 0.85106383 40.8510638 5.53191489 40.4255319 12.7659574 45.106383 20 55.7446809 20 59.1489362 13.6170213 59.5744681 4.68085106 55.7446809 1.27659574"
]
},
{
muscle: MuscleType.TRAPEZIUS,
svgPoints: [
"44.6808511 21.7021277 47.6595745 21.7021277 47.2340426 38.2978723 47.6595745 64.6808511 38.2978723 53.1914894 35.3191489 40.8510638 31.0638298 36.5957447 39.1489362 33.1914894 43.8297872 27.2340426",
"52.3404255 21.7021277 55.7446809 21.7021277 56.5957447 27.2340426 60.8510638 32.7659574 68.9361702 36.5957447 64.6808511 40.4255319 61.7021277 53.1914894 52.3404255 64.6808511 53.1914894 38.2978723"
]
},
{
muscle: MuscleType.BACK_DELTOIDS,
svgPoints: [
"29.3617021 37.0212766 22.9787234 39.1489362 17.4468085 44.2553191 18.2978723 53.6170213 24.2553191 49.3617021 27.2340426 46.3829787",
"71.0638298 37.0212766 78.2978723 39.5744681 82.5531915 44.6808511 81.7021277 53.6170213 74.893617 48.9361702 72.3404255 45.106383"
]
},
{
muscle: MuscleType.UPPER_BACK,
svgPoints: [
"31.0638298 38.7234043 28.0851064 48.9361702 28.5106383 55.3191489 34.0425532 75.3191489 47.2340426 71.0638298 47.2340426 66.3829787 36.5957447 54.0425532 33.6170213 41.2765957",
"68.9361702 38.7234043 71.9148936 49.3617021 71.4893617 56.1702128 65.9574468 75.3191489 52.7659574 71.0638298 52.7659574 66.3829787 63.4042553 54.4680851 66.3829787 41.7021277"
]
},
{
muscle: MuscleType.TRICEPS,
svgPoints: [
"26.8085106 49.787234 17.8723404 55.7446809 14.4680851 72.3404255 16.5957447 81.7021277 21.7021277 63.8297872 26.8085106 55.7446809",
"73.6170213 50.212766 82.1276596 55.7446809 85.9574468 73.1914894 83.4042553 82.1276596 77.8723404 62.9787234 73.1914894 55.7446809",
"26.8085106 58.2978723 26.8085106 68.5106383 22.9787234 75.3191489 19.1489362 77.4468085 22.5531915 65.5319149",
"72.7659574 58.2978723 77.0212766 64.6808511 80.4255319 77.4468085 76.5957447 75.3191489 72.7659574 68.9361702"
]
},
{
muscle: MuscleType.LOWER_BACK,
svgPoints: [
"47.6595745 72.7659574 34.4680851 77.0212766 35.3191489 83.4042553 49.3617021 102.12766 46.8085106 82.9787234",
"52.3404255 72.7659574 65.5319149 77.0212766 64.6808511 83.4042553 50.6382979 102.12766 53.1914894 83.8297872"
]
},
{
muscle: MuscleType.FOREARM,
svgPoints: [
"86.3829787 75.7446809 91.0638298 83.4042553 93.1914894 94.0425532 100 106.382979 96.1702128 104.255319 88.0851064 89.3617021 84.2553191 83.8297872",
"13.6170213 75.7446809 8.93617021 83.8297872 6.80851064 93.6170213 0 106.382979 3.82978723 104.255319 12.3404255 88.5106383 15.7446809 82.9787234",
"81.2765957 79.5744681 77.4468085 77.8723404 79.1489362 84.6808511 91.0638298 103.829787 93.1914894 108.93617 94.4680851 104.680851",
"18.7234043 79.5744681 22.1276596 77.8723404 20.8510638 84.2553191 9.36170213 102.978723 6.80851064 108.510638 5.10638298 104.680851"
]
},
{
muscle: MuscleType.GLUTEAL,
svgPoints: [
"44.6808511 99.5744681 30.212766 108.510638 29.787234 118.723404 31.4893617 125.957447 47.2340426 121.276596 49.3617021 114.893617",
"55.3191489 99.1489362 51.0638298 114.468085 52.3404255 120.851064 68.0851064 125.957447 69.787234 119.148936 69.3617021 108.510638"
]
},
{
muscle: MuscleType.ABDUCTOR,
svgPoints: [
"48.0851064 122.978723 44.6808511 122.978723 41.2765957 125.531915 45.106383 144.255319 48.5106383 135.744681 48.9361702 129.361702",
"51.9148936 122.553191 55.7446809 123.404255 59.1489362 125.957447 54.893617 144.255319 51.9148936 136.170213 51.0638298 129.361702"
]
},
{
muscle: MuscleType.HAMSTRING,
svgPoints: [
"28.9361702 122.12766 31.0638298 129.361702 36.5957447 125.957447 35.3191489 135.319149 34.4680851 150.212766 29.3617021 158.297872 28.9361702 146.808511 27.6595745 141.276596 27.2340426 131.489362",
"71.4893617 121.702128 69.3617021 128.93617 63.8297872 125.957447 65.5319149 136.595745 66.3829787 150.212766 71.0638298 158.297872 71.4893617 147.659574 72.7659574 142.12766 73.6170213 131.914894",
"38.7234043 125.531915 44.2553191 145.957447 40.4255319 166.808511 36.1702128 152.765957 37.0212766 135.319149",
"61.7021277 125.531915 63.4042553 136.170213 64.2553191 153.191489 60 166.808511 56.1702128 146.382979"
]
},
{
muscle: MuscleType.KNEES,
svgPoints: [
"34.4680851 153.191489 31.0638298 159.148936 33.6170213 166.382979 37.4468085 162.553191",
"66.3829787 153.617021 62.9787234 162.978723 66.8085106 166.382979 69.3617021 159.148936"
]
},
{
muscle: MuscleType.CALVES,
svgPoints: [
"29.3617021 160.425532 28.5106383 167.234043 24.6808511 179.574468 23.8297872 192.765957 25.5319149 197.021277 28.5106383 193.191489 29.787234 180 31.9148936 171.06383 31.9148936 166.808511",
"37.4468085 165.106383 35.3191489 167.659574 33.1914894 171.914894 31.0638298 180.425532 30.212766 191.914894 34.0425532 200 38.7234043 190.638298 39.1489362 168.93617",
"62.9787234 165.106383 61.2765957 168.510638 61.7021277 190.638298 66.3829787 199.574468 70.6382979 191.914894 68.9361702 179.574468 66.8085106 170.212766",
"70.6382979 160.425532 72.3404255 168.510638 75.7446809 179.148936 76.5957447 192.765957 74.4680851 196.595745 72.3404255 193.617021 70.6382979 179.574468 68.0851064 168.085106"
]
},
{
muscle: MuscleType.LEFT_SOLEUS,
svgPoints: [
"28.5106383 195.744681 30.212766 195.744681 33.6170213 201.702128 30.6382979 220 28.5106383 213.617021 26.8085106 198.297872"
]
},
{
muscle: MuscleType.RIGHT_SOLEUS,
svgPoints: [
"69.787234 195.744681 71.9148936 195.744681 73.6170213 198.297872 71.9148936 213.191489 70.212766 219.574468 67.2340426 202.12766"
]
},
{
muscle: MuscleType.LEFT_HAND,
svgPoints: ["0 105 4 103 8 104 12 106 14 108 15 110 14 113 12 115 8 116 4 115 0 113 -2 110"]
},
{
muscle: MuscleType.RIGHT_HAND,
svgPoints: ["85 100 89 98 93 99 97 101 99 103 100 105 99 108 97 110 93 111 89 110 85 108 83 105"]
},
{
muscle: MuscleType.LEFT_FOOT,
svgPoints: ["25 185 29 184 33 185 37 187 40 190 41 193 40 197 37 200 33 202 29 201 25 199 23 195 22 191 23 187"]
},
{
muscle: MuscleType.RIGHT_FOOT,
svgPoints: ["65 185 69 184 73 185 77 187 80 190 81 193 80 197 77 200 73 202 69 201 65 199 63 195 62 191 63 187"]
},
{
muscle: MuscleType.LEFT_EAR,
svgPoints: ["33 12 35 10 37 11 38 14 39 17 38 20 36 22 34 21 33 19 32 16 33 12"]
},
{
muscle: MuscleType.RIGHT_EAR,
svgPoints: ["61 12 63 10 65 11 66 14 67 17 66 20 64 22 62 21 61 19 60 16 61 12"]
}
];
// src/constants/index.ts
var DEFAULT_MUSCLE_DATA = {
trapezius: { exercises: [], frequency: 0 },
"upper-back": { exercises: [], frequency: 0 },
"lower-back": { exercises: [], frequency: 0 },
chest: { exercises: [], frequency: 0 },
biceps: { exercises: [], frequency: 0 },
triceps: { exercises: [], frequency: 0 },
forearm: { exercises: [], frequency: 0 },
"back-deltoids": { exercises: [], frequency: 0 },
"front-deltoids": { exercises: [], frequency: 0 },
abs: { exercises: [], frequency: 0 },
obliques: { exercises: [], frequency: 0 },
adductor: { exercises: [], frequency: 0 },
hamstring: { exercises: [], frequency: 0 },
quadriceps: { exercises: [], frequency: 0 },
abductors: { exercises: [], frequency: 0 },
calves: { exercises: [], frequency: 0 },
gluteal: { exercises: [], frequency: 0 },
head: { exercises: [], frequency: 0 },
neck: { exercises: [], frequency: 0 },
knees: { exercises: [], frequency: 0 },
"left-soleus": { exercises: [], frequency: 0 },
"right-soleus": { exercises: [], frequency: 0 },
"left-hand": { exercises: [], frequency: 0 },
"right-hand": { exercises: [], frequency: 0 },
"left-foot": { exercises: [], frequency: 0 },
"right-foot": { exercises: [], frequency: 0 },
"left-ear": { exercises: [], frequency: 0 },
"right-ear": { exercises: [], frequency: 0 }
};
var DEFAULT_BODY_COLOR = "#B6BDC3";
var DEFAULT_HIGHLIGHTED_COLORS = ["#81b1d9", "#277abf"];
var DEFAULT_MODEL_TYPE = ModelType.ANTERIOR;
// src/utils/index.ts
var ensure = (value, backupValue) => {
return value == null ? backupValue : value;
};
var fillIntensityColor = (activityMap, highlightedColors, muscle) => {
const frequency = activityMap[muscle]?.frequency;
if (frequency == null || frequency === 0) {
return void 0;
}
return highlightedColors[Math.min(highlightedColors.length - 1, frequency - 1)];
};
var fillMuscleData = (data) => {
return data.reduce(
(acc, exercise) => {
for (const muscle of exercise.muscles) {
acc[muscle].exercises = [...acc[muscle].exercises, exercise.name];
acc[muscle].frequency += exercise.frequency || 1;
}
return acc;
},
JSON.parse(JSON.stringify(DEFAULT_MUSCLE_DATA))
);
};
// src/component/Model.tsx
import { jsx, jsxs } from "react/jsx-runtime";
var Model_default = memo(function Model({
data = [],
bodyColor = DEFAULT_BODY_COLOR,
highlightedColors = DEFAULT_HIGHLIGHTED_COLORS,
onClick,
svgStyle,
style,
type = DEFAULT_MODEL_TYPE,
showHands = false,
showFeet = false,
showEars = false
}) {
const muscleData = fillMuscleData([...data]);
const modelData = type === ModelType.ANTERIOR ? anteriorData : posteriorData;
const filteredModelData = modelData.filter((exercise) => {
const muscle = exercise.muscle;
if (muscle === MuscleType.LEFT_HAND || muscle === MuscleType.RIGHT_HAND) {
return showHands;
}
if (muscle === MuscleType.LEFT_FOOT || muscle === MuscleType.RIGHT_FOOT) {
return showFeet;
}
if (muscle === MuscleType.LEFT_EAR || muscle === MuscleType.RIGHT_EAR) {
return showEars;
}
return true;
});
const handleClick = (muscle, callback) => {
callback?.({ muscle, data: muscleData[muscle] });
};
const handleKeyDown = (event, muscle) => {
if (event.key === "Enter" || event.key === " ") {
event.preventDefault();
handleClick(muscle, onClick);
}
};
return /* @__PURE__ */ jsx("div", { style, className: "rbh-wrapper", children: /* @__PURE__ */ jsxs(
"svg",
{
className: "rbh",
width: "100%",
height: "100%",
viewBox: "0 0 100 200",
role: "img",
"aria-label": "Interactive body muscle diagram",
style: {
...svgStyle
},
children: [
/* @__PURE__ */ jsx("title", { children: "Body muscle diagram for highlighting worked muscles" }),
filteredModelData.map(
(exercise) => exercise.svgPoints.map((points, index) => /* @__PURE__ */ jsx(
"polygon",
{
points,
tabIndex: 0,
role: "button",
"aria-label": `${exercise.muscle} muscle`,
onClick: () => handleClick(exercise.muscle, onClick),
onKeyDown: (e) => handleKeyDown(e, exercise.muscle),
style: {
cursor: "pointer",
fill: ensure(fillIntensityColor(muscleData, highlightedColors, exercise.muscle), bodyColor)
}
},
`${exercise.muscle}-${index}`
))
)
]
}
) });
});
export {
ModelType,
MuscleType,
Model_default as default
};
//# sourceMappingURL=index.mjs.map