123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- import { IBlock } from '../training/types'
- import { calculateDuration } from '../training/utils'
- import { IExerciseItem } from './types'
- /**
- * Find the right exercise given a certain time.
- * @param exerciseList
- * @param time
- */
- export function getPosition(exerciseList: IExerciseItem[], time: number) {
- const index = exerciseList.findIndex(
- exercise => time < exercise.offset + exercise.duration
- )
- const previousExercise = index >= 1 ? exerciseList[index - 1] : null
- const currentExercise = index >= 0 ? exerciseList[index] : null
- const nextExercise =
- index >= 0 && index < exerciseList.length - 1
- ? exerciseList[index + 1]
- : null
- const values = {
- currentExercise,
- nextExercise,
- previousExercise,
- exerciseTime: 0
- }
- if (currentExercise !== null) {
- values.exerciseTime = Math.max(time - currentExercise.offset, 0)
- }
- return values
- }
- /**
- * Takes a (nested) block of exercises and returns a flat array of exercises.
- * @param blocks
- * @param initialOffset - used for recursive application
- */
- export function getExerciseList(
- blocks: IBlock[],
- initialOffset = 0,
- toplevelBlock: undefined | string = undefined
- ): IExerciseItem[] {
- let offset = initialOffset
- return blocks
- .map(block => {
- if (block.blocks) {
- const blockArray = []
- for (let i = 0; i < (block.repetitions || 1); i++) {
- const subBlocks = getExerciseList(
- block.blocks,
- offset,
- toplevelBlock || block.title
- )
- const lastItem = subBlocks[subBlocks.length - 1]
- offset = lastItem.offset + lastItem.duration
- if (block.rest) {
- if (lastItem.exercise === 'Rest') {
- lastItem.duration += block.rest
- offset += block.rest
- } else {
- subBlocks.push({
- exercise: 'Rest',
- toplevelBlock: toplevelBlock || block.title,
- duration: block.rest,
- offset
- })
- offset += block.rest
- }
- }
- blockArray.push(subBlocks)
- }
- return blockArray.flat()
- } else if (block.exercises) {
- const blockArray: IExerciseItem[] = []
- const newItem = {
- exercise: block.exercises
- .map(exercise =>
- exercise.repetitions > 1
- ? `${exercise.repetitions}x ${exercise.name}`
- : exercise.name
- )
- .join(' - '),
- duration: calculateDuration(block),
- video: block.video,
- description: block.description,
- toplevelBlock: toplevelBlock || block.title,
- offset
- }
- for (let i = 0; i < (block.repetitions || 1); i++) {
- blockArray.push({ ...newItem, offset })
- offset += newItem.duration
- }
- return blockArray.flat()
- }
- })
- .flat()
- }
- export function getTrainingTime(exercises: IExerciseItem[]) {
- return exercises.reduce(
- (accumulator, exercise) => accumulator + exercise.duration,
- 0
- )
- }
- export function polarToCartesian(
- centerX: number,
- centerY: number,
- radius: number,
- angleInDegrees: number
- ) {
- const angleInRadians = ((angleInDegrees - 90) * Math.PI) / 180.0
- return {
- x: centerX + radius * Math.cos(angleInRadians),
- y: centerY + radius * Math.sin(angleInRadians)
- }
- }
- export function describeArc(
- x: number,
- y: number,
- radius: number,
- startAngle: number,
- endAngle: number
- ) {
- const start = polarToCartesian(x, y, radius, endAngle)
- const end = polarToCartesian(x, y, radius, startAngle)
- const largeArcFlag = endAngle - startAngle <= 180 ? '0' : '1'
- const arcString = `M ${start.x} ${start.y} A ${radius} ${radius} 0 ${largeArcFlag} 0 ${end.x} ${end.y}`
- return arcString
- }
- export function limit(value: number, min: number, max: number) {
- return Math.min(Math.max(min, value), max)
- }
|