mirror of
https://github.com/sbrl/Nibriboard.git
synced 2018-01-10 21:33:49 +00:00
[client] Create skeleton for new eraser.
Also, send the actual absolute cursor position instead of the cursor position in screen space.
This commit is contained in:
parent
64667dcc10
commit
d5f6407cf5
7 changed files with 59 additions and 10 deletions
|
@ -185,7 +185,7 @@ class BoardWindow extends EventEmitter
|
|||
}).bind(this))
|
||||
|
||||
// Keep the server up to date on our viewport and cursor position
|
||||
this.cursorSyncer = new CursorSyncer(this.rippleLink, this.cursorUpdateFrequency)
|
||||
this.cursorSyncer = new CursorSyncer(this, this.cursorUpdateFrequency)
|
||||
|
||||
// RippleLink message bindings
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
import { point_line_distance_multi } from 'line-distance-calculator';
|
||||
|
||||
/**
|
||||
* Represents a single chunk on a plane.
|
||||
* Note that this is the client's representation of the chunk, so it's likely
|
||||
|
@ -14,8 +16,11 @@ class Chunk
|
|||
*/
|
||||
constructor(inChunkRef, inSize)
|
||||
{
|
||||
/** @type {ChunkReference} */
|
||||
this.chunkRef = inChunkRef;
|
||||
/** @type {number} */
|
||||
this.size = inSize;
|
||||
/** @type {[ { Points: [Vector], Width: number, Color: string }] */
|
||||
this.lines = [];
|
||||
}
|
||||
|
||||
|
@ -62,6 +67,23 @@ class Chunk
|
|||
return area.overlaps(area);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the last line segment that lies underneath the specified point.
|
||||
* Prefers lines drawn later to lines drawn earlier.
|
||||
* @param {Vector} point The point to find the line underneath.
|
||||
* @return {object|null} The first line (segment) that lies underneath the specified point, or null if one couldn't be found.
|
||||
*/
|
||||
getLineUnderPoint(point)
|
||||
{
|
||||
// Prefer lines that have been drawn later (i.e. on top)
|
||||
for (let i = this.lines.length - 1; i > 0; i--) {
|
||||
// If our distance to the line is less than half the width (i.e.
|
||||
// the radius), then we must be inside it
|
||||
if(point_line_distance_multi(point, this.lines[i].Points) <= this.lines[i].Width / 2)
|
||||
return this.lines[i];
|
||||
}
|
||||
}
|
||||
|
||||
update(dt)
|
||||
{
|
||||
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
"use strict";
|
||||
|
||||
import Vector from './Utilities/Vector.js';
|
||||
|
||||
class CursorSyncer
|
||||
{
|
||||
constructor(inRippleLink, syncFrequency)
|
||||
constructor(inBoardWindow, syncFrequency)
|
||||
{
|
||||
this.boardWindow = inBoardWindow
|
||||
// The ripple link we should send the cursor updates down
|
||||
this.rippleLink = inRippleLink;
|
||||
this.rippleLink = this.boardWindow.rippleLink;
|
||||
// The target frequency in fps at we should send cursor updates.
|
||||
this.cursorUpdateFrequency = syncFrequency;
|
||||
|
||||
|
@ -13,7 +16,10 @@ class CursorSyncer
|
|||
// link connects
|
||||
this.rippleLink.on("connect", this.setup.bind(this));
|
||||
|
||||
this.cursorPosition = { X: 0, Y: 0 };
|
||||
/** The current cursor position in screen-space. @type {Vector} */
|
||||
this.cursorPosition = new Vector(0, 0);
|
||||
/** The current cursor position in plane-space. @type {Vector} */
|
||||
this.absCursorPosition = new Vector(0, 0);
|
||||
}
|
||||
|
||||
setup()
|
||||
|
@ -22,10 +28,11 @@ class CursorSyncer
|
|||
this.lastCursorUpdate = 0;
|
||||
|
||||
document.addEventListener("mousemove", (function(event) {
|
||||
this.cursorPosition = {
|
||||
X: event.clientX,
|
||||
Y: event.clientY
|
||||
};
|
||||
this.cursorPosition.x = event.clientX;
|
||||
this.cursorPosition.y = event.clientY;
|
||||
|
||||
this.absCursorPosition.x = this.boardWindow.viewport.x + this.cursorPosition.x;
|
||||
this.absCursorPosition.y = this.boardWindow.viewport.y + this.cursorPosition.y;
|
||||
|
||||
setTimeout((function() {
|
||||
// Throttle the cursor updates we send to the server - a high
|
||||
|
@ -50,7 +57,10 @@ class CursorSyncer
|
|||
// Update the server on the mouse's position
|
||||
this.rippleLink.send({
|
||||
"Event": "CursorPosition",
|
||||
"AbsCursorPosition": this.cursorPosition
|
||||
"AbsCursorPosition": {
|
||||
X: Math.floor(this.absCursorPosition.x),
|
||||
Y: Math.floor(this.absCursorPosition.y)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import cuid from "cuid";
|
||||
import { simplify_line } from "visvalingam-simplifier";
|
||||
|
||||
import ChunkReference from './ChunkReference.js';
|
||||
import Vector from './Utilities/Vector';
|
||||
import Mouse from './Utilities/Mouse';
|
||||
|
||||
|
@ -129,6 +130,21 @@ class Pencil
|
|||
this.sendUnsent();
|
||||
break;
|
||||
|
||||
case "eraser":
|
||||
let locRef = this.boardWin.cursorSyncer.absCursorPosition;
|
||||
let hoverChunkRef = new ChunkReference(
|
||||
this.boardWindow.currentPlaneName,
|
||||
Math.floor((this.boardWindow.viewport.x + this.mouse.position.x) / this.boardWindow.gridSize),
|
||||
Math.floor((this.boardWindow.viewport.y + this.mouse.position.y) / this.boardWindow.gridSize)
|
||||
);
|
||||
|
||||
let hoverChunk = this.boardWindow.chunkCache.fetchChunk(hoverChunk);
|
||||
if(hoverChunk == null)
|
||||
break; // If it's null, then we haven't received it yet from the server
|
||||
|
||||
let lineToErase = hoverChunk.getLineUnderPoint()
|
||||
break;
|
||||
|
||||
case "pan":
|
||||
// handled by BoardWindow.handleCanvasMovement(event)
|
||||
break;
|
||||
|
|
BIN
Nibriboard/ClientFiles/images/icons/eraser.png
Normal file
BIN
Nibriboard/ClientFiles/images/icons/eraser.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 489 B |
|
@ -21,6 +21,7 @@
|
|||
|
||||
<section class="tools">
|
||||
<span class="tool-selector" data-tool-name="brush" title="Draw lines with a brush." data-selected><img src="images/icons/brush.png" aria-hidden="true" /></span>
|
||||
<span class="tool-selector" data-tool-name="eraser" title="Erase lines. Remember that you can't undo/redo yet!"><img src="images/icons/eraser.png" aria-hidden="true" /></span>
|
||||
<span class="tool-selector" data-tool-name="pan" title="Pan around the plane."><img src="images/icons/pan.png" aria-hidden="true" /></span>
|
||||
<span class="tool-selector" data-tool-name="pointer" title="Point at things, but don't change them."><img src="images/icons/point.png" aria-hidden="true" /></span>
|
||||
</section>
|
||||
|
|
|
@ -47,7 +47,7 @@ Note that if you're intending to use Nibriboard over the internet or an untruste
|
|||
- Images:
|
||||
- [Transparent Square Tiles](https://www.toptal.com/designers/subtlepatterns/transparent-square-tiles/) from [subtlepatterns.com](https://subtlepatterns.com/)
|
||||
- Icons:
|
||||
- [OpenIconic](https://useiconic.com/open) - brush, move -> pan, sun -> point
|
||||
- [OpenIconic](https://useiconic.com/open) - brush, move -> pan, sun -> point, eraser -> delete
|
||||
- Future reference: Libraries I am considering
|
||||
- [Paper.js](http://paperjs.org/) - Client-side rendering
|
||||
- [IotWeb](http://sensaura.org/pages/tools/iotweb/) - Underlying HTTP / WebSocket server
|
||||
|
|
Loading…
Reference in a new issue