2024-03-11 01:33:47 +08:00

58 lines
2.7 KiB
TypeScript

import { DRAW_INTERPOLATION_RADIUS_THRESHOLD, DRAW_INTERPOLATION_STEP_BASE } from '../constants'
import { MouseMovements } from '../types/common'
import { ComputedMovements, InImageRangeConfig, InterpolationStep, RenderInterpolationConfig } from '../types/drawing'
const { sign, abs, max } = Math
/** 判断坐标位置是否在绘制的图像的范围内 */
export function isInImageRange(inRangeConfig: InImageRangeConfig): boolean {
const { x, y, minX, maxX, minY, maxY } = inRangeConfig
return x >= minX && x <= maxX && y >= minY && y <= maxY
}
/** 计算x/y轴方向移动距离及水平/垂直方向上的最大移动距离 */
export function computeMovements(movements: MouseMovements): ComputedMovements {
const { movementX, movementY } = movements
const unsignedMovementX = abs(movementX)
const unsignedMovementY = abs(movementY)
const maxMovement = max(unsignedMovementX, unsignedMovementY)
return { unsignedMovementX, unsignedMovementY, maxMovement }
}
/** 是否需要插值渲染 */
export function needDrawInterpolation(maxMovement: number, radius: number): boolean {
return radius > DRAW_INTERPOLATION_RADIUS_THRESHOLD && maxMovement > radius / DRAW_INTERPOLATION_STEP_BASE
}
/** 计算插值的步长 */
export function computeInterpolationStep(interpolationConfig: RenderInterpolationConfig): InterpolationStep {
const { drawingConfig, unsignedMovementX, unsignedMovementY, maxMovement } = interpolationConfig
const { movementX, movementY, stepBase } = drawingConfig
const rawStepX = computePivotRawStep(movementX, stepBase)
const rawStepY = computePivotRawStep(movementY, stepBase)
const movementXIsMaximum = isMaxMovement(unsignedMovementX, maxMovement)
const stepX = computePivotStep(movementXIsMaximum, rawStepX, unsignedMovementX, unsignedMovementY)
const stepY = computePivotStep(!movementXIsMaximum, rawStepY, unsignedMovementY, unsignedMovementX)
return { stepX, stepY }
}
/** 计算x/y轴方向上朝上一次鼠标指针位置的插值步长 */
function computePivotRawStep(pivotMovement: number, stepBase: number) {
return -sign(pivotMovement) * stepBase
}
/** 是否为最大移动距离 */
function isMaxMovement(pivotMovement: number, maxMovement: number) {
return pivotMovement === maxMovement
}
/** 计算x/y轴方向的累加步长 */
function computePivotStep(isMaxMovement: boolean, rawStepOfPivot: number, unsignedPivotMovement: number, unsignedCrossedMovement: number) {
return isMaxMovement ? rawStepOfPivot : (unsignedPivotMovement / unsignedCrossedMovement) * rawStepOfPivot
}
/** 判断是否需要绘制插值圆点 */
export function needDrawInterpolationPoint(movement: number, moved: number, step: number) {
return movement - moved > step
}