@ -32,6 +32,11 @@ export interface DrawHandler {
cancel ( ) : void ;
}
interface FinalCoordinates {
points : number [ ] ;
box : Box ;
}
export class DrawHandlerImpl implements DrawHandler {
// callback is used to notify about creating new shape
private onDrawDone : ( data : object | null , duration? : number , continueDraw? : boolean ) = > void ;
@ -73,19 +78,14 @@ export class DrawHandlerImpl implements DrawHandler {
return [ xtl , ytl , xbr , ybr ] ;
}
private getFinalPolyshapeCoordinates (
targetPoints : number [ ] ,
) : {
points : number [ ] ;
box : Box ;
} {
private getFinalPolyshapeCoordinates ( targetPoints : number [ ] ) : FinalCoordinates {
const { offset } = this . geometry ;
let points = targetPoints . map ( ( coord : number ) : number = > coord - offset ) ;
const box = {
xtl : Number.MAX_SAFE_INTEGER ,
ytl : Number.MAX_SAFE_INTEGER ,
xbr : Number.M AX _SAFE_INTEGER,
ybr : Number.M AX _SAFE_INTEGER,
xbr : Number.M IN _SAFE_INTEGER,
ybr : Number.M IN _SAFE_INTEGER,
} ;
const frameWidth = this . geometry . image . width ;
@ -96,9 +96,9 @@ export class DrawHandlerImpl implements DrawHandler {
Vertical ,
}
const isBetween = ( x1 : number , x2 : number , c : number ) : boolean = > (
c >= Math . min ( x1 , x2 ) && c <= Math . max ( x1 , x2 )
);
function isBetween ( x1 : number , x2 : number , c : number ) : boolean {
return c >= Math . min ( x1 , x2 ) && c <= Math . max ( x1 , x2 ) ;
}
const isInsideFrame = ( p : Point , direction : Direction ) : boolean = > {
if ( direction === Direction . Horizontal ) {
@ -121,22 +121,35 @@ export class DrawHandlerImpl implements DrawHandler {
const findIntersectionsWithFrameBorders = ( p1 : Point , p2 : Point , direction : Direction ) : number [ ] = > {
const resultPoints = [ ] ;
const leftLine = [
{ x : 0 , y : 0 } ,
{ x : 0 , y : frameHeight } ,
] ;
const topLine = [
{ x : frameWidth , y : 0 } ,
{ x : 0 , y : 0 } ,
] ;
const rightLine = [
{ x : frameWidth , y : frameHeight } ,
{ x : frameWidth , y : 0 } ,
] ;
const bottomLine = [
{ x : 0 , y : frameHeight } ,
{ x : frameWidth , y : frameHeight } ,
] ;
if ( direction === Direction . Horizontal ) {
resultPoints . push ( . . . findInersection ( p1 , p2 , { x : 0 , y : 0 } , { x : 0 , y : frameHeight } ) ) ;
resultPoints . push (
. . . findInersection ( p1 , p2 , { x : frameWidth , y : frameHeight } , { x : frameWidth , y : 0 } ) ,
) ;
resultPoints . push ( . . . findInersection ( p1 , p2 , leftLine [ 0 ] , leftLine [ 1 ] ) ) ;
resultPoints . push ( . . . findInersection ( p1 , p2 , rightLine [ 0 ] , rightLine [ 1 ] ) ) ;
} else {
resultPoints . push (
. . . findInersection ( p1 , p2 , { x : 0 , y : frameHeight } , { x : frameWidth , y : frameHeight } ) ,
) ;
resultPoints . push ( . . . findInersection ( p1 , p2 , { x : frameWidth , y : 0 } , { x : 0 , y : 0 } ) ) ;
resultPoints . push ( . . . findInersection ( p1 , p2 , bottomLine [ 0 ] , bottomLine [ 1 ] ) ) ;
resultPoints . push ( . . . findInersection ( p1 , p2 , topLine [ 0 ] , topLine [ 1 ] ) ) ;
}
if ( resultPoints . length === 4 ) {
if (
Math . sign ( resultPoints [ 0 ] - resultPoints [ 2 ] ) !== Math . sign ( p1 . x - p2 . x )
&& Math . sign ( resultPoints [ 1 ] - resultPoints [ 3 ] ) !== Math . sign ( p1 . y - p2 . y )
( p1 . x === p2 . x || Math . sign ( resultPoints [ 0 ] - resultPoints [ 2 ] ) !== Math . sign ( p1 . x - p2 . x ) )
&& ( p1 . y === p2 . y || Math . sign ( resultPoints [ 1 ] - resultPoints [ 3 ] ) !== Math . sign ( p1 . y - p2 . y ) )
) {
[ resultPoints [ 0 ] , resultPoints [ 2 ] ] = [ resultPoints [ 2 ] , resultPoints [ 0 ] ] ;
[ resultPoints [ 1 ] , resultPoints [ 3 ] ] = [ resultPoints [ 3 ] , resultPoints [ 1 ] ] ;
@ -145,24 +158,23 @@ export class DrawHandlerImpl implements DrawHandler {
return resultPoints ;
} ;
const crop = ( polygon Points: number [ ] , direction : Direction ) : number [ ] = > {
const crop = ( shape Points: number [ ] , direction : Direction ) : number [ ] = > {
const resultPoints = [ ] ;
for ( let i = 0 ; i < polygonPoints . length - 1 ; i += 2 ) {
const curPoint = { x : polygonPoints [ i ] , y : polygonPoints [ i + 1 ] } ;
const isPolyline = this . drawData . shapeType === 'polyline' ;
const isPolygon = this . drawData . shapeType === 'polygon' ;
for ( let i = 0 ; i < shapePoints . length - 1 ; i += 2 ) {
const curPoint = { x : shapePoints [ i ] , y : shapePoints [ i + 1 ] } ;
if ( isInsideFrame ( curPoint , direction ) ) {
resultPoints . push ( polygonPoints [ i ] , polygonPoints [ i + 1 ] ) ;
resultPoints . push ( shapePoints[ i ] , shape Points[ i + 1 ] ) ;
}
const isLastPoint = i === polygonPoints . length - 2 ;
if (
isLastPoint
&& ( this . drawData . shapeType === 'polyline'
|| ( this . drawData . shapeType === 'polygon' && polygonPoints . length === 4 ) )
) {
const isLastPoint = i === shapePoints . length - 2 ;
if ( isLastPoint && ( isPolyline || ( isPolygon && shapePoints . length === 4 ) ) ) {
break ;
}
const nextPoint = isLastPoint
? { x : polygonPoints[ 0 ] , y : polygon Points[ 1 ] }
: { x : polygonPoints[ i + 2 ] , y : polygon Points[ i + 3 ] } ;
? { x : shapePoints [ 0 ] , y : shapePoints [ 1 ] }
: { x : shapePoints[ i + 2 ] , y : shape Points[ i + 3 ] } ;
const intersectionPoints = findIntersectionsWithFrameBorders ( curPoint , nextPoint , direction ) ;
if ( intersectionPoints . length !== 0 ) {
resultPoints . push ( . . . intersectionPoints ) ;
@ -187,20 +199,15 @@ export class DrawHandlerImpl implements DrawHandler {
} ;
}
private getFinalCuboidCoordinates (
targetPoints : number [ ] ,
) : {
points : number [ ] ;
box : Box ;
} {
private getFinalCuboidCoordinates ( targetPoints : number [ ] ) : FinalCoordinates {
const { offset } = this . geometry ;
let points = targetPoints ;
const box = {
xtl : 0 ,
ytl : 0 ,
xbr : Number.M AX _SAFE_INTEGER,
ybr : Number.M AX _SAFE_INTEGER,
xtl : Number.MAX_SAFE_INTEGER ,
ytl : Number.MAX_SAFE_INTEGER ,
xbr : Number.M IN _SAFE_INTEGER,
ybr : Number.M IN _SAFE_INTEGER,
} ;
const frameWidth = this . geometry . image . width ;
@ -238,26 +245,33 @@ export class DrawHandlerImpl implements DrawHandler {
if ( cuboidOffsets . length === points . length / 2 ) {
cuboidOffsets . forEach ( ( offsetCoords : number [ ] ) : void = > {
if ( Math . sqrt ( ( offsetCoords [ 0 ] * * 2 ) + ( offsetCoords [ 1 ] * * 2 ) ) < minCuboidOffset . d ) {
minCuboidOffset . d = Math . sqrt ( ( offsetCoords [ 0 ] * * 2 ) + ( offsetCoords [ 1 ] * * 2 ) ) ;
const dx = offsetCoords [ 0 ] * * 2 ;
const dy = offsetCoords [ 1 ] * * 2 ;
if ( Math . sqrt ( dx + dy ) < minCuboidOffset . d ) {
minCuboidOffset . d = Math . sqrt ( dx + dy ) ;
[ minCuboidOffset . dx , minCuboidOffset . dy ] = offsetCoords ;
}
} ) ;
points = points . map ( ( coord : number , i : number ) : number = > {
const finalCoord = coord + ( i % 2 === 0 ? minCuboidOffset.dx : minCuboidOffset.dy ) ;
if ( i % 2 ) {
return coord + minCuboidOffset . dy ;
}
return coord + minCuboidOffset . dx ;
} ) ;
}
points . forEach ( ( coord : number , i : number ) : number = > {
if ( i % 2 === 0 ) {
box . xtl = Math . max ( box . xtl , finalCoord ) ;
box . xbr = Math . min ( box . xbr , finalCoord ) ;
box . xtl = Math . m in( box . xtl , c oord) ;
box . xbr = Math . m ax( box . xbr , c oord) ;
} else {
box . ytl = Math . m ax( box . ytl , finalC oord) ;
box . ybr = Math . m in( box . ybr , finalC oord) ;
box . ytl = Math . m in( box . ytl , c oord) ;
box . ybr = Math . m ax( box . ybr , c oord) ;
}
return finalC oord;
return c oord;
} ) ;
}
return {
points : points.map ( ( coord : number ) : number = > coord - offset ) ,
@ -449,8 +463,9 @@ export class DrawHandlerImpl implements DrawHandler {
} else {
this . drawInstance . draw ( 'update' , e ) ;
const deltaTreshold = 15 ;
const delta = Math . sqrt ( ( ( e . clientX - lastDrawnPoint . x ) * * 2 )
+ ( ( e . clientY - lastDrawnPoint . y ) * * 2 ) ) ;
const dx = ( e . clientX - lastDrawnPoint . x ) * * 2 ;
const dy = ( e . clientY - lastDrawnPoint . y ) * * 2 ;
const delta = Math . sqrt ( dx + dy ) ;
if ( delta > deltaTreshold ) {
this . drawInstance . draw ( 'point' , e ) ;
}
@ -482,36 +497,15 @@ export class DrawHandlerImpl implements DrawHandler {
&& ( box . xbr - box . xtl ) * ( box . ybr - box . ytl ) >= consts . AREA_THRESHOLD
&& points . length >= 3 * 2
) {
this . onDrawDone (
{
clientID ,
shapeType ,
points ,
} ,
Date . now ( ) - this . startTimestamp ,
) ;
this . onDrawDone ( { clientID , shapeType , points } , Date . now ( ) - this . startTimestamp ) ;
} else if (
shapeType === 'polyline'
&& ( box . xbr - box . xtl >= consts . SIZE_THRESHOLD || box . ybr - box . ytl >= consts . SIZE_THRESHOLD )
&& points . length >= 2 * 2
) {
this . onDrawDone (
{
clientID ,
shapeType ,
points ,
} ,
Date . now ( ) - this . startTimestamp ,
) ;
this . onDrawDone ( { clientID , shapeType , points } , Date . now ( ) - this . startTimestamp ) ;
} else if ( shapeType === 'points' && ( e . target as any ) . getAttribute ( 'points' ) !== '0,0' ) {
this . onDrawDone (
{
clientID ,
shapeType ,
points ,
} ,
Date . now ( ) - this . startTimestamp ,
) ;
this . onDrawDone ( { clientID , shapeType , points } , Date . now ( ) - this . startTimestamp ) ;
// TODO: think about correct constraign for cuboids
} else if ( shapeType === 'cuboid' && points . length === 4 * 2 ) {
this . onDrawDone (