Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
I
IGEV_proyecto
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Automate
Agent sessions
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
adrmanz
IGEV_proyecto
Commits
3f366aa1
Commit
3f366aa1
authored
Apr 7, 2021
by
adrmanz
Browse files
Options
Downloads
Patches
Plain Diff
Upload New File
parent
66fdd174
Branches
Branches containing commit
No related tags found
No related merge requests found
Pipeline
#9378
passed with warnings
Apr 7, 2021
Stage: deploy
Changes
1
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
libs/threex.domevents.js
+450
-0
450 additions, 0 deletions
libs/threex.domevents.js
with
450 additions
and
0 deletions
libs/threex.domevents.js
0 → 100644
+
450
−
0
View file @
3f366aa1
// This THREEx helper makes it easy to handle the mouse events in your 3D scene
//
// * CHANGES NEEDED
// * handle drag/drop
// * notify events not object3D - like DOM
// * so single object with property
// * DONE bubling implement bubling/capturing
// * DONE implement event.stopPropagation()
// * DONE implement event.type = "click" and co
// * DONE implement event.target
//
// # Lets get started
//
// First you include it in your page
//
// ```<script src='threex.domevent.js'>< /script>```
//
// # use the object oriented api
//
// You bind an event like this
//
// ```mesh.on('click', function(object3d){ ... })```
//
// To unbind an event, just do
//
// ```mesh.off('click', function(object3d){ ... })```
//
// As an alternative, there is another naming closer DOM events.
// Pick the one you like, they are doing the same thing
//
// ```mesh.addEventListener('click', function(object3d){ ... })```
// ```mesh.removeEventListener('click', function(object3d){ ... })```
//
// # Supported Events
//
// Always in a effort to stay close to usual pratices, the events name are the same as in DOM.
// The semantic is the same too.
// Currently, the available events are
// [click, dblclick, mouseup, mousedown](http://www.quirksmode.org/dom/events/click.html),
// [mouseover and mouse out](http://www.quirksmode.org/dom/events/mouseover.html).
//
// # use the standalone api
//
// The object-oriented api modifies THREE.Object3D class.
// It is a global class, so it may be legitimatly considered unclean by some people.
// If this bother you, simply do ```THREEx.DomEvents.noConflict()``` and use the
// standalone API. In fact, the object oriented API is just a thin wrapper
// on top of the standalone API.
//
// First, you instanciate the object
//
// ```var domEvent = new THREEx.DomEvent();```
//
// Then you bind an event like this
//
// ```domEvent.bind(mesh, 'click', function(object3d){ object3d.scale.x *= 2; });```
//
// To unbind an event, just do
//
// ```domEvent.unbind(mesh, 'click', callback);```
//
//
// # Code
//
/** @namespace */
var
THREEx
=
THREEx
||
{};
// # Constructor
THREEx
.
DomEvents
=
function
(
camera
,
domElement
)
{
this
.
_camera
=
camera
||
null
;
this
.
_domElement
=
domElement
||
document
;
this
.
_raycaster
=
new
THREE
.
Raycaster
();
this
.
_selected
=
null
;
this
.
_boundObjs
=
{};
// Bind dom event for mouse and touch
var
_this
=
this
;
this
.
_$onClick
=
function
(){
_this
.
_onClick
.
apply
(
_this
,
arguments
);
};
this
.
_$onDblClick
=
function
(){
_this
.
_onDblClick
.
apply
(
_this
,
arguments
);
};
this
.
_$onMouseMove
=
function
(){
_this
.
_onMouseMove
.
apply
(
_this
,
arguments
);
};
this
.
_$onMouseDown
=
function
(){
_this
.
_onMouseDown
.
apply
(
_this
,
arguments
);
};
this
.
_$onMouseUp
=
function
(){
_this
.
_onMouseUp
.
apply
(
_this
,
arguments
);
};
this
.
_$onTouchMove
=
function
(){
_this
.
_onTouchMove
.
apply
(
_this
,
arguments
);
};
this
.
_$onTouchStart
=
function
(){
_this
.
_onTouchStart
.
apply
(
_this
,
arguments
);
};
this
.
_$onTouchEnd
=
function
(){
_this
.
_onTouchEnd
.
apply
(
_this
,
arguments
);
};
this
.
_$onContextmenu
=
function
(){
_this
.
_onContextmenu
.
apply
(
_this
,
arguments
);
};
this
.
_domElement
.
addEventListener
(
'
click
'
,
this
.
_$onClick
,
false
);
this
.
_domElement
.
addEventListener
(
'
dblclick
'
,
this
.
_$onDblClick
,
false
);
this
.
_domElement
.
addEventListener
(
'
mousemove
'
,
this
.
_$onMouseMove
,
false
);
this
.
_domElement
.
addEventListener
(
'
mousedown
'
,
this
.
_$onMouseDown
,
false
);
this
.
_domElement
.
addEventListener
(
'
mouseup
'
,
this
.
_$onMouseUp
,
false
);
this
.
_domElement
.
addEventListener
(
'
touchmove
'
,
this
.
_$onTouchMove
,
false
);
this
.
_domElement
.
addEventListener
(
'
touchstart
'
,
this
.
_$onTouchStart
,
false
);
this
.
_domElement
.
addEventListener
(
'
touchend
'
,
this
.
_$onTouchEnd
,
false
);
this
.
_domElement
.
addEventListener
(
'
contextmenu
'
,
this
.
_$onContextmenu
,
false
);
}
// # Destructor
THREEx
.
DomEvents
.
prototype
.
destroy
=
function
()
{
// unBind dom event for mouse and touch
this
.
_domElement
.
removeEventListener
(
'
click
'
,
this
.
_$onClick
,
false
);
this
.
_domElement
.
removeEventListener
(
'
dblclick
'
,
this
.
_$onDblClick
,
false
);
this
.
_domElement
.
removeEventListener
(
'
mousemove
'
,
this
.
_$onMouseMove
,
false
);
this
.
_domElement
.
removeEventListener
(
'
mousedown
'
,
this
.
_$onMouseDown
,
false
);
this
.
_domElement
.
removeEventListener
(
'
mouseup
'
,
this
.
_$onMouseUp
,
false
);
this
.
_domElement
.
removeEventListener
(
'
touchmove
'
,
this
.
_$onTouchMove
,
false
);
this
.
_domElement
.
removeEventListener
(
'
touchstart
'
,
this
.
_$onTouchStart
,
false
);
this
.
_domElement
.
removeEventListener
(
'
touchend
'
,
this
.
_$onTouchEnd
,
false
);
this
.
_domElement
.
removeEventListener
(
'
contextmenu
'
,
this
.
_$onContextmenu
,
false
);
}
THREEx
.
DomEvents
.
eventNames
=
[
"
click
"
,
"
dblclick
"
,
"
mouseover
"
,
"
mouseout
"
,
"
mousemove
"
,
"
mousedown
"
,
"
mouseup
"
,
"
contextmenu
"
,
"
touchstart
"
,
"
touchend
"
];
THREEx
.
DomEvents
.
prototype
.
_getRelativeMouseXY
=
function
(
domEvent
){
var
element
=
domEvent
.
target
||
domEvent
.
srcElement
;
if
(
element
.
nodeType
===
3
)
{
element
=
element
.
parentNode
;
// Safari fix -- see http://www.quirksmode.org/js/events_properties.html
}
//get the real position of an element relative to the page starting point (0, 0)
//credits go to brainjam on answering http://stackoverflow.com/questions/5755312/getting-mouse-position-relative-to-content-area-of-an-element
var
elPosition
=
{
x
:
0
,
y
:
0
};
var
tmpElement
=
element
;
//store padding
var
style
=
getComputedStyle
(
tmpElement
,
null
);
elPosition
.
y
+=
parseInt
(
style
.
getPropertyValue
(
"
padding-top
"
),
10
);
elPosition
.
x
+=
parseInt
(
style
.
getPropertyValue
(
"
padding-left
"
),
10
);
//add positions
do
{
elPosition
.
x
+=
tmpElement
.
offsetLeft
;
elPosition
.
y
+=
tmpElement
.
offsetTop
;
style
=
getComputedStyle
(
tmpElement
,
null
);
elPosition
.
x
+=
parseInt
(
style
.
getPropertyValue
(
"
border-left-width
"
),
10
);
elPosition
.
y
+=
parseInt
(
style
.
getPropertyValue
(
"
border-top-width
"
),
10
);
}
while
(
tmpElement
=
tmpElement
.
offsetParent
);
var
elDimension
=
{
width
:
(
element
===
window
)
?
window
.
innerWidth
:
element
.
offsetWidth
,
height
:
(
element
===
window
)
?
window
.
innerHeight
:
element
.
offsetHeight
};
return
{
x
:
+
((
domEvent
.
pageX
-
elPosition
.
x
)
/
elDimension
.
width
)
*
2
-
1
,
y
:
-
((
domEvent
.
pageY
-
elPosition
.
y
)
/
elDimension
.
height
)
*
2
+
1
};
};
/********************************************************************************/
/* domevent context */
/********************************************************************************/
// handle domevent context in object3d instance
THREEx
.
DomEvents
.
prototype
.
_objectCtxInit
=
function
(
object3d
){
object3d
.
_3xDomEvent
=
{};
}
THREEx
.
DomEvents
.
prototype
.
_objectCtxDeinit
=
function
(
object3d
){
delete
object3d
.
_3xDomEvent
;
}
THREEx
.
DomEvents
.
prototype
.
_objectCtxIsInit
=
function
(
object3d
){
return
object3d
.
_3xDomEvent
?
true
:
false
;
}
THREEx
.
DomEvents
.
prototype
.
_objectCtxGet
=
function
(
object3d
){
return
object3d
.
_3xDomEvent
;
}
/********************************************************************************/
/* */
/********************************************************************************/
/**
* Getter/Setter for camera
*/
THREEx
.
DomEvents
.
prototype
.
camera
=
function
(
value
)
{
if
(
value
)
this
.
_camera
=
value
;
return
this
.
_camera
;
}
THREEx
.
DomEvents
.
prototype
.
bind
=
function
(
object3d
,
eventName
,
callback
,
useCapture
)
{
console
.
assert
(
THREEx
.
DomEvents
.
eventNames
.
indexOf
(
eventName
)
!==
-
1
,
"
not available events:
"
+
eventName
);
if
(
!
this
.
_objectCtxIsInit
(
object3d
)
)
this
.
_objectCtxInit
(
object3d
);
var
objectCtx
=
this
.
_objectCtxGet
(
object3d
);
if
(
!
objectCtx
[
eventName
+
'
Handlers
'
]
)
objectCtx
[
eventName
+
'
Handlers
'
]
=
[];
objectCtx
[
eventName
+
'
Handlers
'
].
push
({
callback
:
callback
,
useCapture
:
useCapture
});
// add this object in this._boundObjs
if
(
this
.
_boundObjs
[
eventName
]
===
undefined
){
this
.
_boundObjs
[
eventName
]
=
[];
}
this
.
_boundObjs
[
eventName
].
push
(
object3d
);
}
THREEx
.
DomEvents
.
prototype
.
addEventListener
=
THREEx
.
DomEvents
.
prototype
.
bind
THREEx
.
DomEvents
.
prototype
.
unbind
=
function
(
object3d
,
eventName
,
callback
,
useCapture
)
{
console
.
assert
(
THREEx
.
DomEvents
.
eventNames
.
indexOf
(
eventName
)
!==
-
1
,
"
not available events:
"
+
eventName
);
if
(
!
this
.
_objectCtxIsInit
(
object3d
)
)
this
.
_objectCtxInit
(
object3d
);
var
objectCtx
=
this
.
_objectCtxGet
(
object3d
);
if
(
!
objectCtx
[
eventName
+
'
Handlers
'
]
)
objectCtx
[
eventName
+
'
Handlers
'
]
=
[];
var
handlers
=
objectCtx
[
eventName
+
'
Handlers
'
];
for
(
var
i
=
0
;
i
<
handlers
.
length
;
i
++
){
var
handler
=
handlers
[
i
];
if
(
callback
!=
handler
.
callback
)
continue
;
if
(
useCapture
!=
handler
.
useCapture
)
continue
;
handlers
.
splice
(
i
,
1
)
break
;
}
// from this object from this._boundObjs
var
index
=
this
.
_boundObjs
[
eventName
].
indexOf
(
object3d
);
console
.
assert
(
index
!==
-
1
);
this
.
_boundObjs
[
eventName
].
splice
(
index
,
1
);
}
THREEx
.
DomEvents
.
prototype
.
removeEventListener
=
THREEx
.
DomEvents
.
prototype
.
unbind
THREEx
.
DomEvents
.
prototype
.
_bound
=
function
(
eventName
,
object3d
)
{
var
objectCtx
=
this
.
_objectCtxGet
(
object3d
);
if
(
!
objectCtx
)
return
false
;
return
objectCtx
[
eventName
+
'
Handlers
'
]
?
true
:
false
;
}
/********************************************************************************/
/* onMove */
/********************************************************************************/
// # handle mousemove kind of events
THREEx
.
DomEvents
.
prototype
.
_onMove
=
function
(
eventName
,
mouseX
,
mouseY
,
origDomEvent
)
{
//console.log('eventName', eventName, 'boundObjs', this._boundObjs[eventName])
// get objects bound to this event
var
boundObjs
=
this
.
_boundObjs
[
eventName
];
if
(
boundObjs
===
undefined
||
boundObjs
.
length
===
0
)
return
;
// compute the intersection
var
vector
=
new
THREE
.
Vector2
();
// update the picking ray with the camera and mouse position
vector
.
set
(
mouseX
,
mouseY
);
this
.
_raycaster
.
setFromCamera
(
vector
,
this
.
_camera
);
var
intersects
=
this
.
_raycaster
.
intersectObjects
(
boundObjs
);
var
oldSelected
=
this
.
_selected
;
if
(
intersects
.
length
>
0
){
var
notifyOver
,
notifyOut
,
notifyMove
;
var
intersect
=
intersects
[
0
];
var
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
;
}
// notify mouseMove - done at the end with a copy of the list to allow callback to remove handlers
notifyMove
&&
this
.
_notify
(
'
mousemove
'
,
newSelected
,
origDomEvent
,
intersect
);
// notify mouseEnter - done at the end with a copy of the list to allow callback to remove handlers
notifyOver
&&
this
.
_notify
(
'
mouseover
'
,
newSelected
,
origDomEvent
,
intersect
);
// notify mouseLeave - done at the end with a copy of the list to allow callback to remove handlers
notifyOut
&&
this
.
_notify
(
'
mouseout
'
,
oldSelected
,
origDomEvent
,
intersect
);
}
/********************************************************************************/
/* onEvent */
/********************************************************************************/
// # handle click kind of events
THREEx
.
DomEvents
.
prototype
.
_onEvent
=
function
(
eventName
,
mouseX
,
mouseY
,
origDomEvent
)
{
//console.log('eventName', eventName, 'boundObjs', this._boundObjs[eventName])
// get objects bound to this event
var
boundObjs
=
this
.
_boundObjs
[
eventName
];
if
(
boundObjs
===
undefined
||
boundObjs
.
length
===
0
)
return
;
// compute the intersection
var
vector
=
new
THREE
.
Vector2
();
// update the picking ray with the camera and mouse position
vector
.
set
(
mouseX
,
mouseY
);
this
.
_raycaster
.
setFromCamera
(
vector
,
this
.
_camera
);
var
intersects
=
this
.
_raycaster
.
intersectObjects
(
boundObjs
,
true
);
// if there are no intersections, return now
if
(
intersects
.
length
===
0
)
return
;
// init some variables
var
intersect
=
intersects
[
0
];
var
object3d
=
intersect
.
object
;
var
objectCtx
=
this
.
_objectCtxGet
(
object3d
);
var
objectParent
=
object3d
.
parent
;
while
(
typeof
(
objectCtx
)
==
'
undefined
'
&&
objectParent
)
{
objectCtx
=
this
.
_objectCtxGet
(
objectParent
);
objectParent
=
objectParent
.
parent
;
}
if
(
!
objectCtx
)
return
;
// notify handlers
this
.
_notify
(
eventName
,
object3d
,
origDomEvent
,
intersect
);
}
THREEx
.
DomEvents
.
prototype
.
_notify
=
function
(
eventName
,
object3d
,
origDomEvent
,
intersect
)
{
var
objectCtx
=
this
.
_objectCtxGet
(
object3d
);
var
handlers
=
objectCtx
?
objectCtx
[
eventName
+
'
Handlers
'
]
:
null
;
// parameter check
console
.
assert
(
arguments
.
length
===
4
)
// do bubbling
if
(
!
objectCtx
||
!
handlers
||
handlers
.
length
===
0
){
object3d
.
parent
&&
this
.
_notify
(
eventName
,
object3d
.
parent
,
origDomEvent
,
intersect
);
return
;
}
// notify all handlers
var
handlers
=
objectCtx
[
eventName
+
'
Handlers
'
];
for
(
var
i
=
0
;
i
<
handlers
.
length
;
i
++
){
var
handler
=
handlers
[
i
];
var
toPropagate
=
true
;
handler
.
callback
({
type
:
eventName
,
target
:
object3d
,
origDomEvent
:
origDomEvent
,
intersect
:
intersect
,
stopPropagation
:
function
(){
toPropagate
=
false
;
}
});
if
(
!
toPropagate
)
continue
;
// do bubbling
if
(
handler
.
useCapture
===
false
){
object3d
.
parent
&&
this
.
_notify
(
eventName
,
object3d
.
parent
,
origDomEvent
,
intersect
);
}
}
}
/********************************************************************************/
/* handle mouse events */
/********************************************************************************/
// # handle mouse events
THREEx
.
DomEvents
.
prototype
.
_onMouseDown
=
function
(
event
){
return
this
.
_onMouseEvent
(
'
mousedown
'
,
event
);
}
THREEx
.
DomEvents
.
prototype
.
_onMouseUp
=
function
(
event
){
return
this
.
_onMouseEvent
(
'
mouseup
'
,
event
);
}
THREEx
.
DomEvents
.
prototype
.
_onMouseEvent
=
function
(
eventName
,
domEvent
)
{
var
mouseCoords
=
this
.
_getRelativeMouseXY
(
domEvent
);
this
.
_onEvent
(
eventName
,
mouseCoords
.
x
,
mouseCoords
.
y
,
domEvent
);
}
THREEx
.
DomEvents
.
prototype
.
_onMouseMove
=
function
(
domEvent
)
{
var
mouseCoords
=
this
.
_getRelativeMouseXY
(
domEvent
);
this
.
_onMove
(
'
mousemove
'
,
mouseCoords
.
x
,
mouseCoords
.
y
,
domEvent
);
this
.
_onMove
(
'
mouseover
'
,
mouseCoords
.
x
,
mouseCoords
.
y
,
domEvent
);
this
.
_onMove
(
'
mouseout
'
,
mouseCoords
.
x
,
mouseCoords
.
y
,
domEvent
);
}
THREEx
.
DomEvents
.
prototype
.
_onClick
=
function
(
event
)
{
// TODO handle touch ?
this
.
_onMouseEvent
(
'
click
'
,
event
);
}
THREEx
.
DomEvents
.
prototype
.
_onDblClick
=
function
(
event
)
{
// TODO handle touch ?
this
.
_onMouseEvent
(
'
dblclick
'
,
event
);
}
THREEx
.
DomEvents
.
prototype
.
_onContextmenu
=
function
(
event
)
{
//TODO don't have a clue about how this should work with touch..
this
.
_onMouseEvent
(
'
contextmenu
'
,
event
);
}
/********************************************************************************/
/* handle touch events */
/********************************************************************************/
// # handle touch events
THREEx
.
DomEvents
.
prototype
.
_onTouchStart
=
function
(
event
){
return
this
.
_onTouchEvent
(
'
touchstart
'
,
event
);
}
THREEx
.
DomEvents
.
prototype
.
_onTouchEnd
=
function
(
event
){
return
this
.
_onTouchEvent
(
'
touchend
'
,
event
);
}
THREEx
.
DomEvents
.
prototype
.
_onTouchMove
=
function
(
domEvent
)
{
if
(
domEvent
.
touches
.
length
!=
1
)
return
undefined
;
domEvent
.
preventDefault
();
var
mouseX
=
+
(
domEvent
.
touches
[
0
].
pageX
/
window
.
innerWidth
)
*
2
-
1
;
var
mouseY
=
-
(
domEvent
.
touches
[
0
].
pageY
/
window
.
innerHeight
)
*
2
+
1
;
this
.
_onMove
(
'
mousemove
'
,
mouseX
,
mouseY
,
domEvent
);
this
.
_onMove
(
'
mouseover
'
,
mouseX
,
mouseY
,
domEvent
);
this
.
_onMove
(
'
mouseout
'
,
mouseX
,
mouseY
,
domEvent
);
}
THREEx
.
DomEvents
.
prototype
.
_onTouchEvent
=
function
(
eventName
,
domEvent
)
{
if
(
domEvent
.
touches
.
length
!=
1
)
return
undefined
;
domEvent
.
preventDefault
();
var
mouseX
=
+
(
domEvent
.
touches
[
0
].
pageX
/
window
.
innerWidth
)
*
2
-
1
;
var
mouseY
=
-
(
domEvent
.
touches
[
0
].
pageY
/
window
.
innerHeight
)
*
2
+
1
;
this
.
_onEvent
(
eventName
,
mouseX
,
mouseY
,
domEvent
);
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
sign in
to comment