11const DEGREES_PER_RADIAN = 180 / Math . PI ;
22const RADIANS_PER_DEGREE = Math . PI / 180 ;
3+ const DEFAULT_OBJECT_VECTOR_BOUNDS = Object . freeze ( { height : 80 , width : 120 , x : - 60 , y : - 40 } ) ;
34
45function isRecord ( value ) {
56 return Boolean ( value ) && typeof value === "object" && ! Array . isArray ( value ) ;
@@ -89,6 +90,10 @@ export function transformObjectVectorShapePoint(point, transform = {}, origin =
8990 } ;
9091}
9192
93+ export function transformObjectVectorShapePoints ( points , transform = { } , origin = { } ) {
94+ return ( Array . isArray ( points ) ? points : [ ] ) . map ( ( point ) => transformObjectVectorShapePoint ( point , transform , origin ) ) ;
95+ }
96+
9297export function inverseTransformObjectVectorShapePoint ( point , transform = { } , origin = { } ) {
9398 const resolvedTransform = normalizeObjectVectorTransform ( transform ) ;
9499 const resolvedOrigin = normalizeObjectVectorOrigin ( origin ) ;
@@ -115,6 +120,10 @@ export function transformObjectVectorInstancePoint(point, instance = {}, options
115120 } ) ;
116121}
117122
123+ export function transformObjectVectorInstancePoints ( points , instance = { } , options = { } ) {
124+ return ( Array . isArray ( points ) ? points : [ ] ) . map ( ( point ) => transformObjectVectorInstancePoint ( point , instance , options ) ) ;
125+ }
126+
118127export function transformRuntimeOrientedPoint ( point , {
119128 rotation = 0 ,
120129 rotationUnit = "radians" ,
@@ -137,6 +146,100 @@ export function transformRuntimeOrientedPoints(points, options = {}) {
137146 return ( Array . isArray ( points ) ? points : [ ] ) . map ( ( point ) => transformRuntimeOrientedPoint ( point , options ) ) ;
138147}
139148
149+ export function objectVectorBoundsCornerPoints ( bounds = { } ) {
150+ const x = numberValue ( bounds . x ) ;
151+ const y = numberValue ( bounds . y ) ;
152+ const width = numberValue ( bounds . width , 1 ) ;
153+ const height = numberValue ( bounds . height , 1 ) ;
154+ return [
155+ { x, y } ,
156+ { x : x + width , y } ,
157+ { x : x + width , y : y + height } ,
158+ { x, y : y + height }
159+ ] ;
160+ }
161+
162+ export function boundsFromObjectVectorPoints ( points , fallback = DEFAULT_OBJECT_VECTOR_BOUNDS ) {
163+ const normalizedPoints = ( Array . isArray ( points ) ? points : [ ] )
164+ . map ( ( point ) => ( { x : Number ( point ?. x ) , y : Number ( point ?. y ) } ) )
165+ . filter ( ( point ) => Number . isFinite ( point . x ) && Number . isFinite ( point . y ) ) ;
166+ if ( ! normalizedPoints . length ) {
167+ return { ...fallback } ;
168+ }
169+ const xValues = normalizedPoints . map ( ( point ) => point . x ) ;
170+ const yValues = normalizedPoints . map ( ( point ) => point . y ) ;
171+ const minX = Math . min ( ...xValues ) ;
172+ const minY = Math . min ( ...yValues ) ;
173+ const maxX = Math . max ( ...xValues ) ;
174+ const maxY = Math . max ( ...yValues ) ;
175+ const width = Math . max ( 1 , maxX - minX ) ;
176+ const height = Math . max ( 1 , maxY - minY ) ;
177+ return {
178+ height : Number ( height . toFixed ( 3 ) ) ,
179+ originX : Number ( ( minX + width / 2 ) . toFixed ( 3 ) ) ,
180+ originY : Number ( ( minY + height / 2 ) . toFixed ( 3 ) ) ,
181+ width : Number ( width . toFixed ( 3 ) ) ,
182+ x : Number ( minX . toFixed ( 3 ) ) ,
183+ y : Number ( minY . toFixed ( 3 ) )
184+ } ;
185+ }
186+
187+ export function transformedObjectVectorShapeBounds ( points , transform = { } , origin = { } ) {
188+ return boundsFromObjectVectorPoints ( transformObjectVectorShapePoints ( points , transform , origin ) ) ;
189+ }
190+
191+ export function combineObjectVectorBounds ( boundsList , fallback = DEFAULT_OBJECT_VECTOR_BOUNDS ) {
192+ const points = ( Array . isArray ( boundsList ) ? boundsList : [ ] ) . flatMap ( ( bounds ) => objectVectorBoundsCornerPoints ( bounds ) ) ;
193+ return boundsFromObjectVectorPoints ( points , fallback ) ;
194+ }
195+
196+ export function createObjectVectorTransformPipeline ( {
197+ instance = { } ,
198+ objectOrigin = { } ,
199+ screenTransform = null ,
200+ shapeTransform = { }
201+ } = { } ) {
202+ const origin = normalizeObjectVectorOrigin ( objectOrigin ) ;
203+ const transform = normalizeObjectVectorTransform ( shapeTransform ) ;
204+ const localPointToShape = ( point ) => transformObjectVectorShapePoint ( point , transform , origin ) ;
205+ const localPointsToShape = ( points ) => transformObjectVectorShapePoints ( points , transform , origin ) ;
206+ const shapePointToWorld = ( point ) => transformObjectVectorInstancePoint ( point , instance ) ;
207+ const shapePointsToWorld = ( points ) => transformObjectVectorInstancePoints ( points , instance ) ;
208+ const worldPointToViewport = ( point ) => (
209+ typeof screenTransform ?. worldPointToViewportPoint === "function"
210+ ? screenTransform . worldPointToViewportPoint ( point )
211+ : point
212+ ) ;
213+ const localPointToWorld = ( point ) => shapePointToWorld ( localPointToShape ( point ) ) ;
214+ const localPointsToWorld = ( points ) => shapePointsToWorld ( localPointsToShape ( points ) ) ;
215+ const localPointToViewport = ( point ) => worldPointToViewport ( localPointToWorld ( point ) ) ;
216+ const localPointsToViewport = ( points ) => localPointsToWorld ( points ) . map ( ( point ) => worldPointToViewport ( point ) ) ;
217+ const originWorld = ( ) => shapePointToWorld ( origin ) ;
218+ const originViewport = ( ) => worldPointToViewport ( originWorld ( ) ) ;
219+
220+ return Object . freeze ( {
221+ localPointToShape,
222+ localPointToViewport,
223+ localPointToWorld,
224+ localPointsToShape,
225+ localPointsToViewport,
226+ localPointsToWorld,
227+ origin,
228+ originViewport,
229+ originWorld,
230+ shapeBounds ( points ) {
231+ return transformedObjectVectorShapeBounds ( points , transform , origin ) ;
232+ } ,
233+ shapeTransform : transform ,
234+ viewportBounds ( points ) {
235+ return boundsFromObjectVectorPoints ( localPointsToViewport ( points ) ) ;
236+ } ,
237+ worldBounds ( points ) {
238+ return boundsFromObjectVectorPoints ( localPointsToWorld ( points ) ) ;
239+ }
240+ } ) ;
241+ }
242+
140243export function objectVectorSvgTransformAttribute ( transform = { } , origin = { } ) {
141244 const resolvedTransform = normalizeObjectVectorTransform ( transform ) ;
142245 const resolvedOrigin = normalizeObjectVectorOrigin ( origin ) ;
0 commit comments