{"size": 8721, "ext": "js", "max_stars_repo_path": "src/domevents/DomeventPointer.es.js", "max_stars_repo_name": "i3ernie/three-domevents", "max_stars_repo_stars_event_min_datetime": "2020-09-10T13:39:01.000Z", "max_stars_repo_stars_event_max_datetime": "2020-09-10T13:39:01.000Z", "max_issues_repo_path": "src/domevents/DomeventPointer.es.js", "max_issues_repo_name": "i3ernie/three-domevents", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "src/domevents/DomeventPointer.es.js", "max_forks_repo_name": "i3ernie/three-domevents", "max_forks_repo_forks_event_min_datetime": "2021-08-04T08:15:48.000Z", "max_forks_repo_forks_event_max_datetime": "2021-08-04T08:15:48.000Z"}
{"max_stars_count": 1, "max_issues_count": null, "max_forks_count": 1, "avg_line_length": 30.9255319149, "max_line_length": 111, "alphanum_fraction": 0.5778007109}
import {Vector3} from "../../node_modules/three/build/three.module.js";


import getRelativeMouseXY from "../PointerTools.es.js";

const CLICK_TIMEOUT = 500;
let emulateMouse = false, emulateClick = false;

const _onPointerDown	= function( event ){
    
    this.pointerDownTimeStamp = event.timeStamp;

    _onMouseEvent.call(this, 'pointerdown', event);

    if ( emulateMouse && ( event.pointerType === "mouse" || event.pointerType === "touch") ) {
        this.stateMouse.mousedown = true;

        if ( event.buttons && event.buttons > 1 ) {
            if ( event.button === 1 ) {
                return _onMouseEvent.call(this, 'mousemiddledown', event);
            }
            if ( event.button === 2 ) {
                //rightdown
                return _onMouseEvent.call(this, 'mouserightdown', event);
            }
        }
        _onMouseEvent.call(this, 'mousedown', event);
    }
};

const _onPointerUp	= function( event ){

    this.pointerUpTimeStamp = event.timeStamp;

    _onMouseEvent.call(this, 'pointerup', event);

    if ( emulateMouse && ( event.pointerType === "mouse" || event.pointerType === "touch") ) {
        this.stateMouse.mousedown = false;

        if ( event.buttons && event.buttons > 1 ) {
            if ( event.button === 1 ) {
                return _onMouseEvent.call(this, 'mousemiddleup', event);
            }
            if ( event.button === 2 ) {
                //rightdown
                return _onMouseEvent.call(this, 'mouserightup', event);
            }
        }
        _onMouseEvent.call(this, 'mouseup'	, event);

        if ( emulateClick ){
            this._$onClick( event );
        }
    }
};

/********************************************************************************/
/*		onMove								*/
/********************************************************************************/

// # handle mousemove kind of events

const _onMove = function( eventName, mouseX, mouseY, origDomEvent )
{
    //console.log('eventName', eventName, 'boundObjs', this._boundObjs[eventName])
    // get objects bound to this event
    let boundObjs	= this._boundObjs[eventName];
    if( boundObjs === undefined || boundObjs.length === 0 )	return;

    // compute the intersection
    let vector = new Vector3( mouseX, mouseY, 0.5 );
    this._ray.setFromCamera( vector, this._camera );

    let intersects = null;
    try {
        intersects  = this._ray.intersectObjects( boundObjs );
    } catch( e ){
        this.clean();
        this._onMove( eventName, mouseX, mouseY, origDomEvent );
        return;
    }

    let oldSelected	= this._selected;
    let notifyOver, notifyOut, notifyMove;
    let intersect;
    let newSelected;
    let i = 0;
    let doIntersect = true;

    while ( doIntersect ) {
        
        doIntersect = false;

        if ( intersects.length > 0 ){
            intersect	= intersects[ i ];
            newSelected	= intersect.object;

            this._selected	= newSelected;
            // if newSelected bound mousemove, notify it
            notifyMove	= this._bound('mousemove', newSelected);

            if ( oldSelected !== newSelected ) {
                // if newSelected bound mouseenter, notify it
                notifyOver	= this._bound('mouseover', newSelected);
                // if there is a oldSelect and oldSelected bound mouseleave, notify it
                notifyOut	= oldSelected && this._bound('mouseout', oldSelected);
            }

        } else {
            // if there is a oldSelect and oldSelected bound mouseleave, notify it
            notifyOut	= oldSelected && this._bound('mouseout', oldSelected);
            this._selected	= null;
        }
        i++;

        // notify mouseMove - done at the end with a copy of the list to allow callback to remove handlers
        if (notifyMove) {
            doIntersect = this._notify('mousemove', newSelected, origDomEvent, intersect, intersects);
        }
        // notify mouseEnter - done at the end with a copy of the list to allow callback to remove handlers
        if (notifyOver) {
            this._notify('mouseover', newSelected, origDomEvent, intersect, intersects);
        }
        // notify mouseLeave - done at the end with a copy of the list to allow callback to remove handlers
        if (notifyOut) {
            this._notify('mouseout' , oldSelected, origDomEvent, intersect, intersects);
        }
       
    }
};


const _onClick = function( event )
{
    // TODO handle touch ? 
    if ( this.pointerDownTimeStamp !== null && (event.timeStamp - this.pointerDownTimeStamp) > CLICK_TIMEOUT ){
        return;
    }
    this.pointerDownTimeStamp = null;
    _onMouseEvent.call(this, 'click', event );
};

const _onDblClick = function( event )
{
    // TODO handle touch ?
    _onMouseEvent.call(this, 'dblclick', event);
};


/************************************************/
/*		handle mouse events						*/
/************************************************/
// # handle mouse events

const _onMouseEvent	= function( eventName, domEvent )
{
    let mouseCoords = getRelativeMouseXY( domEvent );
    this._onEvent(eventName, mouseCoords.x, mouseCoords.y, domEvent);
};

const _onPointerMove	= function( domEvent )
{
    let mouseCoords = getRelativeMouseXY( domEvent );

    _onMove.call(this, 'pointermove', mouseCoords.x, mouseCoords.y, domEvent);
    
    if ( emulateMouse ){
        _onMove.call(this, 'mousemove', mouseCoords.x, mouseCoords.y, domEvent);
    }
    
    //_onMove.call(this, 'mouseover', mouseCoords.x, mouseCoords.y, domEvent);
    //_onMove.call(this, 'mouseout' , mouseCoords.x, mouseCoords.y, domEvent);
};


const _onContextmenu = function( event )
{
    //TODO don't have a clue about how this should work with touch..
    _onMouseEvent.call(this, 'contextmenu', event);
};


const mouseEvents = [
    "mousedown",
    "mouseup",
    "mousemove",
    "contextmenu",

    "click",
    
    "dblclick"
];
const mouseEventMapping = {
    "mousedown"     : "onMousedown",
    "mouseup" 	    : "onMouseup",

    "click"         : "onClick",
    "mousemove"     : "onMousemove",
    "dblclick"      : "onDblclick"
};


const DomeventPointer = {

    eventNames : [

        "pointerover",
        "pointerenter",

        "pointerdown",
        "pointermove",
        "pointerup",
        "pointercancel",        
        "pointerout",
        "pointerleave"
    ],

    eventMapping : {
        "pointerover"   : "onPointerover",
        "pointerenter"  : "onPointerenter",
        "pointerdown"   : "onPointerdown",
        "pointermove"   : "onPointermove",
        "pointerup"     : "onPointerup",
        "pointercancel" : "onPointercancel"
    },

    config : function( opt ){
        if ( opt ){ 
            if( opt.emulateMouse ) {
                emulateMouse = true;
                emulateClick = true;
                DomeventPointer.eventNames = DomeventPointer.eventNames.concat( mouseEvents );
                Object.assign(DomeventPointer.eventMapping, mouseEventMapping);
            }
            if ( opt.emulateClick ) {
                emulateClick = true;
                DomeventPointer.eventNames.push("click");
                Object.assign(DomeventPointer.eventMapping, {"click":"onClick"});
            }
        }
        return DomeventPointer;
    },

    initialize : function( ){
        let _this = this; 

        this.stateMouse = this.stateMouse || {};
        this.stateMouse.mousedown = false;
    
        this._onMove            = function(){ _onMove.apply( _this, arguments ); };  
        this._onMouseEvent      = function(){ _onMouseEvent.apply( _this, arguments ); };

        this._$onPointerDown	= function(){ _onPointerDown.apply( _this, arguments ); };
	    this._$onPointerUp	    = function(){ _onPointerUp.apply( _this, arguments ); };
  

        this._$onPointerMove	= function(){ _onPointerMove.apply(_this, arguments);	};

        if ( emulateClick ){
            this._$onClick      = function(){ _onClick.apply( _this, arguments ); }
        }
    },

    enable : function(){ 

        this._domElement.addEventListener( 'pointerdown', this._$onPointerDown, false );
        this._domElement.addEventListener( 'pointerup', this._$onPointerUp, false );

        this._domElement.addEventListener( 'pointermove'	, this._$onPointerMove	, false );
    },

    disable : function(){
        
        this._domElement.removeEventListener( 'pointerdown'	, this._$onMouseDown	, false );
        this._domElement.removeEventListener( 'pointerup'	, this._$onMouseUp		, false );
        
        this._domElement.removeEventListener( 'pointermove'	, this._$onMouseMove	, false );
    }
};

export default DomeventPointer;
export { DomeventPointer };