diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..78f1e87 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +dist +.nyc-output +/*.js \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 94539a5..d81a114 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,22 +1,21 @@ { "root": true, - "rules": {}, - "env": { - "es6": true, - "browser": true, - "jasmine": true - }, - "parserOptions": { - "ecmaVersion": 2018, - "sourceType": "module" - }, - "plugins": ["jasmine"], + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], "extends": [ "eslint:recommended", - "plugin:prettier/recommended", - "plugin:jasmine/recommended" + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" ], - "globals": { - "createjs": true + "rules": { + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-use-before-define": "off", + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/camelcase": "off", + "no-sparse-arrays": "off", + "no-prototype-builtins": "off" } } diff --git a/.gitignore b/.gitignore index 688baed..50c968b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ node_modules package-lock.json -research \ No newline at end of file +research +/dist +/tmp +/coverage +/docs \ No newline at end of file diff --git a/.nycrc.json b/.nycrc.json new file mode 100644 index 0000000..31dd491 --- /dev/null +++ b/.nycrc.json @@ -0,0 +1,8 @@ +{ + "cache": false, + "compact": false, + "reporter": ["text", "lcov"], + "excludeAfterRemap": false, + "all": true, + "temp-dir": "tmp" +} diff --git a/.travis.yml b/.travis.yml index 470c8f3..10c4f0d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,11 @@ language: node_js -# TODO: break out browsers into matrix + addons: chrome: stable node_js: - 10 +before_script: + - "npm run build" deploy: provider: npm email: jeremy@burnbright.net diff --git a/TODO.md b/TODO.md index 60d503f..435e02b 100644 --- a/TODO.md +++ b/TODO.md @@ -1,7 +1,48 @@ # TODO +Convert to Typescript? + Update border, and constrain elements +## Transforming a transformed Container's child DisplayObjects + +It is useful to support transforming elements within a container that might also have some transformations applied. + +Use case: design area has been resized/zoomed. + +Currently the coordinate systems are out, and the boundary mechanism fails too. + +Come up with a design / plan... + +We might need to introduce functions for transforming through parent layers. + +## Decomposing tools into classes + +Conceptually tool sequence is: + +- Provides a handle that can be dragged +- Take the handle's start and current events, the registration point +- Produces a potential transformation (of various types) +- Transformation gets limited by new bounds +- DisplayObject gets updated with final transform + +Tools therefore need to know: + +- Orientation point +- How to limit a transformation? Surely this is deterministic, but in some cases the math is hard, such as scaling + +Tools don't need to know + +## Types of bounds + +Oriented Bounds - bounds that have been positioned, rotated, scaled with the target +Simple Boundary Bounds - bounds that wrap the transformed oriented bounds +Complex Boundary Bounds - bounds that wrap the complexities of a shape: eg vector graphics, various primitive shapes, or images with some pixel analysis. + +We'll settle for a simple bounds approach, since reorienting isn't common. + +Current issue: we rely on un-oriented bounds to collide with boundary, resulting in the objects crossing over the boundary. Perhaps this is ok. + ## Build test infrastructure - Build out test suite @@ -72,3 +113,17 @@ Features - Allow moving the registration point with a handle - Prevent or warn when scaling above best print resolution + +Generalising cursor update logic + +```js +const ANGLE_STEP = 45; +const DIRECTIONS = ["n", "ne", "e", "se", "s", "sw", "w", "nw"]; + +export function angleToOrdinalDirection(angle: number): string { + const index = + Math.floor((angle + 360) / ANGLE_STEP + 0.5) % DIRECTIONS.length; + console.log(angle, DIRECTIONS[index], index); + return DIRECTIONS[index]; +} +``` diff --git a/createjs.util.FreeTransformTool.js b/createjs.util.FreeTransformTool.js deleted file mode 100644 index fde675c..0000000 --- a/createjs.util.FreeTransformTool.js +++ /dev/null @@ -1,569 +0,0 @@ -// namespace: -var createjs = this.createjs; - -// package -this.createjs.util = this.createjs.util || {}; - -// helpers - -function calcAngleDegrees(x, y) { - return (Math.atan2(y, x) * 180) / Math.PI; -} -this.createjs.util.calcAngleDegrees = calcAngleDegrees; - -function calcDistance(x1, y1, x2, y2) { - return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); -} -this.createjs.util.calcDistance = calcDistance; - -/** - * Force a rectangle to always be inside another by - * updating location and size. - * @param {createjs.Rectangle} rect - * @param {createjs.Rectangle} container - */ -function constrainRectTo(rect, container) { - if (rect.width >= container.width) { - rect.width = container.width; - } - if (rect.height >= container.height) { - rect.height = container.height; - } - if (rect.x <= container.x) { - rect.x = container.x; - } - if (rect.x + rect.width > container.x + container.width) { - rect.x = container.x + container.width - rect.width; - } - if (rect.y <= container.y) { - rect.y = container.y; - } - if (rect.y + rect.height > container.y + container.height) { - rect.y = container.y + container.height - rect.height; - } - return rect; -} -this.createjs.util.constrainRectTo = constrainRectTo; - -// constrains a display object to a given rect -function constrainObjectTo(obj, rect) { - var bounds = obj.getBounds(); - bounds.x = obj.x - obj.regX * obj.scaleX; - bounds.y = obj.y - obj.regY * obj.scaleY; - var constrained = new createjs.Rectangle( - bounds.x, - bounds.y, - bounds.width, - bounds.height - ); - constrainRectTo(constrained, rect); - obj.x = constrained.x + obj.regX * obj.scaleX; - obj.y = constrained.y + obj.regY * obj.scaleY; - // TODO: work out new scale to apply, rather than overlapping - var newScale = { - x: constrained.width / bounds.width, - y: constrained.height / bounds.height - }; - obj.scaleX *= newScale.x; - obj.scaleY *= newScale.y; -} -this.createjs.util.constrainObjectTo = constrainObjectTo; - -// class -(function() { - var FreeTransformTool = function( - lineColor, - dashed, - color, - controlsSize, - boundary - ) { - this.initialize(lineColor, dashed, color, controlsSize, boundary); - }; - var p = (FreeTransformTool.prototype = new createjs.Container()); - - // public properties: - p.moveTool = null; - p.moveHitArea = null; - p.scaleTool = null; - p.hScaleTool = null; - p.vScaleTool = null; - p.rotateTool = null; - p.target = null; - p.border = null; - p.dashed = null; - p.boundary = null; - - // constructor: - // copy before override - p.Container_initialize = p.initialize; - p.initialize = function(lineColor, dashed, color, controlsSize, boundary) { - this.Container_initialize(); - - // default values - lineColor = lineColor || "#4285F4"; - color = color || "rgba(255,255,255,0.8)"; - controlsSize = controlsSize || 10; - - this.controlsDim = 0.15; - this.controlStrokeThickness = 1; - this.dashed = dashed === undefined ? true : dashed; - - this.boundary = boundary === undefined ? null : boundary; - - var that = this; - - // create border - this.border = new createjs.Shape(); - this.border.color = lineColor; - this.addChild(this.border); - - function addToolTip(shape, name, cursor) { - shape.on("mouseover", function() { - that.setTitle(name); - that.setCursor(cursor); - }); - shape.on("mouseout", function() { - that.setTitle(); - that.setCursor("default"); - }); - } - - // create a transform control handle - var handleStrokeWidth = this.controlStrokeThickness; - function createHandle(name, cursor) { - var shape = new createjs.Shape(); - addToolTip(shape, name, cursor); - shape.graphics - .beginStroke(lineColor) - .setStrokeStyle(handleStrokeWidth) - .beginFill(color); - shape.x = shape.regX = controlsSize / 2; - shape.y = shape.regY = controlsSize / 2; - return shape; - } - - /** - * Move tool - * Drag anywhere within the object bounds to move. - * Click to deselect. - */ - this.moveTool = new createjs.Shape(); - addToolTip(this.moveTool, "Move", "move"); - this.moveTool.on("mousedown", function(downEvent) { - if (that.target) { - var tool = downEvent.currentTarget; - var tBounds = that.target.getBounds(); - var targetStart = that.target.clone(); - var scaledReg = { - x: that.target.regX * that.target.scaleX, - y: that.target.regY * that.target.scaleY - }; - tool.on("pressmove", function(moveEvent) { - that.alpha = that.controlsDim; - var newLocation = { - x: targetStart.x + moveEvent.stageX - downEvent.stageX, - y: targetStart.y + moveEvent.stageY - downEvent.stageY - }; - // constrain new location, if there is a boundary - if (that.boundary) { - var newBounds = new createjs.Rectangle( - newLocation.x - scaledReg.x, - newLocation.y - scaledReg.y, - tBounds.width * that.target.scaleX, - tBounds.height * that.target.scaleY - ); - var constrainedBounds = constrainRectTo(newBounds, that.boundary); - newLocation.x = constrainedBounds.x + scaledReg.x; - newLocation.y = constrainedBounds.y + scaledReg.y; - } - that.target.set(newLocation); - tool.dragDistance = calcDistance( - downEvent.stageX, - downEvent.stageY, - moveEvent.stageX, - moveEvent.stageY - ); - that.stage.update(); - }); - tool.on("pressup", function(upEvent) { - that.alpha = 1; - tool.removeAllEventListeners("pressmove"); - upEvent.stopPropagation(); - tool.dragDistance = 0; - that.stage.update(); - }); - } - }); - // click to deselect - this.moveTool.on("click", function(clickEvent) { - // only deselect if there was very little movement on click - // which helps on mobile devices, where it's difficult to - // tap without dragging slightly - var movedThreshold = 10; - if (clickEvent.currentTarget.dragDistance < movedThreshold) { - that.unselect(); - that.stage.update(); - } - }); - this.moveHitArea = new createjs.Shape(); - this.moveTool.hitArea = this.moveHitArea; - this.addChild(this.moveTool); - - // init hScale tool - this.hScaleTool = createHandle("Stretch", "e-resize"); - this.hScaleTool.graphics.drawRect(0, 0, controlsSize, controlsSize); - this.hScaleTool.on("mousedown", function(downEvent) { - if (that.target) { - var tool = downEvent.currentTarget; - var tBounds = that.target.getBounds(); - var targetStart = that.target.clone().set({ - width: tBounds.width, - height: tBounds.height - }); - tool.on("pressmove", function(moveEvent) { - that.alpha = that.controlsDim; - var distStart = calcDistance( - downEvent.stageX, - downEvent.stageY, - that.target.x, - that.target.y - ); - var distEnd = calcDistance( - moveEvent.stageX, - moveEvent.stageY, - that.target.x, - that.target.y - ); - var rescaleFactor = distEnd / distStart; - var updates = { - scaleX: targetStart.scaleX * rescaleFactor - }; - // constrain to bounds - if (that.boundary) { - var newBounds = new createjs.Rectangle( - targetStart.x - targetStart.regX * updates.scaleX, - targetStart.y - targetStart.regY * targetStart.scaleY, - targetStart.width * updates.scaleX, - targetStart.height - ); - var constrainedBounds = constrainRectTo(newBounds, that.boundary); - updates.scaleX = constrainedBounds.width / targetStart.width; - updates.x = constrainedBounds.x + targetStart.regX * updates.scaleX; - } - that.target.set(updates); - that.stage.update(); - }); - tool.on("pressup", function() { - tool.removeAllEventListeners("pressmove"); - that.alpha = 1; - that.stage.update(); - }); - } - }); - this.addChild(this.hScaleTool); - - // init vScale tool - this.vScaleTool = createHandle("Stretch", "s-resize"); - this.vScaleTool.graphics.drawRect(0, 0, controlsSize, controlsSize); - this.vScaleTool.on("mousedown", function(downEvent) { - if (that.target) { - var tool = downEvent.currentTarget; - var tBounds = that.target.getBounds(); - var targetStart = that.target.clone().set({ - width: tBounds.width, - height: tBounds.height - }); - tool.on("pressmove", function(moveEvent) { - that.alpha = that.controlsDim; - var distStart = calcDistance( - downEvent.stageX, - downEvent.stageY, - that.target.x, - that.target.y - ); - var distEnd = calcDistance( - moveEvent.stageX, - moveEvent.stageY, - that.target.x, - that.target.y - ); - var rescaleFactor = distEnd / distStart; - var updates = { - scaleY: targetStart.scaleY * rescaleFactor - }; - // constrain to bounds - if (that.boundary) { - var newBounds = new createjs.Rectangle( - targetStart.x - targetStart.regX * updates.scaleX, - targetStart.y - targetStart.regY * targetStart.scaleY, - targetStart.width, - targetStart.height * updates.scaleY - ); - var constrainedBounds = constrainRectTo(newBounds, that.boundary); - updates.scaleY = constrainedBounds.height / targetStart.height; - updates.y = constrainedBounds.y + targetStart.regY * updates.scaleY; - } - that.target.set(updates); - that.stage.update(); - }); - tool.on("pressup", function() { - tool.removeAllEventListeners("pressmove"); - that.alpha = 1; - that.stage.update(); - }); - } - }); - this.addChild(this.vScaleTool); - - /** - * Scale tool: - * Changes display object's scale based on - * the difference in position away/near the - * registration point - */ - this.scaleTool = createHandle("Resize", "se-resize"); - this.scaleTool.graphics.drawRect(0, 0, controlsSize, controlsSize); - this.scaleTool.on("mousedown", function(downEvent) { - if (that.target) { - var tool = downEvent.currentTarget; - var tBounds = that.target.getBounds(); - var targetStart = that.target.clone().set({ - width: tBounds.width, - height: tBounds.height - }); - tool.on("pressmove", function(moveEvent) { - that.alpha = that.controlsDim; - var distStart = calcDistance( - downEvent.stageX, - downEvent.stageY, - that.target.x, - that.target.y - ); - var distEnd = calcDistance( - moveEvent.stageX, - moveEvent.stageY, - that.target.x, - that.target.y - ); - var rescaleFactor = distEnd / distStart; - var updates = { - scaleX: targetStart.scaleX * rescaleFactor, - scaleY: targetStart.scaleY * rescaleFactor - }; - // constrain to bounds - if (that.boundary) { - var newBounds = new createjs.Rectangle( - targetStart.x - targetStart.regX * updates.scaleX, - targetStart.y - targetStart.regY * updates.scaleY, - targetStart.width * updates.scaleX, - targetStart.height * updates.scaleY - ); - var constrainedBounds = constrainRectTo(newBounds, that.boundary); - updates.scaleX = constrainedBounds.width / targetStart.width; - updates.scaleY = constrainedBounds.height / targetStart.height; - updates.x = constrainedBounds.x + targetStart.regX * updates.scaleX; - updates.y = constrainedBounds.y + targetStart.regY * updates.scaleY; - } - that.target.set(updates); - that.stage.update(); - }); - tool.on("pressup", function() { - tool.removeAllEventListeners("pressmove"); - that.alpha = 1; - that.stage.update(); - }); - } - }); - this.addChild(this.scaleTool); - - /** - * Rotate Tool: - * Rotates around registration point - * Work out delta angle between three points: - * 1. drag start point - * 2. registration point - * 3. drag end/current point - * Add that angle to the object's start rotation - */ - this.rotateTool = createHandle("Rotate", "pointer"); - this.rotateTool.graphics.drawEllipse(0, 0, controlsSize, controlsSize); - this.rotateTool.on("mousedown", function(downEvent) { - if (that.target) { - var tool = downEvent.currentTarget; - var startRotation = that.target.rotation; - tool.on("pressmove", function(moveEvent) { - that.alpha = 0.1; - // the drag point is relative to the display object x,y position on the stage (it's registration point) - var relativeStartPoint = { - x: downEvent.stageX - that.target.x, - y: downEvent.stageY - that.target.y - }; - var relativeEndPoint = { - x: moveEvent.stageX - that.target.x, - y: moveEvent.stageY - that.target.y - }; - var endAngle = calcAngleDegrees( - relativeEndPoint.x, - relativeEndPoint.y - ); - var startAngle = calcAngleDegrees( - relativeStartPoint.x, - relativeStartPoint.y - ); - var deltaAngle = endAngle - startAngle; - // TTODO: constrain to bounds - that.target.rotation = startRotation + deltaAngle; - that.stage.update(); - }); - tool.on("pressup", function() { - tool.removeAllEventListeners("pressmove"); - that.alpha = 1; - that.stage.update(); - }); - } - }); - this.addChild(this.rotateTool); - - // update - this.on("tick", function() { - that.update(); - }); - - this.visible = false; - }; - - // public methods: - p.select = function(target) { - if (target) { - // copy object translation/transformation - this.target = target; - var bounds = target.getBounds(); - this.width = bounds.width; - this.height = bounds.height; - this.scaleX = target.scaleX; - this.scaleY = target.scaleY; - this.x = target.x; - this.y = target.y; - this.rotation = target.rotation; - - // respect registration point of target - this.regX = -this.width / 2 + target.regX; - this.regY = -this.height / 2 + target.regY; - - // borders - this.border.graphics.clear(); - if (this.dashed) { - this.border.graphics.setStrokeDash([5, 5], 0); - } - this.border.graphics - .beginStroke(this.border.color) - .setStrokeStyle(this.controlStrokeThickness, 0, 0, 10, true) - .moveTo(-this.width / 2, -this.height / 2) - .lineTo(this.width / 2, -this.height / 2) - .moveTo(this.width / 2, this.height / 2) - .lineTo(-this.width / 2, this.height / 2); - if (this.dashed) { - this.border.graphics.setStrokeDash([5, 5], 0); - } - this.border.graphics - .setStrokeStyle(this.controlStrokeThickness, 0, 0, 10, true) - .moveTo(-this.width / 2, -this.height / 2) - .lineTo(-this.width / 2, this.height / 2) - .moveTo(this.width / 2, this.height / 2) - .lineTo(this.width / 2, -this.height / 2); - - // tools size should stay consistent - var toolScaleX = 1 / (this.scaleX * this.stage.scaleX); - var toolScaleY = 1 / (this.scaleY * this.stage.scaleY); - - // draw move hit area - this.moveHitArea.graphics - .clear() - .beginFill("#000") - .rect(-this.width / 2, -this.height / 2, this.width, this.height); - - // scale tool (bottom right) - this.scaleTool.x = bounds.width / 2; - this.scaleTool.y = bounds.height / 2; - this.scaleTool.scaleX = toolScaleX; - this.scaleTool.scaleY = toolScaleY; - - // hScale tool (right edge) - this.hScaleTool.x = bounds.width / 2; - this.hScaleTool.y = 0; - this.hScaleTool.scaleX = toolScaleX; - this.hScaleTool.scaleY = toolScaleY; - - // vScale tool (bottom edge) - this.vScaleTool.x = 0; - this.vScaleTool.y = bounds.height / 2; - this.vScaleTool.scaleX = toolScaleX; - this.vScaleTool.scaleY = toolScaleY; - - // rotate tool - this.rotateTool.x = bounds.width / 2; - this.rotateTool.y = -bounds.height / 2; - this.rotateTool.scaleX = toolScaleX; - this.rotateTool.scaleY = toolScaleY; - - this.visible = true; - } else { - this.unselect(); - } - return; - }; - - p.unselect = function() { - this.target = null; - this.visible = false; - }; - - p.update = function() { - if (this.target) { - this.select(this.target); - } - }; - - p.setTitle = function(title) { - title = title || ""; - this.stage.canvas.title = title; - }; - - p.setCursor = function(cursor) { - var cursors = [ - "e-resize", - "se-resize", - "s-resize", - "sw-resize", - "w-resize", - "nw-resize", - "n-resize", - "ne-resize" - ]; - var index = cursors.indexOf(cursor); - if (index >= 0) { - var angle = 45; - var rotation = this.target.rotation; - rotation = rotation + angle / 2; - var newIndex = index + Math.floor(rotation / angle); - newIndex = newIndex % cursors.length; - document.body.style.cursor = cursors[newIndex]; - } else { - document.body.style.cursor = cursor; - } - }; - - // override methods - // copy before override - p.Container_draw = p.draw; - p.draw = function(ctx, ignoreCache) { - if (this.DisplayObject_draw(ctx, ignoreCache)) { - return true; - } - this.Container_draw(ctx, ignoreCache); - return true; - }; - - createjs.util.FreeTransformTool = FreeTransformTool; -})(); diff --git a/demo/demo.js b/demo/demo.js deleted file mode 100644 index 56c0921..0000000 --- a/demo/demo.js +++ /dev/null @@ -1,172 +0,0 @@ -var canvas, stage; -var update = true; - -var boundary; -var boundaryLine; - -var selectTool; - -var container; - -function init() { - // create stage and point it to the canvas: - canvas = document.getElementById("Designer"); - stage = new createjs.Stage(canvas); - - // enable touch interactions if supported on the current device: - createjs.Touch.enable(stage); - - // enabled mouse over / out events - stage.enableMouseOver(10); - stage.mouseMoveOutside = true; // keep tracking the mouse even when it leaves the canvas - - // set up free transform tool - var top = new createjs.Container(); - top.name = "top"; - stage.addChild(top); - - // define boundary - boundary = new createjs.Rectangle(); - updateBoundary(boundary); - boundaryLine = new createjs.Shape(); - top.addChild(boundaryLine); - - let controlsSize = 10 * window.devicePixelRatio; - selectTool = new createjs.util.FreeTransformTool( - "#057", - true, - "rgba(255,255,255,0.8)", - controlsSize, - boundary - ); - selectTool.name = "transform"; - - top.addChild(selectTool); - - // load the source image: - var image = new Image(); - image.src = "demo/daisy.png"; - image.onload = handleImageLoad; -} - -function stop() { - createjs.Ticker.removeEventListener("tick", tick); -} - -function updateBoundary(boundary) { - var top = canvas.height * 0.1; - var left = canvas.width * 0.1; - var padding = Math.min(top, left); - boundary.setValues( - padding, - padding, - canvas.width - padding * 2, - canvas.height - padding * 2 - ); -} - -function drawBoundary() { - boundaryLine.graphics - .clear() - .beginStroke("rgba(100, 100, 100, 0.5)") - .setStrokeDash([20, 4]) - .drawRect(boundary.x, boundary.y, boundary.width, boundary.height); -} - -function constrainStageObjects(objects) { - objects.forEach(function(obj) { - createjs.util.constrainObjectTo(obj, boundary); - }); -} - -function handleImageLoad(event) { - var image = event.target; - var bitmap; - container = new createjs.Container(); - stage.addChildAt(container, 0); - - // Shape - var ellipse = new createjs.Shape(); - ellipse.x = canvas.width / 2; - ellipse.y = canvas.height / 4; - ellipse.setBounds(0, 0, 200, 300); - ellipse.regX = (ellipse.getBounds().width / 2) | 0; - ellipse.regY = (ellipse.getBounds().height / 6) | 0; - ellipse.graphics - .setStrokeStyle(4) - .beginRadialGradientFill(["#FFF", "#35E"], [1, 0], 0, 0, 200, 30, -50, 40) - .drawEllipse(0, 0, 200, 300); - clickToSelect(ellipse); - container.addChild(ellipse); - - // Bitmap - bitmap = new createjs.Bitmap(image); - bitmap.x = canvas.width / 2; - bitmap.y = canvas.height / 6; - bitmap.rotation = -25 | 0; - bitmap.regX = (bitmap.image.width / 2) | 0; - bitmap.regY = (bitmap.image.height / 2) | 0; - bitmap.name = "flower"; - bitmap.cursor = "pointer"; - clickToSelect(bitmap); - container.addChild(bitmap); - - // Text - var text = new createjs.Text("Hello\nWorld", "70px Arial", "#052865"); - var textBounds = text.getBounds(); - text.regX = textBounds.width / 2; - text.regY = textBounds.height / 2; - text.outline = 5; - text.x = canvas.width / 2; - text.y = canvas.height / 2.3; - text.rotation = 5 | 0; - text.cursor = "pointer"; - - var hit = new createjs.Shape(); - hit.graphics - .beginFill("#000") - .drawRect(0, 0, text.getBounds().width, text.getBounds().height); - text.hitArea = hit; - clickToSelect(text); - container.addChild(text); - - createjs.Ticker.addEventListener("tick", tick); - - handleResize(); -} - -function clickToSelect(displayObject) { - displayObject.on("click", function(evt) { - evt.stopPropagation(); - selectTool.select(evt.currentTarget, stage); - update = true; - }); -} - -function tick(event) { - // this set makes it so the stage only re-renders when an event handler indicates a change has happened. - if (update) { - update = false; // only update once - stage.update(event); - } -} - -var containerElement = document.getElementById("CanvasContainer"); -window.addEventListener("resize", handleResize); -function handleResize() { - selectTool.unselect(); - var w = containerElement.clientWidth; // -2 accounts for the border - //var h = window.innerHeight-2; - - stage.canvas.width = w; - //stage.canvas.height = h; - - updateBoundary(boundary); - // TODO: constrain all elements - constrainStageObjects(container.children); - - drawBoundary(); - stage.update(); -} - -init(); diff --git a/karma.conf.js b/karma.conf.js deleted file mode 100644 index 2bbd2bd..0000000 --- a/karma.conf.js +++ /dev/null @@ -1,94 +0,0 @@ -// eslint env node - -// Karma configuration -// Generated on Wed Dec 11 2019 07:30:25 GMT+1300 (NZDT) - -module.exports = function(config) { - config.set({ - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: "", - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ["jasmine"], - - // list of files / patterns to load in the browser - files: [ - { - pattern: "tests/images/*.*", - watched: false, - included: false, - served: true, - nocache: false - }, - "module-shim.js", - "node_modules/pixelmatch/index.js", - "demo/easeljs.js", - "createjs.text-fix.js", - "node_modules/txtjs/dist/txt.js", - "createjs.util.FreeTransformTool.js", - "tests/*.js" - ], - - proxies: { - "/img/": "/base/tests/images/" - }, - - // list of files / patterns to exclude - exclude: [], - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: {}, - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ["progress"], - - // web server port - port: 9876, - - // enable / disable colors in the output (reporters and logs) - colors: true, - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - logLevel: config.LOG_INFO, - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: true, - - browsers: ["ChromeWithoutGPU", "FirefoxWithoutGPU"], - - // disable gpu to stay consistent with headless renders - customLaunchers: { - ChromeWithoutGPU: { - base: "Chrome", - flags: ["--disable-gpu"] - }, - ChromeHeadlessWithoutGPU: { - base: "ChromeHeadless", - flags: ["--disable-gpu"] - }, - FirefoxWithoutGPU: { - base: "Firefox", - prefs: { - "webgl.disabled": true - } - } - }, - - client: { - clearContext: false - }, - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: false, - - // Concurrency level - // how many browser should be started simultaneous - concurrency: Infinity - }); -}; diff --git a/package.json b/package.json index 297e60c..a307889 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "createjs-free-transform-tool", - "version": "1.0.0", + "version": "1.1.0", "description": "Provides ability to free transform CreateJS Display Objects", "keywords": [ "canvas", @@ -20,31 +20,55 @@ "license": "MIT", "author": "Jeremy Shipman", "files": [ - "createjs.util.FreeTransformTool.js" + "dist/createjs.util.FreeTransformTool.js" ], - "browser": "createjs.util.FreeTransformTool.js", + "browser": "dist/createjs.util.FreeTransformTool.js", "scripts": { - "start": "http-server .", - "lint": "eslint ./*FreeTransformTool.js", - "test": "npm run lint && npm run test:ci", - "test:ci": "karma start --browsers=ChromeHeadlessWithoutGPU,FirefoxHeadless --single-run", - "test:server": "karma start --reporters=kjhtml" + "start": "run-p server watch", + "build": "mkdir -p tmp && run-s build:compile bundle copy", + "copy": "copyfiles -f public/* dist/", + "build:compile": "tsc --project .", + "bundle": "run-s bundle:lib bundle:demo bundle:tests", + "bundle:lib": "rollup -c -f umd dist/esnext/src/freetransform/index.js --name=createjs.util.FreeTransformTool --file=dist/createjs.util.FreeTransformTool.js --sourcemap", + "bundle:lib:cov": "rollup -c -f umd dist/instrumented/index.js --name=createjs.util.FreeTransformTool --file=dist/createjs.util.FreeTransformTool.instrumented.js --sourcemap", + "bundle:demo": "rollup -c -f umd dist/esnext/src/demo/index.js --globals freetransform:createjs.util.FreeTransformTool --file=dist/demo.umd.js --sourcemap", + "bundle:tests": "rollup -c -f umd dist/esnext/tests/index.js --globals freetransform:createjs.util.FreeTransformTool --file=dist/tests.umd.js --sourcemap", + "cov:instrument": "mkdir -p tmp && nyc instrument dist/esnext/src/freetransform dist/instrumented", + "cov:view": "nyc report && live-server coverage/lcov-report", + "test": "run-s lint cov:instrument bundle:lib:cov test:ci", + "test:ci": "HEADLESS=true testem ci .", + "test:server": "testem server .", + "watch": "run-p \"build:compile -- --watch\" \"bundle:lib -- --watch\" \"bundle:demo -- --watch\"", + "lint": "eslint . --ext .ts && prettier --check **/*.ts", + "lint:fix": "eslint . --ext .ts --fix && prettier --write **/*.ts", + "docs:build": "typedoc --tsconfig src", + "docs:view": "live-server docs", + "clean": "rm -Rf dist docs coverage tmp", + "server": "live-server dist" }, "devDependencies": { - "@types/createjs": "0.0.29", - "@types/pixelmatch": "^5.0.0", - "eslint": "^6.7.2", - "eslint-config-prettier": "^6.7.0", - "eslint-plugin-jasmine": "^4.1.0", - "eslint-plugin-prettier": "^3.1.1", - "http-server": "^0.11.1", + "@recreatejs/jasmine-pixelmatch": "^0.1.0", + "@rollup/plugin-commonjs": "^14.0.0", + "@rollup/plugin-node-resolve": "^8.4.0", + "@types/easeljs": "^1.0.0", + "@types/jasmine": "^3.5.11", + "@typescript-eslint/eslint-plugin": "^3.5.0", + "@typescript-eslint/parser": "^3.5.0", + "copyfiles": "^2.3.0", + "eslint": "^7.3.1", + "eslint-plugin-prettier": "^3.1.4", "jasmine-core": "^3.5.0", - "karma": "^4.4.1", - "karma-chrome-launcher": "^3.1.0", - "karma-firefox-launcher": "^1.2.0", - "karma-jasmine": "^2.0.1", - "karma-jasmine-html-reporter": "^1.4.2", + "live-server": "^1.2.1", + "npm-run-all": "^4.1.5", + "nyc": "^15.1.0", + "onchange": "^7.0.2", "pixelmatch": "^5.1.0", - "prettier": "^1.19.1" + "prettier": "^2.0.5", + "rollup": "^2.18.1", + "rollup-plugin-sourcemaps": "^0.6.2", + "testem": "^3.2.0", + "tslib": "^2.0.0", + "typedoc": "^0.17.8", + "typescript": "^3.9.5" } } diff --git a/demo/daisy.png b/public/daisy.png similarity index 100% rename from demo/daisy.png rename to public/daisy.png diff --git a/demo/easeljs.js b/public/easeljs.js similarity index 100% rename from demo/easeljs.js rename to public/easeljs.js diff --git a/demo/flower.svg b/public/flower.svg similarity index 100% rename from demo/flower.svg rename to public/flower.svg diff --git a/index.html b/public/index.html similarity index 87% rename from index.html rename to public/index.html index 070c3eb..67b4afd 100644 --- a/index.html +++ b/public/index.html @@ -3,7 +3,7 @@ Create.js Free Transform Tool - +