diff --git a/core/modules/widgets/edit/editors/bitmapeditor.js b/core/modules/widgets/edit/editors/bitmapeditor.js index 3d0ff2069..095e0ec54 100644 --- a/core/modules/widgets/edit/editors/bitmapeditor.js +++ b/core/modules/widgets/edit/editors/bitmapeditor.js @@ -12,8 +12,14 @@ A bitmap editor /*global $tw: false */ "use strict"; +// Default images sizes var DEFAULT_IMAGE_WIDTH = 300, - DEFAULT_IMAGE_HEIGHT = 182; + DEFAULT_IMAGE_HEIGHT = 185; + +// The elements of the editor UI +var DOM_CANVAS = 0, + DOM_WIDTH = 1, + DOM_HEIGHT = 2; var BitmapEditor = function(editWidget,tiddlerTitle,fieldName) { this.editWidget = editWidget; @@ -58,13 +64,39 @@ BitmapEditor.prototype.render = function() { handlerObject: this, handlerMethod: "handleMouseUpEvent" }] + },{ + type: "element", + tag: "input", + attributes: { + "class": {type: "string", value: "tw-edit-bitmapeditor-width"}, + "type": {type: "string", value: "number"}, + "value": {type: "string", value: ""} + }, + events: [{ + name: "change", + handlerObject: this, + handlerMethod: "handleWidthChangeEvent" + }] + },{ + type: "element", + tag: "input", + attributes: { + "class": {type: "string", value: "tw-edit-bitmapeditor-height"}, + "type": {type: "string", value: "number"}, + "value": {type: "string", value: ""} + }, + events: [{ + name: "change", + handlerObject: this, + handlerMethod: "handleHeightChangeEvent" + }] }]; this.editWidget.children = this.editWidget.renderer.renderTree.createRenderers(this.editWidget.renderer,children); }; BitmapEditor.prototype.postRenderInDom = function() { var tiddler = this.editWidget.renderer.renderTree.wiki.getTiddler(this.tiddlerTitle), - canvas = this.editWidget.renderer.domNode.firstChild, + canvas = this.getDomNode(DOM_CANVAS), currImage = new Image(); // Set up event handlers for loading the image var self = this; @@ -74,6 +106,8 @@ BitmapEditor.prototype.postRenderInDom = function() { // And also copy the current bitmap to the off-screen canvas self.currCanvas = self.editWidget.renderer.renderTree.document.createElement("canvas"); self.initCanvas(self.currCanvas,currImage.width,currImage.height,currImage); + // Set the width and height input boxes + self.updateSize(); }; currImage.onerror = function() { // Set the on-screen canvas size and clear it @@ -81,6 +115,8 @@ BitmapEditor.prototype.postRenderInDom = function() { // Set the off-screen canvas size and clear it self.currCanvas = self.editWidget.renderer.renderTree.document.createElement("canvas"); self.initCanvas(self.currCanvas,DEFAULT_IMAGE_WIDTH,DEFAULT_IMAGE_HEIGHT); + // Set the width and height input boxes + self.updateSize(); } // Get the current bitmap into an image object currImage.src = "data:" + tiddler.fields.type + ";base64," + tiddler.fields.text; @@ -98,6 +134,61 @@ BitmapEditor.prototype.initCanvas = function(canvas,width,height,image) { } } +BitmapEditor.prototype.getDomNode = function(index) { + return this.editWidget.renderer.domNode.childNodes[index]; +}; + +/* +** Update the input boxes with the actual size of the canvas +*/ +BitmapEditor.prototype.updateSize = function() { + this.getDomNode(DOM_WIDTH).value = this.currCanvas.width; + this.getDomNode(DOM_HEIGHT).value = this.currCanvas.height; +}; + +/* +** Change the size of the canvas, preserving the current image +*/ +BitmapEditor.prototype.changeCanvasSize = function(newWidth,newHeight) { + // Create and size a new canvas + var newCanvas = this.editWidget.renderer.renderTree.document.createElement("canvas"); + this.initCanvas(newCanvas,newWidth,newHeight); + // Copy the old image + var ctx = newCanvas.getContext("2d"); + ctx.drawImage(this.currCanvas,0,0); + // Set the new canvas as the current one + this.currCanvas = newCanvas; + // Set the size of the onscreen canvas + var canvas = this.getDomNode(DOM_CANVAS); + canvas.width = newWidth; + canvas.height = newHeight; + // Paint the onscreen canvas with the offscreen canvas + ctx = canvas.getContext("2d"); + ctx.drawImage(this.currCanvas,0,0); +}; + +BitmapEditor.prototype.handleWidthChangeEvent = function(event) { + // Get the new width + var newWidth = parseInt(this.getDomNode(DOM_WIDTH).value,10); + // Update if necessary + if(newWidth > 0 && newWidth !== this.currCanvas.width) { + this.changeCanvasSize(newWidth,this.currCanvas.height); + } + // Update the input controls + this.updateSize(); +}; + +BitmapEditor.prototype.handleHeightChangeEvent = function(event) { + // Get the new width + var newHeight = parseInt(this.getDomNode(DOM_HEIGHT).value,10); + // Update if necessary + if(newHeight > 0 && newHeight !== this.currCanvas.height) { + this.changeCanvasSize(this.currCanvas.width,newHeight); + } + // Update the input controls + this.updateSize(); +}; + BitmapEditor.prototype.handleTouchStartEvent = function(event) { this.brushDown = true; this.strokeStart(event.touches[0].clientX,event.touches[0].clientY); @@ -155,7 +246,7 @@ BitmapEditor.prototype.handleMouseUpEvent = function(event) { }; BitmapEditor.prototype.adjustCoordinates = function(x,y) { - var canvas = this.editWidget.renderer.domNode.firstChild, + var canvas = this.getDomNode(DOM_CANVAS), canvasRect = canvas.getBoundingClientRect(), scale = canvas.width/canvasRect.width; return {x: (x - canvasRect.left) * scale, y: (y - canvasRect.top) * scale}; @@ -167,7 +258,7 @@ BitmapEditor.prototype.strokeStart = function(x,y) { }; BitmapEditor.prototype.strokeMove = function(x,y) { - var canvas = this.editWidget.renderer.domNode.firstChild, + var canvas = this.getDomNode(DOM_CANVAS), ctx = canvas.getContext("2d"), t; // Add the new position to the end of the stroke @@ -193,7 +284,7 @@ BitmapEditor.prototype.strokeMove = function(x,y) { BitmapEditor.prototype.strokeEnd = function() { // Copy the bitmap to the off-screen canvas - var canvas = this.editWidget.renderer.domNode.firstChild, + var canvas = this.getDomNode(DOM_CANVAS), ctx = this.currCanvas.getContext("2d"); ctx.drawImage(canvas,0,0); // Save the image into the tiddler @@ -204,7 +295,7 @@ BitmapEditor.prototype.saveChanges = function() { var tiddler = this.editWidget.renderer.renderTree.wiki.getTiddler(this.tiddlerTitle); if(tiddler) { // data URIs look like "data:;base64," - var dataURL = this.editWidget.renderer.domNode.firstChild.toDataURL(tiddler.fields.type,1.0), + var dataURL = this.getDomNode(DOM_CANVAS).toDataURL(tiddler.fields.type,1.0), posColon = dataURL.indexOf(":"), posSemiColon = dataURL.indexOf(";"), posComma = dataURL.indexOf(","), diff --git a/themes/tiddlywiki/snowwhite/base.tid b/themes/tiddlywiki/snowwhite/base.tid index 5843aa729..0975ce0c9 100644 --- a/themes/tiddlywiki/snowwhite/base.tid +++ b/themes/tiddlywiki/snowwhite/base.tid @@ -453,6 +453,14 @@ canvas.tw-edit-bitmapeditor { -ms-user-select: none; } +.tw-edit-bitmapeditor-width { + display: block; +} + +.tw-edit-bitmapeditor-height { + display: block; +} + /* ** Tiddler edit mode */