import { h } from '@cycle/dom' ; import { List , Record , Set } from 'immutable' ; import { identity } from 'ramda' ; import { distanceBetweenPointAndSegment , getCoordinateUpdater } from './common' ; import Sem from './Sem' ; import { ItemMethods , Point , ResizeDirConfig } from '../interfaces' ; const PolylineItemRecord = Record ( { id : - 1 , locked : false , sem : new Sem ( ) , points : List < Point > ( ) , stroke : '#000000' , strokeWidth : 5 , opacity : 1 , fill : 'none' , } , 'PolylineItem' ) ; export default class PolylineItem extends PolylineItemRecord implements ItemMethods { toJS ( ) { const superJS = super . toJS ( ) ; superJS . type = 'PolylineItem' ; return superJS ; } static fromJS ( object ) { return new PolylineItem ( object ) . update ( 'points' , List ) . update ( 'sem' , Sem . fromJS ) ; } static lineFromPoints ( [ p1 , p2 ] ) { return new PolylineItem ( { points : List ( [ p1 , p2 ] ) } ) ; } static fromPoints ( points ) { return new PolylineItem ( { points : List ( points ) } ) ; } getVertices ( ) { return this . points ; } resize ( anchor , { h , v } , startPos , endPos ) { if ( this . locked ) { return this ; } const xUpdater = h ? getCoordinateUpdater ( anchor . x , startPos . x , endPos . x ) : identity ; const yUpdater = v ? getCoordinateUpdater ( anchor . y , startPos . y , endPos . y ) : identity ; return this . update ( 'points' , ps => ps . map ( p => ( { x : xUpdater ( p . x ) , y : yUpdater ( p . y ) } ) ) ) ; } render ( ) { return h ( 'polyline' , { key : this . id , attrs : { stroke : this . stroke , 'stroke-linejoin' : 'round' , 'stroke-width' : this . strokeWidth , opacity : this . opacity , fill : this . fill , points : this . points . map ( p => `${ p . x },${ p . y }` ) . join ( ' ' ) , } , } ) ; } containsPoint ( point ) { const segments = this . points . butLast ( ) . zip ( this . points . rest ( ) ) ; return Boolean ( segments . find ( ( [ start , end ] ) => { const distance = distanceBetweenPointAndSegment ( point , start , end ) ; return distance <= this . strokeWidth / 2 ; } ) ) ; } move ( dx , dy ) { if ( this . locked ) { return this ; } return this . update ( 'points' , ps => ps . map ( p => ( { x : p . x + dx , y : p . y + dy } ) ) ) ; } supportEditVertex ( ) { return true ; } insertVertex ( insertIndex , p ) { return this . update ( 'points' , points => points . insert ( insertIndex , p ) ) ; } deleteVertex ( vertexIndex ) { return this . update ( 'points' , points => points . delete ( vertexIndex ) ) ; } moveVertex ( vertexIndex , dx , dy ) { return this . update ( 'points' , points => points . update ( vertexIndex , p => ( { x : p . x + dx , y : p . y + dy , } ) ) ) ; } getShortDescription ( ) { return 'PolylineItem' ; } }