UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

57 lines (56 loc) 1.89 kB
"use strict"; import { CubicBezierCurve, Vector2 } from "three"; import { keyframeTangentToEndPoint } from "../KeyframeTangent"; const _v2 = new Vector2(); const _endPt0 = new Vector2(); const _endPt1 = new Vector2(); export const curve = new CubicBezierCurve(new Vector2(), new Vector2(), new Vector2(), new Vector2()); export const setCurveFromKeyframePairCubic = (keyframeStart, keyframeEnd) => { keyframeTangentToEndPoint(keyframeStart, false, _endPt0); keyframeTangentToEndPoint(keyframeEnd, true, _endPt1); curve.v0.x = keyframeStart.pos; curve.v0.y = keyframeStart.value; curve.v1.x = keyframeStart.pos + _endPt0.x; curve.v1.y = keyframeStart.value + _endPt0.y; curve.v3.x = keyframeEnd.pos; curve.v3.y = keyframeEnd.value; curve.v2.x = keyframeEnd.pos - _endPt1.x; curve.v2.y = keyframeEnd.value - _endPt1.y; }; function getX(t, curve2) { curve2.getPoint(t, _v2); return _v2.x; } const MAX_ITERATIONS = 500; const EPSILON = 1e-6; const range = { min: 0, max: 1 }; function findTForXCubic(expectedX) { const curveStartPos = curve.v0.x; const curveEndPos = curve.v3.x; range.min = curveStartPos; range.max = curveEndPos; function _normalizePos(_pos) { return (_pos - curveStartPos) / (curveEndPos - curveStartPos); } let currentX = expectedX; for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) { const foundX = getX(_normalizePos(currentX), curve); const delta = foundX - expectedX; if (Math.abs(delta) < EPSILON) { return _normalizePos(currentX); } if (foundX < expectedX) { range.min = currentX; currentX = (range.max + currentX) / 2; } else { range.max = currentX; currentX = (range.min + currentX) / 2; } } return _normalizePos(currentX); } export function getValueCubic(pos) { const t = findTForXCubic(pos); curve.getPoint(t, _v2); return _v2.y; }