2020-11-15 03:10:44 +01:00
import { InputElement } from "./InputElement" ;
import { UIEventSource } from "../../Logic/UIEventSource" ;
import Combine from "../Base/Combine" ;
import Svg from "../../Svg" ;
2021-06-23 02:15:28 +02:00
import BaseUIElement from "../BaseUIElement" ;
2021-06-16 17:09:32 +02:00
import { FixedUiElement } from "../Base/FixedUiElement" ;
2021-06-23 02:15:28 +02:00
import { Utils } from "../../Utils" ;
import Loc from "../../Models/Loc" ;
2021-09-21 02:10:42 +02:00
import Minimap from "../Base/Minimap" ;
2021-01-02 21:03:40 +01:00
2020-11-15 03:10:44 +01:00
/ * *
* Selects a direction in degrees
* /
export default class DirectionInput extends InputElement < string > {
public readonly IsSelected : UIEventSource < boolean > = new UIEventSource < boolean > ( false ) ;
2021-09-09 00:05:51 +02:00
private readonly _location : UIEventSource < Loc > ;
2021-06-18 14:30:49 +02:00
private readonly value : UIEventSource < string > ;
2021-06-23 02:15:28 +02:00
private background ;
2020-11-15 03:10:44 +01:00
2021-09-09 00:05:51 +02:00
constructor ( mapBackground : UIEventSource < any > ,
2021-06-23 02:15:28 +02:00
location : UIEventSource < Loc > ,
value? : UIEventSource < string > ) {
2020-11-15 03:10:44 +01:00
super ( ) ;
2021-06-23 02:15:28 +02:00
this . _location = location ;
2020-11-15 03:10:44 +01:00
this . value = value ? ? new UIEventSource < string > ( undefined ) ;
2021-06-23 02:15:28 +02:00
this . background = mapBackground ;
2021-06-16 17:09:32 +02:00
}
2021-06-18 14:30:49 +02:00
GetValue ( ) : UIEventSource < string > {
return this . value ;
}
IsValid ( str : string ) : boolean {
const t = Number ( str ) ;
return ! isNaN ( t ) && t >= 0 && t <= 360 ;
}
2021-06-16 17:09:32 +02:00
protected InnerConstructElement ( ) : HTMLElement {
2021-06-23 02:15:28 +02:00
let map : BaseUIElement = new FixedUiElement ( "" )
if ( ! Utils . runningFromConsole ) {
2021-09-21 02:10:42 +02:00
map = Minimap . createMiniMap ( {
2021-06-23 02:15:28 +02:00
background : this.background ,
allowMoving : false ,
location : this._location
} )
}
2021-06-16 17:09:32 +02:00
2021-06-18 14:30:49 +02:00
const element = new Combine ( [
2021-09-09 00:05:51 +02:00
Svg . direction_stroke_svg ( ) . SetStyle (
2021-06-10 14:05:26 +02:00
` position: absolute;top: 0;left: 0;width: 100%;height: 100%;transform:rotate( ${ this . value . data ? ? 0 } deg); ` )
2021-06-23 02:15:28 +02:00
. SetClass ( "direction-svg relative" )
2021-09-09 00:05:51 +02:00
. SetStyle ( "z-index: 1000" ) ,
2021-09-03 17:00:36 +02:00
map . SetStyle (
` position: absolute;top: 0;left: 0;width: 100%;height: 100%; ` )
2021-06-10 14:05:26 +02:00
] )
2021-09-03 17:00:36 +02:00
. SetStyle ( "width: min(100%, 25em); height: 0; padding-bottom: 100%" ) // A bit a weird CSS , see https://stackoverflow.com/questions/13851940/pure-css-solution-square-elements#19448481
2021-08-26 16:24:18 +02:00
. SetClass ( "relative block bg-white border border-black overflow-hidden rounded-full" )
2021-06-10 14:05:26 +02:00
. ConstructElement ( )
2021-06-30 15:38:14 +02:00
this . value . addCallbackAndRunD ( rotation = > {
2021-06-16 17:09:32 +02:00
const cone = element . getElementsByClassName ( "direction-svg" ) [ 0 ] as HTMLElement
2021-04-21 01:55:15 +02:00
cone . style . transform = ` rotate( ${ rotation } deg) ` ;
2020-11-15 03:10:44 +01:00
} )
2021-06-18 14:30:49 +02:00
this . RegisterTriggers ( element )
2021-07-12 00:05:56 +02:00
element . style . overflow = "hidden"
2021-08-26 16:24:18 +02:00
element . style . display = "block"
2020-11-15 03:10:44 +01:00
2021-06-18 14:30:49 +02:00
return element ;
2020-11-15 03:10:44 +01:00
}
2021-06-16 17:09:32 +02:00
private RegisterTriggers ( htmlElement : HTMLElement ) {
2020-11-15 03:10:44 +01:00
const self = this ;
function onPosChange ( x : number , y : number ) {
const rect = htmlElement . getBoundingClientRect ( ) ;
const dx = - ( rect . left + rect . right ) / 2 + x ;
const dy = ( rect . top + rect . bottom ) / 2 - y ;
const angle = 180 * Math . atan2 ( dy , dx ) / Math . PI ;
const angleGeo = Math . floor ( ( 450 - angle ) % 360 ) ;
2020-11-17 02:22:48 +01:00
self . value . setData ( "" + angleGeo )
2020-11-15 03:10:44 +01:00
}
htmlElement . ontouchmove = ( ev : TouchEvent ) = > {
2020-11-15 19:17:36 +01:00
onPosChange ( ev . touches [ 0 ] . clientX , ev . touches [ 0 ] . clientY ) ;
ev . preventDefault ( ) ;
}
htmlElement . ontouchstart = ( ev : TouchEvent ) = > {
2020-11-15 03:10:44 +01:00
onPosChange ( ev . touches [ 0 ] . clientX , ev . touches [ 0 ] . clientY ) ;
}
let isDown = false ;
htmlElement . onmousedown = ( ev : MouseEvent ) = > {
isDown = true ;
2021-04-21 01:55:15 +02:00
onPosChange ( ev . clientX , ev . clientY ) ;
2020-11-15 03:10:44 +01:00
ev . preventDefault ( ) ;
}
htmlElement . onmouseup = ( ev ) = > {
2021-06-18 14:30:49 +02:00
isDown = false ;
ev . preventDefault ( ) ;
2020-11-15 03:10:44 +01:00
}
htmlElement . onmousemove = ( ev : MouseEvent ) = > {
if ( isDown ) {
2021-04-21 01:55:15 +02:00
onPosChange ( ev . clientX , ev . clientY ) ;
2021-06-18 14:30:49 +02:00
}
ev . preventDefault ( ) ;
2020-11-15 03:10:44 +01:00
}
}
}