-
Notifications
You must be signed in to change notification settings - Fork 471
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
187 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<title> | ||
Replacing RxJS With A State Machine In JavaScript | ||
</title> | ||
<link rel="stylesheet" type="text/css" href="./main.css" /> | ||
</head> | ||
<body> | ||
|
||
<h1> | ||
Replacing RxJS With A State Machine In JavaScript | ||
</h1> | ||
|
||
<p> | ||
If you mouse-down and then start dragging (vertically), you get console logging. | ||
</p> | ||
|
||
<script type="text/javascript"> | ||
|
||
default_setup(); | ||
|
||
// --- | ||
// DEFAULT STATE: At this point, the user is just viewing the page, but has not | ||
// yet interacted with it. Once they mousedown, we'll move into the pending state. | ||
// --- | ||
|
||
function default_setup() { | ||
|
||
console.info( "Default: Setup" ); | ||
document.addEventListener( "mousedown", default_handleMousedown ); | ||
|
||
} | ||
|
||
function default_teardown() { | ||
|
||
console.info( "Default: Teardown" ); | ||
document.removeEventListener( "mousedown", default_handleMousedown ); | ||
|
||
} | ||
|
||
function default_handleMousedown( event ) { | ||
|
||
event.preventDefault(); | ||
|
||
default_teardown(); | ||
pending_setup( event.clientY ); | ||
|
||
} | ||
|
||
// --- | ||
// PENDING STATE: The user has moused-down on the page, but we don't yet know if | ||
// they intend to drag or just click. If they do start to drag (and pass a minimum | ||
// threshold), we'll move into the dragging state. | ||
// --- | ||
|
||
function pending_setup( clientY ) { | ||
|
||
console.info( "Pending: Setup" ); | ||
document.addEventListener( "mouseup", pending_handleMouseup ); | ||
document.addEventListener( "mousemove", pending_handleMousemove ); | ||
|
||
pending_setup.initialClientY = clientY; | ||
|
||
} | ||
|
||
function pending_teardown() { | ||
|
||
console.info( "Pending: Teardown" ); | ||
document.removeEventListener( "mouseup", pending_handleMouseup ); | ||
document.removeEventListener( "mousemove", pending_handleMousemove ); | ||
|
||
} | ||
|
||
function pending_handleMouseup( event ) { | ||
|
||
pending_teardown(); | ||
default_setup(); | ||
|
||
} | ||
|
||
function pending_handleMousemove( event ) { | ||
|
||
// Only move onto next state if dragging threshold is passed. | ||
// -- | ||
// CAUTION: This concept was not present in the RxJS version; but, I think it | ||
// should have been. And, in the state-based approach (for me) it is easier to | ||
// reason about this update using states vs. streams. | ||
if ( Math.abs( pending_setup.initialClientY - event.clientY ) > 10 ) { | ||
|
||
pending_teardown(); | ||
dragging_setup( pending_setup.initialClientY ); | ||
|
||
} | ||
|
||
} | ||
|
||
// --- | ||
// DRAGGING STATE. | ||
// --- | ||
|
||
function dragging_setup( clientY ) { | ||
|
||
console.info( "Dragging: Setup" ); | ||
document.addEventListener( "mousemove", dragging_handleMousemove ); | ||
document.addEventListener( "mouseup", dragging_handleMouseup ); | ||
|
||
dragging_setup.initialClientY = clientY; | ||
dragging_setup.currentClientY = null; | ||
dragging_setup.timer = setInterval( dragging_handleInterval, 60 ); | ||
|
||
} | ||
|
||
function dragging_teardown() { | ||
|
||
console.info( "Dragging: Teardown" ); | ||
document.removeEventListener( "mousemove", dragging_handleMousemove ); | ||
document.removeEventListener( "mouseup", dragging_handleMouseup ); | ||
clearInterval( dragging_setup.timer ); | ||
|
||
} | ||
|
||
function dragging_handleMousemove( event ) { | ||
|
||
dragging_setup.currentClientY = event.clientY; | ||
|
||
} | ||
|
||
function dragging_handleMouseup( event ) { | ||
|
||
dragging_teardown(); | ||
default_setup(); | ||
|
||
} | ||
|
||
function dragging_handleInterval() { | ||
|
||
console.log( | ||
"Drag delta from origin:", | ||
( dragging_setup.currentClientY - dragging_setup.initialClientY ) | ||
); | ||
|
||
} | ||
|
||
</script> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
|
||
html { | ||
box-sizing: border-box ; | ||
} | ||
html *, | ||
html *:before, | ||
html *:after { | ||
box-sizing: inherit ; | ||
} | ||
|
||
body { | ||
font-family: sans-serif ; | ||
font-size: 18px ; | ||
line-height: 1.4 ; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Get the three major events | ||
var mouseup = Rx.Observable.fromEvent(document, 'mouseup'); | ||
var mousemove = Rx.Observable.fromEvent(document, 'mousemove'); | ||
var mousedown = Rx.Observable.fromEvent(dragTarget, 'mousedown'); | ||
var intervalSource = Rx.Observable.interval(60, Rx.Scheduler.requestAnimationFrame); | ||
|
||
var mousedrag = mousedown.flatMap(function(md) { | ||
return intervalSource | ||
.takeUntil(mouseup) | ||
.withLatestFrom(mousemove, function(s1, s2) { | ||
return s2.clientY; | ||
}) | ||
.scan(md.clientY, function( initialClientY, clientY ) { | ||
return( clientY - initialClientY ); | ||
}) | ||
; | ||
}); | ||
|
||
mousedrag.subscribe(function( delta ) { | ||
console.log( "Drag delta from origin:", delta ); | ||
}); |