diff --git a/lib/stylus/README.txt b/lib/stylus/README.txt deleted file mode 100644 index e4da17e..0000000 --- a/lib/stylus/README.txt +++ /dev/null @@ -1,13 +0,0 @@ - - -https://mattdesl.svbtle.com/drawing-lines-is-hard -http://perfectionkills.com/exploring-canvas-drawing-techniques/ - - - -https://github.com/mattdesl/polyline-normals - -var path = [ [0, 122], [0, 190], [90, 190] ] - -//get the normals as a closed loop -var normals = getNormals(path, true) diff --git a/lib/stylus/index.html b/lib/stylus/index.html deleted file mode 100644 index 1a38d4a..0000000 --- a/lib/stylus/index.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - Stylus Functional Tests - - - - - - -
- - Get a better browser, bro. - -
- - - diff --git a/lib/stylus/main.js b/lib/stylus/main.js deleted file mode 100644 index d3ff5ce..0000000 --- a/lib/stylus/main.js +++ /dev/null @@ -1,90 +0,0 @@ -import PIXIApp from '../../lib/pixi/app.js' -import Button from '../../lib/pixi/button.js' -import ButtonGroup from '../../lib/pixi/buttongroup.js' -import Stylus from './stylus.js' - -class StylusApp extends PIXIApp { - - sceneFactory() { - return new Stylus(this.renderer) - } - - setup() { - let buttonColor = 0x666666 - super.setup() - - this.tools = new ButtonGroup({ - type: 'checkbox', - margin: 0, - x: 16, - y: 16, - fill: buttonColor, - buttons: [{icon: 'edit', - iconColorActive: 0xFFFF00, - action: (event, button) => this.toggleEditMode() }, - {icon: 'undo', - action: (event, button) => this.undo(button) }, - {icon: 'redo', - action: (event, button) => this.redo(button) }, - {icon: 'delete', - action: (event, button) => this.clear(button) } - ] - }) - this.scene.addChild(this.tools) - - let defaults = { icon: 'brightness_1', - action: (event, button) => this.selectColor(button), - fillAlpha: 0, - strokeAlpha: 0, - fillActiveAlpha: 0, - strokeActiveAlpha: 0} - - this.palette = new ButtonGroup( { - type: "radio", - x: 200, - y: 16, - margin: 0, - strokeAlpha: 0, - fill: buttonColor, - buttons: [ - Object.assign({}, defaults, { iconColor: 0x111111, - iconColorActive: 0x111111}), // tooltip: "Black", - Object.assign({}, defaults, { iconColor: 0xFFFF00, - iconColorActive: 0xFFFF00}), // tooltip: "Yellow", - Object.assign({}, defaults, { iconColor: 0x00FF00, - iconColorActive:0x00FF00}), // tooltip: "Green", - Object.assign({}, defaults, { iconColor: 0xFF00FF, - iconColorActive:0xFF00FF}) // tooltip: "Violet", - ] - }) - this.scene.addChild(this.palette) - } - - selectColor(button) { - this.scene.color = button.opts.iconColor - } - - undo(button) { - this.scene.undo() - setTimeout(() => { - button.active = false}, 200) - } - - redo(button) { - this.scene.redo() - setTimeout(() => { - button.active = false}, 200) - } - - clear(button) { - this.scene.clearAll() - setTimeout(() => { - button.active = false}, 200) - } -} - -const app = new StylusApp({ view: canvas }) -window.app = app -app.setup() -app.run() - diff --git a/lib/stylus/stylus.js b/lib/stylus/stylus.js deleted file mode 100644 index dbbbbe0..0000000 --- a/lib/stylus/stylus.js +++ /dev/null @@ -1,398 +0,0 @@ -import Events from '../events.js' -import { Angle } from '../utils.js' - -class StylusCommand extends Object { - - constructor() { - super() - } - - do(stylus) { - stylus.commandStack.push(this) - } - - undo(stylus) { - stylus.undoCommandStack.push(this) - } - - redo(stylus) { - this.do(stylus) - } -} - -class StrokeCommand extends StylusCommand { - - constructor(stroke) { - super() - this.stroke = stroke - } - - do(stylus) { - if (this.stroke.length > 0) { - super.do(stylus) - stylus.stroke = [] - stylus.strokes.push(this.stroke) - stylus.redraw() - stylus.changed() - } - } - - undo(stylus) { - if (this.stroke.length > 0) { - super.undo(stylus) - stylus.strokes.pop() - stylus.redraw() - stylus.changed() - } - } -} - -class ClearCommand extends StylusCommand { - - do(stylus) { - // Clears the command stack - stylus.commandStack = [] - super.do(stylus) - this.strokes = stylus.strokes - stylus.stroke = [] - stylus.strokes = [] - stylus.redraw() - stylus.changed() - } - - undo(stylus) { - //super.undo(stylus) // Clear all is not redoable - stylus.stroke = [] - stylus.strokes = this.strokes - stylus.redraw() - stylus.changed() - } -} - - -export default class Stylus extends PIXI.Graphics { - - constructor({ width = window.innerWidth, - height = window.innerHeight, - interactive = true, - color = 0x000000, - tiltX = 0, - tiltY = 0, - backgroundAlpha = 1, - backgroundFill = 0xFFFFFF, - colorAlpha = 1, - captureEvents = true, - acceptMouseEvents = true } = {}) { - super() - this.wantedWidth = width - this.wantedHeight = height - this.backgroundAlpha = backgroundAlpha - this.backgroundFill = backgroundFill - this.colorAlpha = colorAlpha - this.color = color - this.interactive = interactive - this.debug = false - this.tiltX = tiltX // degrees -90 ... 90 - this.tiltY = tiltY // degrees -90 ... 90 - this.captureEvents = captureEvents - this.commandStack = [] - this.undoCommandStack = [] - this.strokes = [] - this.stroke = [] - if (captureEvents) - this.registerEventHandler(acceptMouseEvents) - this.drawBackground() - } - - drawBackground() { - this.clear() - this.beginFill(this.backgroundFill, this.backgroundAlpha) - this.drawRect(0, 0, this.wantedWidth, this.wantedHeight) - this.endFill() - } - - touchToPoint(t) { - return { x: t.clientX, y: t.clientY } - } - - isStylusPointer(event) { - let identifier = event.data.identifier - if (typeof (event.data.originalEvent.changedTouches) !== 'undefined') { - for (let touch of event.data.originalEvent.changedTouches) { - if (touch.identifier === identifier && touch.touchType === 'stylus') { - this.tiltX = Angle.radian2degree(touch.azimuthAngle) - this.tiltY = 90.0 - Angle.radian2degree(touch.altitudeAngle) - return true - } - } - } - // UO: Not tested since the Sprot delivered "mouse" events to Chrome - if (event.data.originalEvent.pointerType === 'pen') { - this.tiltX = event.data.originalEvent.tiltX - this.tiltY = event.data.originalEvent.tiltY - return true - } - return false - } - - isStylusTouch(event) { - let identifier = event.data.identifier - if (typeof (event.data.originalEvent.changedTouches) !== 'undefined') { - for (let touch of event.data.originalEvent.changedTouches) { - if (touch.identifier === identifier && touch.pointerType === 'touch') { - return true - } - } - } - return false - } - - getPointerID(event) { - let identifier = event.data.identifier - for (let touch of event.data.originalEvent.changedTouches) { - if (touch.identifier === identifier) { - return touch.pointerId - } - } - } - - registerEventHandler() { - window.addEventListener('keydown', (e) => { - switch (e.keyCode) { - case 38: // up arrow - this.tiltX += 5 - break - case 40: // down arrow - this.tiltX -= 5 - break - case 37: // left arrow - this.tiltY -= 5 - break - case 39: // right arrow - this.tiltY += 5 - break - } - if (this.debug) console.log("keydown", e.keyCode, this.tiltX, this.tiltY) - }) - - this.on('pointerdown', (e) => { - if (this.debug) console.log("pointerdown", e) - if (this.eventInside(e)) - this.startStroke(this.toStroke(e)) - }) - this.on('pointermove', (e) => { - if (Events.isPointerDown(e.data.originalEvent) || this.isStylusPointer(e) || this.isStylusTouch(e)) { - if (this.debug) console.log("pointermove", e, this.eventInside(e)) - if (this.eventInside(e)) - this.moveStroke(this.toStroke(e)) - } - }) - this.on('pointerup', (e) => { - if (this.debug) console.log("pointerup", e) - if (this.eventInside(e)) - this.endStroke(this.toStroke(e)) - }) - this.on('pointerleave', (e) => { - this.endStroke(this.toStroke(e)) - }) - this.on('pointercancel', (e) => { - this.endStroke(this.toStroke(e)) - }) - } - - undoable() { - return this.commandStack.length > 0 - } - - redoable() { - return this.undoCommandStack.length > 0 - } - - undo() { - if (this.undoable()) { - let cmd = this.commandStack.pop() - cmd.undo(this) - } - } - - redo() { - if (this.redoable()) { - let cmd = this.undoCommandStack.pop() - cmd.redo(this) - } - } - - eventInside(event) { - - let local = this.toLocal(event.data.global) - for (let child of this.children) { - let r = child.getBounds() - if (r.contains(local.x, local.y)) { - console.log("Child touched") - return false - } - } - if (local.x < 0 || local.x > this.wantedWidth) - return false - if (local.y < 0 || local.y > this.wantedHeight) - return false - event.stopPropagation() - if (this.debug) console.log("stopPropagation", event) - if (event.data.originalEvent.claimedByScatter) { - return false - } - return true - } - - toLocalPoint(event) { - return this.toLocal(event.data.global) - } - - toStroke(event) { - let local = this.toLocalPoint(event) - let x = Math.max(0, Math.min(local.x, this.wantedWidth)) - let y = Math.max(0, Math.min(local.y, this.wantedHeight)) - let desc = { - x, y, - pressure: event.pressure || null, - tiltX: this.tiltX, tiltY: this.tiltY, - color: this.color - } - return desc - } - - startStroke(info) { - this.stroke = [info] - this.redraw() - } - - moveStroke(info) { - this.stroke.push(info) - this.redraw() - } - - endStroke(info) { - if (this.stroke.length > 1) { - let cmd = new StrokeCommand(this.stroke) - cmd.do(this) - } - } - - tiltToLineWidth(value) { - return Math.round(Math.abs(value / 10) + 1) - } - - drawStroke(stroke) { - if (stroke.length) { - let start = stroke[0] - this.beginFill(0, 0) - this.moveTo(start.x, start.y) - for (let i = 1; i < stroke.length; i++) { - let info = stroke[i] - this.lineStyle(this.tiltToLineWidth(info.tiltY), - info.color, this.colorAlpha) - this.lineTo(info.x, info.y) - } - this.endFill() - } - } - - drawTouch(point) { - this.beginFill(0, 0) - this.drawCircle(point.x, point.y, 22) - this.endFill() - } - - drawStrokes() { - this.drawBackground() - this.lineStyle(1.0, 0xFF0000, 1) - for (let stroke of this.iterStrokes()) { - this.drawStroke(stroke) - } - } - - redraw() { - this.drawStrokes() - } - - // Can be overwritten if different levels of strokes are necessary - *iterStrokes() { - for (let stroke of this.strokes) { - yield stroke - } - yield this.stroke - } - - changed() { - // Can be overwritten - } - - clearAll() { - let cmd = new ClearCommand() - cmd.do(this) - } - - normalizeInfo(info) { - let { x, y, pressure, tiltX, tiltY, color } = info - x /= this.wantedWidth - y /= this.wantedHeight - return { x, y, pressure, tiltX, tiltY, color } - } - - denormalizeInfo(info) { - let { x, y, pressure, tiltX, tiltY, color } = info - x = x * this.wantedWidth - y = y * this.wantedHeight - return { x, y, pressure, tiltX, tiltY, color } - } - - // Convert strokes into an object that can be stored in an Indexed DB. - // Returns normalized strokes - toObject() { - let result = [] - for (let stroke of this.strokes) { - let normalized = [] - for (let info of stroke) { - normalized.push(this.normalizeInfo(info)) - } - result.push(normalized) - } - return result - } - - // Read normalized strokes from an object from an Indexed DB. - fromObject(normalizedStrokes) { - this.strokes = [] - for (let stroke of normalizedStrokes) { - let denormalized = [] - for (let info of stroke) { - denormalized.push(this.denormalizeInfo(info)) - } - this.strokes.push(denormalized) - } - } - - // Convert strokes into a JSON object that can be stored in an Indexed DB - toJSON() { - return JSON.stringify(this.toObject()) - } - - // Convert strokes from a JSON - fromJSON(json) { - this.fromObject(JSON.parse(json)) - } - - // Returns a set of used colors - usedColors() { - let used = new Set() - for (let info of this.stroke) { - used.add(info.color) - } - for (let stroke of this.strokes) { - for (let info of stroke) { - used.add(info.color) - } - } - return used.values() - } -} diff --git a/lib/stylus/thumbnail.png b/lib/stylus/thumbnail.png deleted file mode 100644 index e2c7b2b..0000000 Binary files a/lib/stylus/thumbnail.png and /dev/null differ