define(["easel","sugar-web/datastore","sugar-web/env","webL10n","humane"], function (easel, datastore, env, l10n, humane) {
|
|
|
|
|
|
env.getEnvironment(function(err, environment) {
|
|
var defaultLanguage = (typeof chrome != 'undefined' && chrome.app && chrome.app.runtime) ? chrome.i18n.getUILanguage() : navigator.language;
|
|
var language = environment.user ? environment.user.language : defaultLanguage;
|
|
l10n.language.code = language;
|
|
console.log('LANG ' + language);
|
|
});
|
|
|
|
function _(text) {
|
|
// copied from activity.js
|
|
translation = l10n.get(text);
|
|
if (translation == '') {
|
|
translation = text;
|
|
};
|
|
return translation;
|
|
};
|
|
|
|
var onAndroid = /Android/i.test(navigator.userAgent);
|
|
|
|
var smallScreen = (window.innerWidth < 700) || (window.innerHeight < 600);
|
|
var font = smallScreen ? "16px Arial" : "24px Arial";
|
|
|
|
var LINE_WIDTH = 3;
|
|
var BLACK = "#000000";
|
|
var WHITE = "#ffffff";
|
|
|
|
// Spanish names for historic reasons
|
|
var DIR_DOWN = "abajo";
|
|
var DIR_UP = "arriba";
|
|
var DIR_LEFT = "izq";
|
|
var DIR_RIGHT = "der";
|
|
|
|
var MODE_NORMAL = 'normal';
|
|
var MODE_WHISPER = 'despacio';
|
|
|
|
var SIZE_RESIZE_AREA = 40; // TODO style.GRID_CELL_SIZE / 2
|
|
|
|
var TYPE_GLOBE = 'GLOBE';
|
|
var TYPE_CLOUD = 'CLOUD';
|
|
var TYPE_EXCLAMATION = 'EXCLAMATION';
|
|
var TYPE_RECTANGLE = 'RECTANGLE';
|
|
|
|
// TYPE_WHISPER is saved as TYPE_GLOBE and mode MODE_WHISPER
|
|
var TYPE_WHISPER = 'WHISPER';
|
|
|
|
var DEFAULT_FONT_SIZE = 14;
|
|
|
|
toon = {};
|
|
|
|
function createAsyncBitmap(box, url, callback) {
|
|
// Async creation of bitmap from SVG data
|
|
// Works with Chrome, Safari, Firefox (untested on IE)
|
|
var img = new Image();
|
|
img.onload = function () {
|
|
bitmap = new createjs.Bitmap(img);
|
|
bitmap.setBounds(0, 0, img.width, img.height);
|
|
bitmap.mouseEnabled = false;
|
|
callback(box, bitmap);
|
|
};
|
|
img.onerror = function (errorMsg, url, lineNumber) {
|
|
callback(box, null);
|
|
};
|
|
img.src = url;
|
|
};
|
|
|
|
function createAsyncBitmapButton(globe, url, callback) {
|
|
// creates a square black button with a image inside
|
|
// is used for the corner controls in the globe
|
|
var img = new Image();
|
|
img.cont = null;
|
|
img.globe = globe;
|
|
|
|
img.onload = function () {
|
|
var bitmap = new createjs.Bitmap(img);
|
|
bitmap.setBounds(0, 0, img.width, img.height);
|
|
bounds = bitmap.getBounds();
|
|
var scale = SIZE_RESIZE_AREA / bounds.height;
|
|
bitmap.scaleX = scale;
|
|
bitmap.scaleY = scale;
|
|
|
|
if (this.cont == null) {
|
|
this.cont = new createjs.Container();
|
|
this.cont.name = 'button';
|
|
var hitArea = new createjs.Shape();
|
|
hitArea.graphics.beginFill("#000").drawRect(0, 0,
|
|
SIZE_RESIZE_AREA, SIZE_RESIZE_AREA);
|
|
this.cont.width = SIZE_RESIZE_AREA;
|
|
this.cont.height = SIZE_RESIZE_AREA;
|
|
this.cont.hitArea = hitArea;
|
|
this.cont.addChild(hitArea);
|
|
this.cont.addChild(bitmap);
|
|
callback(this.globe, this.cont);
|
|
};
|
|
};
|
|
img.src = url;
|
|
return img;
|
|
};
|
|
|
|
function Model(data, canvas, textpalette) {
|
|
|
|
this._data = data;
|
|
// this._data have the following fields:
|
|
// 'version':'1' (don't change, for compatibility with python version)
|
|
// 'boxs': [] array with the boxes information
|
|
// every item have the background properties and a array of globes
|
|
//
|
|
// The next properites are temporary and are not saved:
|
|
// 'images': are loaded async, then have no garatie of be present.
|
|
// we use the fact that the first box do not have a background
|
|
// image, and expect that when the user change to the next box
|
|
// the images will be charged.
|
|
// 'previews': loaded from the canvas, will be displayed on the sorting
|
|
// mode.
|
|
|
|
this._canvas = canvas;
|
|
this._textpalette = textpalette;
|
|
this.comicBox = null;
|
|
this._imageCounter = 0;
|
|
this._pageCounterDisplay = null;
|
|
this._prevButton = null;
|
|
this._nextButton = null;
|
|
this._boxSorter = null;
|
|
this._sortButton = null;
|
|
this._data['previews'] = [];
|
|
|
|
// wait dialog
|
|
this._waitMsg = document.getElementById("wait");
|
|
|
|
this.comicBox = new ComicBox(this._canvas, this);
|
|
|
|
this.init = function() {
|
|
this.activeBox = 0;
|
|
var comic_box_data = this._data['boxs'][this.activeBox];
|
|
this._imageCounter = this._data['boxs'].length;
|
|
|
|
if (this._data['boxs'].length == 1) {
|
|
if (comic_box_data['globes'].length == 0) {
|
|
console.log('EMPTY TOON');
|
|
// add a globe for the title
|
|
var titleGlobe = {
|
|
"direction": null, "text_font_description": "Sans 30",
|
|
"globe_type": "RECTANGLE", "height": 50, "width": 200,
|
|
"text_color": [0, 0, 0], "radio": 15, "text_width": 76,
|
|
"y": this._canvas.height / 2,
|
|
"x": this._canvas.width / 2,
|
|
"text_height": 8, "title_globe": true,
|
|
"text_text": _('Title')};
|
|
comic_box_data['globes'].push(titleGlobe);
|
|
};
|
|
};
|
|
|
|
this.comicBox.init(comic_box_data, this._data['images']);
|
|
this.comicBox.attachTextEditionPalette(this._textpalette);
|
|
this._updatePageCounter();
|
|
};
|
|
|
|
this.setData = function(data) {
|
|
this._data = data;
|
|
this._data['previews'] = [];
|
|
this.init();
|
|
};
|
|
|
|
this.showWait = function () {
|
|
this._waitMsg.style.display = 'block';
|
|
};
|
|
|
|
this.hideWait = function () {
|
|
this._waitMsg.style.display = 'none';
|
|
};
|
|
|
|
this.getTitle = function() {
|
|
var firstBoxData = this._data['boxs'][0];
|
|
for (var i = 0; i < firstBoxData['globes'].length; i ++) {
|
|
var globeData = firstBoxData['globes'][i];
|
|
if (globeData['title_globe']) {
|
|
return globeData['text_text'];
|
|
}
|
|
};
|
|
return '';
|
|
};
|
|
|
|
this.initSort = function(sortCanvas) {
|
|
this._canvas.style.display = 'none';
|
|
|
|
this._boxSorter = new BoxSorter(sortCanvas, this._data);
|
|
this._boxSorter.init();
|
|
if (this._pageCounterDisplay != null) {
|
|
// hide the page counter
|
|
this._pageCounterDisplay.parentNode.style.display = "none";
|
|
};
|
|
};
|
|
|
|
this.finishSort = function() {
|
|
var sortedBoxes = [];
|
|
// get a rray with the new order for the boxes, like [0, 3, 2, 1]
|
|
var newOrders = this._boxSorter.getSortOrder();
|
|
this.changeToEditMode();
|
|
for (var i = 0; i < newOrders.length; i++) {
|
|
sortedBoxes.push(this._data['boxs'][newOrders[i]]);
|
|
};
|
|
this._data['boxs'] = sortedBoxes;
|
|
};
|
|
|
|
this.changeToEditMode = function() {
|
|
this._boxSorter.hide();
|
|
this._canvas.style.display = 'block';
|
|
if (this._pageCounterDisplay != null) {
|
|
// hide the page counter
|
|
this._pageCounterDisplay.parentNode.style.display = "block";
|
|
};
|
|
|
|
};
|
|
|
|
this.changeBox = function(newOrder) {
|
|
if (newOrder >= 0 && newOrder < this._data['boxs'].length) {
|
|
this.updateData();
|
|
|
|
// load the new data
|
|
this.activeBox = newOrder;
|
|
this.comicBox.init(this._data['boxs'][this.activeBox],
|
|
this._data['images'], (this.activeBox > 0));
|
|
|
|
this._updatePageCounter();
|
|
};
|
|
};
|
|
|
|
this.removeBox = function() {
|
|
// remove the actual box */
|
|
this._data['boxs'].splice(this.activeBox, 1);
|
|
this._data['previews'] = [];
|
|
if (this.activeBox > this._data['boxs'].length - 1) {
|
|
this.activeBox --;
|
|
}
|
|
this.comicBox.init(this._data['boxs'][this.activeBox],
|
|
this._data['images'], (this.activeBox > 0));
|
|
|
|
this._updatePageCounter();
|
|
};
|
|
|
|
this.updateData = function() {
|
|
this._data['boxs'][this.activeBox] = this.comicBox.getJson();
|
|
};
|
|
|
|
this.initPreviews = function() {
|
|
// store the initial preview images
|
|
for (var i = 0; i < this._data['boxs'].length; i++) {
|
|
this.storePreview(i);
|
|
};
|
|
};
|
|
|
|
this.storePreview = function(boxOrder) {
|
|
var previewCanvas = document.createElement('canvas');
|
|
previewCanvas.width = this._canvas.width;
|
|
previewCanvas.height = this._canvas.height;
|
|
var previewComicBox = new ComicBox(previewCanvas);
|
|
var that = this;
|
|
previewComicBox.init(this._data['boxs'][boxOrder],
|
|
this._data['images'], false, {canvas: previewCanvas, order: boxOrder}, function(context) {
|
|
that._data['previews'][context.order] =
|
|
context.canvas.toDataURL("image/png");
|
|
});
|
|
};
|
|
|
|
this._updatePageCounter = function() {
|
|
if (this._pageCounterDisplay != null) {
|
|
this._pageCounterDisplay.innerHTML = (this.activeBox + 1) +
|
|
' ' + _('of') + ' ' + this._data['boxs'].length;
|
|
};
|
|
if (this._prevButton != null) {
|
|
this._prevButton.disabled = (this.activeBox == 0);
|
|
};
|
|
if (this._nextButton != null) {
|
|
this._nextButton.disabled = (this.activeBox ==
|
|
(this._data['boxs'].length - 1));
|
|
};
|
|
if (this._sortButton != null) {
|
|
this._sortButton.disabled = this._data['boxs'].length < 3;
|
|
}
|
|
};
|
|
|
|
this.addGlobe = function(globeType) {
|
|
this.comicBox.addGlobe(globeType);
|
|
};
|
|
|
|
this.showPreviousBox = function() {
|
|
var prevBox = this.activeBox - 1;
|
|
this.changeBox(prevBox);
|
|
};
|
|
|
|
this.showNextBox = function() {
|
|
var nextBox = this.activeBox + 1;
|
|
this.changeBox(nextBox);
|
|
};
|
|
|
|
this.addImage = function(url) {
|
|
if (this._data['images'] == undefined) {
|
|
this._data['images'] = {};
|
|
};
|
|
|
|
this._imageCounter = this._imageCounter + 1;
|
|
var imageName = 'bAcKgRoUnD_' + this._imageCounter;
|
|
// verify if the name already exists
|
|
while (this._data['images'][imageName] != undefined) {
|
|
this._imageCounter = this._imageCounter + 1;
|
|
imageName = 'bAcKgRoUnD_' + this._imageCounter;
|
|
};
|
|
|
|
var emptyData = {'image_name': imageName, 'globes':[]};
|
|
this._data['boxs'].push(emptyData);
|
|
this._data['images'][imageName] = url;
|
|
this.changeBox(this._data['boxs'].length - 1);
|
|
};
|
|
|
|
this.getData = function() {
|
|
this.updateData();
|
|
return this._data;
|
|
};
|
|
|
|
this.attachPageCounterViewer = function(div) {
|
|
this._pageCounterDisplay = div.children[0];
|
|
this._updatePageCounter();
|
|
};
|
|
|
|
this.attachPrevNextButtons = function(prevButton, nextButton) {
|
|
this._prevButton = prevButton;
|
|
this._nextButton = nextButton;
|
|
this._updatePageCounter();
|
|
};
|
|
|
|
this.attachSortButton = function(sortButton) {
|
|
this._sortButton = sortButton;
|
|
this._updatePageCounter();
|
|
};
|
|
|
|
this.saveAsImage = function(columns) {
|
|
/* columns can be '0', '1', or '2'
|
|
if '0' means show the images in a single row */
|
|
this.showWait();
|
|
var cantBoxes = this._data['boxs'].length;
|
|
var MARGIN = 20;
|
|
if (columns == '0') {
|
|
var width = (this._canvas.width + MARGIN) * cantBoxes + MARGIN;
|
|
var height = this._canvas.height + MARGIN * 2;
|
|
} else if (columns == '1') {
|
|
var width = this._canvas.width + MARGIN * 2;
|
|
var height = (this._canvas.height + MARGIN) * cantBoxes + MARGIN;
|
|
} else if (columns == '2') {
|
|
var width = this._canvas.width * 2 + MARGIN * 3;
|
|
var height = (this._canvas.height + MARGIN) *
|
|
Math.ceil(cantBoxes / 2) + MARGIN;
|
|
};
|
|
// create the canvas where will draw all
|
|
var imageCanvas = document.createElement('canvas');
|
|
imageCanvas.width = width;
|
|
imageCanvas.height = height;
|
|
var ctx = imageCanvas.getContext("2d");
|
|
|
|
// add a white background
|
|
ctx.fillStyle="#FFFFFF";
|
|
ctx.fillRect(0, 0, width, height);
|
|
|
|
var currentbox = 0;
|
|
for (var i = 0; i < cantBoxes; i++) {
|
|
// load the bix image in a temp canvas
|
|
var that = this;
|
|
var tmpCanvas = document.createElement('canvas');
|
|
tmpCanvas.width = this._canvas.width;
|
|
tmpCanvas.height = this._canvas.height;
|
|
var tmpComicBox = new ComicBox(tmpCanvas);
|
|
tmpComicBox.init(this._data['boxs'][i],
|
|
this._data['images'], false, tmpCanvas, function(mycanvas) {
|
|
|
|
// add to the image canvas
|
|
var img = new Image();
|
|
img.src = mycanvas.toDataURL("image/png");
|
|
img.addEventListener("load", function() {
|
|
// calculate coordinates
|
|
if (columns == '0') {
|
|
var x = MARGIN + (that._canvas.width + MARGIN) * currentbox;
|
|
var y = MARGIN;
|
|
} else if (columns == '1') {
|
|
var x = MARGIN;
|
|
var y = MARGIN + (that._canvas.height + MARGIN) * currentbox;
|
|
} else if (columns == '2') {
|
|
var x = MARGIN + (currentbox % 2) * (that._canvas.width + MARGIN);
|
|
var y = MARGIN + Math.floor(currentbox / 2) * (that._canvas.height + MARGIN);
|
|
};
|
|
|
|
// draw image
|
|
ctx.drawImage(this, x, y);
|
|
|
|
if (currentbox++ >= cantBoxes-1) {
|
|
// save in datastore
|
|
var imgAsDataURL = imageCanvas.toDataURL("image/png");
|
|
var metadata = {
|
|
mimetype: "image/png",
|
|
title: "Image FotoToon",
|
|
activity: "org.olpcfrance.MediaViewerActivity",
|
|
timestamp: new Date().getTime(),
|
|
creation_time: new Date().getTime(),
|
|
file_size: 0
|
|
};
|
|
datastore.create(metadata, function(err) {
|
|
if (err) {
|
|
console.log("error saving image in journal");
|
|
humane.log(_("SavingError"));
|
|
} else {
|
|
console.log("image saved in journal.");
|
|
humane.log(_("ImageSaved"));
|
|
}
|
|
that.hideWait();
|
|
}, imgAsDataURL);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
};
|
|
|
|
};
|
|
|
|
function ComicBox(canvas, model) {
|
|
/* model is only used to call the removeBox method,
|
|
the data is set in the init() method */
|
|
|
|
this.canvas = canvas;
|
|
this._model = model;
|
|
this._width = canvas.width - LINE_WIDTH * 2;
|
|
this._height = canvas.height - LINE_WIDTH * 2;
|
|
|
|
this.stage = new createjs.Stage(canvas);
|
|
// Enable touch interactions if supported on the current device
|
|
createjs.Touch.enable(this.stage);
|
|
|
|
this.globes = [];
|
|
this._globeSelected = null;
|
|
|
|
// reference to the text palette used to edit the text in the globes
|
|
this._textpalette = null;
|
|
|
|
this.init = function (data, imagesData, canRemove, context, callback) {
|
|
this._data = data;
|
|
this.imagesData = imagesData
|
|
this.canRemove = canRemove;
|
|
this.globes = [];
|
|
this.stage.removeAllChildren();
|
|
this._backContainer = new createjs.Container();
|
|
var background = new createjs.Shape();
|
|
background.graphics.setStrokeStyle(LINE_WIDTH, "round");
|
|
background.graphics.beginStroke(
|
|
BLACK).drawRect(LINE_WIDTH, LINE_WIDTH,
|
|
this._width, this._height);
|
|
this.stage.addChild(this._backContainer);
|
|
this._backContainer.addChild(background);
|
|
this._backContainer.cache(0, 0, this.canvas.width, this.canvas.height);
|
|
|
|
if (this._data != null) {
|
|
if (this._data['image_name'] != '' &&
|
|
this._data['image_name'] != undefined) {
|
|
this._image_x = this._data['img_x'];
|
|
this._image_y = this._data['img_y'];
|
|
this._image_width = this._data['img_w'];
|
|
this._image_height = this._data['img_h'];
|
|
this._image_name = this._data['image_name'];
|
|
this._slideshow_duration = this._data['slideshow_duration'];
|
|
|
|
if (this.imagesData != null) {
|
|
this._setBackgroundImageDataUrl(
|
|
this.imagesData[this._image_name], context, callback);
|
|
};
|
|
} else {
|
|
this._image_x = 0;
|
|
this._image_y = 0;
|
|
this._image_width = canvas.width;
|
|
this._image_height = canvas.height;
|
|
this._image_name = '';
|
|
this._slideshow_duration = 10;
|
|
this.createGlobes();
|
|
if (callback) callback(context);
|
|
};
|
|
};
|
|
this.stage.update();
|
|
};
|
|
|
|
this._setBackgroundImageDataUrl = function(imageUrl, context, callback) {
|
|
this._image_x = 0;
|
|
this._image_y = 0;
|
|
this._image_width = this._width;
|
|
this._image_height = this._height;
|
|
var img = new Image();
|
|
var that = this;
|
|
img.addEventListener("load", function() {
|
|
bitmap = new createjs.Bitmap(img);
|
|
bitmap.setBounds(0, 0, img.width, img.height);
|
|
// calculate scale
|
|
var scale_x = that._width / img.width;
|
|
var scale_y = that._height / img.height;
|
|
var scale = Math.min(scale_x, scale_y);
|
|
|
|
bitmap.mouseEnabled = false;
|
|
bitmap.x = LINE_WIDTH;
|
|
bitmap.y = LINE_WIDTH;
|
|
bitmap.scaleX = scale;
|
|
bitmap.scaleY = scale;
|
|
that._backContainer.addChildAt(bitmap, 0);
|
|
|
|
// add a trash button
|
|
if (that.canRemove) {
|
|
createAsyncBitmapButton(that, './icons/remove.svg',
|
|
function(comicBox, button) {
|
|
button.x = 0;
|
|
button.y = comicBox._height - button.height;
|
|
button.visible = true;
|
|
comicBox._removeButton = button;
|
|
comicBox._backContainer.addChildAt(button, 1);
|
|
comicBox._backContainer.updateCache();
|
|
|
|
button.on('click', function(event) {
|
|
comicBox.remove();
|
|
});
|
|
|
|
comicBox.createGlobes();
|
|
});
|
|
} else {
|
|
that._backContainer.updateCache();
|
|
that.createGlobes();
|
|
};
|
|
if (callback) {
|
|
callback(context);
|
|
}
|
|
});
|
|
img.src = imageUrl;
|
|
};
|
|
|
|
this.remove = function() {
|
|
console.log('remove');
|
|
this._model.removeBox();
|
|
};
|
|
|
|
this.attachTextEditionPalette = function(textpalette) {
|
|
this._textpalette = textpalette;
|
|
var box = this;
|
|
// NOTE: this not work on IE see here for more info:
|
|
// http://stackoverflow.com/questions/2823733/textarea-onchange-detection
|
|
this._textpalette.editorElem.addEventListener('input', function() {
|
|
if (box.getSelectedGlobe() != null) {
|
|
box.getSelectedGlobe().getTextViewer().setText(this.value);
|
|
};
|
|
}, false);;
|
|
|
|
var editor = this._textpalette.editorElem;
|
|
|
|
var colorButtons = this._textpalette.colorButtons;
|
|
for (var i = 0; i < colorButtons.length; i++) {
|
|
colorButtons[i].addEventListener('click', function(e) {
|
|
editor.style.color =
|
|
box.getSelectedGlobe().getTextViewer().setColor(this.value);
|
|
});
|
|
};
|
|
|
|
this._textpalette.incTextBtn.addEventListener('click', function(e) {
|
|
editor.style.fontSize =
|
|
box.getSelectedGlobe().getTextViewer().incSize() + "px";
|
|
});
|
|
|
|
this._textpalette.decTextBtn.addEventListener('click', function(e) {
|
|
editor.style.fontSize =
|
|
box.getSelectedGlobe().getTextViewer().decSize() + "px";
|
|
});
|
|
|
|
this._textpalette.boldTextBtn.addEventListener('click', function(e) {
|
|
var bold = box.getSelectedGlobe().getTextViewer().toggleBold();
|
|
if (bold) {
|
|
editor.style.fontWeight = 'bold';
|
|
} else {
|
|
editor.style.fontWeight = 'normal';
|
|
};
|
|
});
|
|
|
|
this._textpalette.italicTextBtn.addEventListener('click', function(e) {
|
|
var italic = box.getSelectedGlobe().getTextViewer().toggleItalic();
|
|
if (italic) {
|
|
editor.style.fontStyle = 'italic';
|
|
} else {
|
|
editor.style.fontStyle = 'normal';
|
|
};
|
|
});
|
|
|
|
};
|
|
|
|
this.popupTextEditionPalette = function() {
|
|
if (this._textpalette != null) {
|
|
this._textpalette.popUp();
|
|
this._textpalette.editorElem.focus();
|
|
};
|
|
};
|
|
|
|
this.getSelectedGlobe = function() {
|
|
return this._globeSelected;
|
|
};
|
|
|
|
this.isGlobeSelected = function(globe) {
|
|
return this._globeSelected == globe;
|
|
};
|
|
|
|
this.selectGlobe = function(globe) {
|
|
this._globeSelected = globe;
|
|
var textpalette = this._textpalette;
|
|
this.globes.forEach(
|
|
function (element, index, array) {
|
|
if (element != globe) {
|
|
element.setSelected(false);
|
|
} else {
|
|
if (textpalette != null) {
|
|
textpalette.setText(
|
|
element.getTextViewer().getText());
|
|
element.getTextViewer().applyTextProperties(
|
|
textpalette.editorElem);
|
|
};
|
|
};
|
|
});
|
|
};
|
|
|
|
this.addGlobe = function (globeType) {
|
|
var width = 100;
|
|
var height = 50;
|
|
globeData = {'globe_type': globeType, 'x': 100, 'y': 100,
|
|
'width': width, 'height': height,
|
|
'point_0': width / 2, 'point_1': height / 2,
|
|
'radio': 100, 'direction': DIR_DOWN,
|
|
'mode': MODE_NORMAL};
|
|
|
|
if (globeType == TYPE_WHISPER) {
|
|
globeData['globe_type'] = TYPE_GLOBE;
|
|
globeData['mode'] = MODE_WHISPER;
|
|
};
|
|
|
|
var globe = new Globe(this, globeData);
|
|
this.globes.push(globe);
|
|
this.stage.update();
|
|
};
|
|
|
|
this.getJson = function() {
|
|
jsonData = {};
|
|
jsonData['img_x'] = this._image_x;
|
|
jsonData['img_y'] = this._image_y;
|
|
jsonData['img_w'] = this._image_width;
|
|
jsonData['img_h'] = this._image_height;
|
|
jsonData['image_name'] = this._image_name;
|
|
jsonData['slideshow_duration'] = this._slideshow_duration;
|
|
|
|
jsonData['globes'] = [];
|
|
for (var n = 0; n < this.globes.length; n++) {
|
|
globe = this.globes[n];
|
|
globeData = {};
|
|
|
|
globeData['globe_type'] = globe._type;
|
|
globeData['x'] = globe._x;
|
|
globeData['y'] = globe._y;
|
|
globeData['width'] = globe._width;
|
|
globeData['height'] = globe._height;
|
|
|
|
if (globe._type != TYPE_RECTANGLE) {
|
|
globeData['point_0'] = globe._point[0];
|
|
globeData['point_1'] = globe._point[1];
|
|
};
|
|
if (globe._type == TYPE_GLOBE) {
|
|
globeData['mode'] = globe._mode;
|
|
};
|
|
globeData['radio'] = globe._radio;
|
|
globeData['direction'] = globe._direction;
|
|
globeData['title_globe'] = globe._isTitleGlobe;
|
|
// text properties
|
|
globeData['text_text'] = globe._textViewer.getText();
|
|
globeData['text_font_description'] =
|
|
globe._textViewer.getCairoFontFormat();
|
|
globeData['text_color'] =
|
|
globe._textViewer.HtmlToGdkColor(
|
|
globe._textViewer._color);
|
|
globeData['text_width'] = globe._textViewer._width;
|
|
globeData['text_height'] = globe._textViewer._height;
|
|
jsonData['globes'].push(globeData);
|
|
};
|
|
|
|
return jsonData;
|
|
};
|
|
|
|
this.createGlobes = function() {
|
|
var globes = this._data['globes'];
|
|
for (var n = 0; n < globes.length; n++) {
|
|
var globe = new Globe(this, globes[n]);
|
|
this.globes.push(globe);
|
|
};
|
|
this.stage.update();
|
|
};
|
|
|
|
};
|
|
|
|
function TextViewer(globe, globeData) {
|
|
|
|
this._globe = globe;
|
|
this._globeData = globeData;
|
|
|
|
this.init = function() {
|
|
|
|
this._text = '';
|
|
this._color = BLACK;
|
|
this._width = globe._width - 20;
|
|
this._height = SIZE_RESIZE_AREA / 2;
|
|
this._size = DEFAULT_FONT_SIZE;
|
|
this._bold = false;
|
|
this._italic = false;
|
|
if (this._globeData != null) {
|
|
/* example of the text data in the json globe data stored
|
|
{"text_font_description": "Sans 10",
|
|
"text_text": "Hmm, esto parece estar funcionando",
|
|
"text_color": [0, 0, 0],
|
|
"text_width": 78, "text_height": 22}
|
|
|
|
NOTE: color components are in the range 0-65535
|
|
https://developer.gnome.org/pygtk/stable/class-gdkcolor.html#constructor-gdkcolor
|
|
*/
|
|
if (this._globeData['text_text'] != undefined) {
|
|
this._text = this._globeData['text_text'];
|
|
};
|
|
if (this._globeData['text_font_description'] != undefined) {
|
|
this.ReadHtmlFontFormat(
|
|
this._globeData['text_font_description']);
|
|
};
|
|
if (this._globeData['text_color'] != undefined) {
|
|
this._color = this.GdkToHtmlColor(
|
|
this._globeData['text_color']);
|
|
};
|
|
if (this._globeData['text_width'] != undefined) {
|
|
this._width = this._globeData['text_width'];
|
|
};
|
|
if (this._globeData['text_height'] != undefined) {
|
|
this._height = this._globeData['text_height'];
|
|
};
|
|
this._textView = null;
|
|
};
|
|
};
|
|
|
|
this.GdkToHtmlColor = function(color) {
|
|
// int array [r, g, b] are int in the range 0-65535
|
|
// returns a str with the format "#rrggbb"
|
|
rh = (color[0] / 65535 * 255).toString(16);
|
|
gh = (color[1] / 65535 * 255).toString(16);
|
|
bh = (color[2] / 65535 * 255).toString(16);
|
|
// Number.toString() can return a single char.
|
|
if (rh.length < 2) { rh = '0' + rh};
|
|
if (gh.length < 2) { gh = '0' + gh};
|
|
if (bh.length < 2) { bh = '0' + bh};
|
|
return "#" + rh + gh + bh;
|
|
};
|
|
|
|
this.HtmlToGdkColor = function(rgb) {
|
|
// rgb is a str with the format "#rrggbb"
|
|
// return a array [r, g, b] with int in the range 0-65535
|
|
rh = rgb.substr(1, 2);
|
|
gh = rgb.substr(3, 2);
|
|
bh = rgb.substr(5, 2);
|
|
r = parseInt(rh, 16) / 255 * 65535;
|
|
g = parseInt(gh, 16) / 255 * 65535;
|
|
b = parseInt(bh, 16) / 255 * 65535;
|
|
return [r, g, b];
|
|
};
|
|
|
|
this.ReadHtmlFontFormat = function(cairoFormat) {
|
|
// get a str with format "Sans 10" or "Sans bold 10"
|
|
// return a str with format "10px Sans" or "bold 10px Sans"
|
|
var parts = cairoFormat.split(' ');
|
|
var family = parts[0];
|
|
if (parts.length == 2) {
|
|
size = parts[1];
|
|
style = '';
|
|
} else {
|
|
style = parts[1] + ' ';
|
|
size = parts[2];
|
|
};
|
|
this._size = Number(size);
|
|
this._family = family;
|
|
this._bold = style.toLowerCase().indexOf('bold') > -1;
|
|
this._italic = style.toLowerCase().indexOf('italic') > -1;
|
|
};
|
|
|
|
this.getCairoFontFormat = function() {
|
|
// return a str with format "Sans 10" or "Sans bold 10"
|
|
var cairoFormat = this._family;
|
|
if (this._bold) {
|
|
cairoFormat = cairoFormat + ' ' + 'bold';
|
|
};
|
|
if (this._italic) {
|
|
cairoFormat = cairoFormat + ' ' + 'italic';
|
|
};
|
|
return cairoFormat + ' ' + this._size;
|
|
|
|
};
|
|
|
|
this.getFontDescription = function() {
|
|
// return a str with format "10px Sans" or "bold 10px Sans"
|
|
var cairoFormat = '';
|
|
if (this._bold) {
|
|
cairoFormat = cairoFormat + ' ' + 'bold';
|
|
};
|
|
if (this._italic) {
|
|
cairoFormat = cairoFormat + ' ' + 'italic';
|
|
};
|
|
return cairoFormat + ' ' + this._size + 'px ' + this._family;
|
|
|
|
};
|
|
|
|
this.update = function() {
|
|
if (this._textView != null) {
|
|
this._globe._stage.removeChild(this._textView);
|
|
};
|
|
this._textView = new createjs.Text(this._text,
|
|
this.getFontDescription(),
|
|
this._color);
|
|
this._textView.textAlign = 'center';
|
|
this._textView.lineWidth = this._globe._width * 2;
|
|
this._textView.x = this._globe._x;
|
|
this._textView.y = this._globe._y -
|
|
this._textView.getMeasuredHeight() / 2;
|
|
this._globe._stage.addChild(this._textView);
|
|
this._globe._stage.update();
|
|
};
|
|
|
|
this.getText = function() {
|
|
return this._text;
|
|
};
|
|
|
|
this.setText = function(text) {
|
|
this._text = text;
|
|
this.update();
|
|
};
|
|
|
|
this.setColor = function(color) {
|
|
this._color = color;
|
|
this.update();
|
|
return this._color;
|
|
};
|
|
|
|
this.incSize = function() {
|
|
if (this._size < 60) {
|
|
this._size = this._size + Math.round(this._size / 4);
|
|
this.update();
|
|
};
|
|
return this._size;
|
|
};
|
|
|
|
this.decSize = function() {
|
|
if (this._size > 10) {
|
|
this._size = this._size - Math.round(this._size / 4);
|
|
this.update();
|
|
};
|
|
return this._size;
|
|
};
|
|
|
|
this.toggleBold = function() {
|
|
this._bold = ! this._bold;
|
|
this.update();
|
|
return this._bold;
|
|
};
|
|
|
|
this.toggleItalic = function() {
|
|
this._italic = ! this._italic;
|
|
this.update();
|
|
return this._italic;
|
|
};
|
|
|
|
this.applyTextProperties = function(editor) {
|
|
// apply the viewer text properties to the editor
|
|
// (used when a globe is selected)
|
|
editor.style.fontSize = this._size + 'px';
|
|
editor.style.color = this._color;
|
|
if (this._italic) {
|
|
editor.style.fontStyle = 'italic';
|
|
} else {
|
|
editor.style.fontStyle = 'normal';
|
|
};
|
|
if (this._bold) {
|
|
editor.style.fontWeight = 'bold';
|
|
} else {
|
|
editor.style.fontWeight = 'normal';
|
|
};
|
|
};
|
|
|
|
this.remove = function() {
|
|
this._globe._stage.removeChild(this._textView);
|
|
};
|
|
|
|
this.init();
|
|
return this;
|
|
};
|
|
|
|
|
|
function Globe(box, globeData) {
|
|
this._box = box;
|
|
this._stage = box.stage;
|
|
this._shapeControls = null;
|
|
this._pointerControl = null;
|
|
this._resizeButton = null;
|
|
this._editButton = null;
|
|
this._rotateButton = null;
|
|
this._removeButton = null;
|
|
|
|
this._shapeChanged = true;
|
|
this._pointerChanged = true;
|
|
|
|
this.init = function() {
|
|
if (globeData == null) {
|
|
this._type = TYPE_GLOBE;
|
|
this._x = 100;
|
|
this._y = 100;
|
|
this._width = 100;
|
|
this._height = 50;
|
|
this._point = [this._width / 2,
|
|
this._height / 2];
|
|
this._radio = 100;
|
|
this._direction = DIR_DOWN;
|
|
this._textViewer = new TextViewer(this, null);
|
|
this._mode = MODE_NORMAL;
|
|
// title_globe can't be deleted
|
|
this._isTitleGlobe = false;
|
|
} else {
|
|
/* example of the json data stored
|
|
|
|
{"direction": "abajo", "text_font_description": "Sans 10",
|
|
"globe_type": "GLOBE",
|
|
"text_text": "Hmm, esto parece estar funcionando",
|
|
"height": 36.66666666666667, "width": 130.0,
|
|
"text_color": [0, 0, 0], "radio": 30, "mode": "normal",
|
|
"text_width": 78, "y": 63.0, "x": 202.0,
|
|
"text_height": 22, "title_globe": false, "point_0": 40.5,
|
|
"point_1": 54}
|
|
*/
|
|
this._type = globeData['globe_type'];
|
|
this._x = globeData['x'];
|
|
this._y = globeData['y'];
|
|
this._width = globeData['width'];
|
|
this._height = globeData['height'];
|
|
if (this._type != TYPE_RECTANGLE) {
|
|
this._point = [globeData['point_0'],
|
|
globeData['point_1']];
|
|
} else {
|
|
this._point = [0, 0];
|
|
};
|
|
if (this._type == TYPE_GLOBE) {
|
|
this._mode = globeData['mode'];
|
|
} else {
|
|
this._mode = MODE_NORMAL;
|
|
};
|
|
this._radio = globeData['radio'];
|
|
this._direction = globeData['direction'];
|
|
this._textViewer = new TextViewer(this, globeData);
|
|
this._isTitleGlobe = globeData['title_globe'];
|
|
};
|
|
|
|
this._shape = null;
|
|
};
|
|
|
|
this.createShape = function() {
|
|
if (this._shape != null) {
|
|
this._stage.removeChild(this._shape);
|
|
if (this._type == TYPE_CLOUD) {
|
|
this._stage.removeChild(this._shapeCircles);
|
|
};
|
|
};
|
|
|
|
var scale_x = this._width /this._radio;
|
|
var scale_y = this._height /this._radio;
|
|
|
|
var scaled_x = this._x / scale_x;
|
|
var scaled_y = this._y / scale_y;
|
|
|
|
if (this._type == TYPE_CLOUD) {
|
|
this.createShapeCloud(scaled_x, scaled_y, scale_x, scale_y);
|
|
} else if (this._type == TYPE_EXCLAMATION) {
|
|
this.createShapeExclamation(scaled_x, scaled_y, scale_x, scale_y);
|
|
} else if (this._type == TYPE_RECTANGLE) {
|
|
this.createShapeRectangle();
|
|
} else {
|
|
this.createShapeGlobe(scaled_x, scaled_y, scale_x, scale_y);
|
|
};
|
|
|
|
this._shape.on('click', function(event) {
|
|
this.setSelected(true);
|
|
}, this);
|
|
|
|
this._shape.on("pressmove",function(event) {
|
|
this._x = event.stageX;
|
|
this._y = event.stageY;
|
|
this.setSelected(true);
|
|
this.update();
|
|
}, this);
|
|
|
|
};
|
|
|
|
this.getSelected = function() {
|
|
return this._box.isGlobeSelected(this);
|
|
};
|
|
|
|
this.setSelected = function(selected) {
|
|
if (selected) {
|
|
this._box.selectGlobe(this);
|
|
this._shapeControls.visible = true;
|
|
if (this._type != TYPE_RECTANGLE) {
|
|
this._pointerControl.visible = true;
|
|
this._rotateButton.visible = true;
|
|
};
|
|
this._resizeButton.visible = true;
|
|
this._editButton.visible = true;
|
|
if (!this._isTitleGlobe) {
|
|
this._removeButton.visible = true;
|
|
};
|
|
|
|
} else {
|
|
this._shapeControls.visible = false;
|
|
if (this._type != TYPE_RECTANGLE) {
|
|
this._pointerControl.visible = false;
|
|
this._rotateButton.visible = false;
|
|
};
|
|
this._resizeButton.visible = false;
|
|
this._editButton.visible = false;
|
|
if (!this._isTitleGlobe) {
|
|
this._removeButton.visible = false;
|
|
};
|
|
};
|
|
this._stage.update();
|
|
};
|
|
|
|
this.getTextViewer = function() {
|
|
return this._textViewer;
|
|
};
|
|
|
|
this.createShapeGlobe = function(x, y, scale_x, scale_y) {
|
|
switch (this._direction) {
|
|
case DIR_DOWN:
|
|
var begin = 100;
|
|
var end = 80;
|
|
break;
|
|
case DIR_RIGHT:
|
|
var begin = 10;
|
|
var end = 350;
|
|
break;
|
|
case DIR_LEFT:
|
|
var begin = 190;
|
|
var end = 170;
|
|
break;
|
|
case DIR_UP:
|
|
var begin = 280;
|
|
var end = 260;
|
|
};
|
|
|
|
this._shape = new createjs.Shape();
|
|
this._shape.name = 'globe';
|
|
this._stage.addChild(this._shape);
|
|
this._shape.graphics.setStrokeStyle(LINE_WIDTH, "round",
|
|
null, null, true);
|
|
this._shape.graphics.beginStroke(BLACK);
|
|
this._shape.graphics.beginFill(WHITE);
|
|
if (this._mode == MODE_WHISPER) {
|
|
this._shape.graphics.setStrokeDash([3]);
|
|
};
|
|
this._shape.graphics.arc(x, y, this._radio,
|
|
begin / (180.0) * Math.PI,
|
|
end / (180.0) * Math.PI)
|
|
|
|
point_pos = this.getPointPosition(true);
|
|
this._shape.graphics.lineTo(point_pos[0], point_pos[1]);
|
|
this._shape.graphics.closePath();
|
|
this._shape.graphics.endStroke();
|
|
this._shape.setTransform(0, 0, scale_x, scale_y);
|
|
};
|
|
|
|
this.createShapeRectangle = function() {
|
|
var x = this._x;
|
|
var y = this._y;
|
|
var w = this._width;
|
|
var h = this._height;
|
|
|
|
this._shape = new createjs.Shape();
|
|
this._shape.name = 'rect';
|
|
this._stage.addChild(this._shape);
|
|
this._shape.graphics.setStrokeStyle(LINE_WIDTH, "round",
|
|
null, null, true);
|
|
this._shape.graphics.beginStroke(BLACK);
|
|
this._shape.graphics.beginFill(WHITE);
|
|
|
|
this._shape.graphics.rect(x - w , y - h, w * 2, h * 2);
|
|
this._shape.graphics.endStroke();
|
|
};
|
|
|
|
this.createShapeCloud = function(x, y, scale_x, scale_y) {
|
|
this._shape = new createjs.Shape();
|
|
this._shape.name = 'cloud';
|
|
this._stage.addChild(this._shape);
|
|
this._shape.graphics.setStrokeStyle(LINE_WIDTH, "round",
|
|
null, null, true);
|
|
this._shape.graphics.beginStroke(BLACK);
|
|
this._shape.graphics.beginFill(WHITE);
|
|
|
|
var w = this._width / scale_x;
|
|
var h = this._height / scale_y;
|
|
|
|
var steps = 36;
|
|
var state = 0;
|
|
|
|
for (var i = 0; i < steps; i++) {
|
|
var alpha = 2.0 * i * (Math.PI / steps);
|
|
var sinalpha = Math.sin(alpha);
|
|
var cosalpha = Math.cos(alpha);
|
|
|
|
if (state == 0) {
|
|
var x1 = x + w * cosalpha;
|
|
var y1 = y + h * sinalpha;
|
|
} else if (state == 1) {
|
|
var x2 = x + w * cosalpha;
|
|
var y2 = y + h * sinalpha;
|
|
} else if (state == 2) {
|
|
var x3 = x + 0.8 * w * cosalpha;
|
|
var y3 = y + 0.8 * h * sinalpha;
|
|
};
|
|
if (state == 2) {
|
|
this._shape.graphics.bezierCurveTo(x1, y1, x2, y2, x3, y3);
|
|
};
|
|
|
|
state += 1;
|
|
if (state == 3) {
|
|
state = 0;
|
|
};
|
|
|
|
if (i == 0) {
|
|
this._shape.graphics.moveTo(x1, y1);
|
|
};
|
|
};
|
|
|
|
x1 = x + w * cosalpha;
|
|
y1 = y + h * sinalpha;
|
|
x2 = x + w;
|
|
y2 = y;
|
|
x3 = x + w;
|
|
y3 = y;
|
|
this._shape.graphics.bezierCurveTo(x1, y1, x2, y2, x3, y3);
|
|
|
|
this._shape.graphics.closePath();
|
|
this._shape.graphics.endStroke();
|
|
|
|
firstCirclePos = this.getCloudPointPosition();
|
|
|
|
this._shapeCircles = new createjs.Shape();
|
|
this._shapeCircles.name = 'cloud circles';
|
|
this._stage.addChild(this._shapeCircles);
|
|
this._shapeCircles.graphics.setStrokeStyle(LINE_WIDTH, "round");
|
|
this._shapeCircles.graphics.beginStroke(BLACK);
|
|
this._shapeCircles.graphics.beginFill(WHITE);
|
|
|
|
this._shapeCircles.graphics.arc(
|
|
firstCirclePos[0], firstCirclePos[1], 7,
|
|
0, 2 * Math.PI);
|
|
this._shapeCircles.graphics.endStroke();
|
|
|
|
secondCirclePos = this.getPointPosition(false);
|
|
|
|
this._shapeCircles.graphics.beginStroke(BLACK);
|
|
this._shapeCircles.graphics.beginFill(WHITE);
|
|
this._shapeCircles.graphics.arc(
|
|
secondCirclePos[0], secondCirclePos[1], 5,
|
|
0, 2 * Math.PI);
|
|
this._shapeCircles.graphics.endStroke();
|
|
|
|
this._shape.setTransform(0, 0, scale_x, scale_y);
|
|
|
|
};
|
|
|
|
this.getCloudPointPosition = function() {
|
|
var x = this._x;
|
|
var y = this._y;
|
|
var w = this._width;
|
|
var h = this._height;
|
|
|
|
switch (this._direction) {
|
|
case DIR_DOWN:
|
|
return [x + this._point[0] / 2,
|
|
y + h + this._point[1] / 2];
|
|
case DIR_RIGHT:
|
|
return [x + w + this._point[0] / 2,
|
|
y + this._point[1] / 2];
|
|
case DIR_LEFT:
|
|
return [x - w - this._point[0] / 2,
|
|
y + this._point[1] / 2];
|
|
case DIR_UP:
|
|
return [x + this._point[0] / 2,
|
|
y - h - this._point[1] / 2];
|
|
};
|
|
};
|
|
|
|
this.createShapeExclamation = function(x, y, scale_x, scale_y) {
|
|
this._shape = new createjs.Shape();
|
|
this._shape.name = 'exclamation';
|
|
this._stage.addChild(this._shape);
|
|
this._shape.graphics.setStrokeStyle(LINE_WIDTH, "round",
|
|
null, null, true);
|
|
this._shape.graphics.beginStroke(BLACK);
|
|
this._shape.graphics.beginFill(WHITE);
|
|
|
|
var w = this._width / scale_x;
|
|
var h = this._height / scale_y;
|
|
|
|
var steps = 24;
|
|
|
|
for (var i = 0; i < steps; i++) {
|
|
var alpha = 2.0 * i * (Math.PI / steps);
|
|
var sinalpha = Math.sin(alpha);
|
|
var cosalpha = Math.cos(alpha);
|
|
|
|
if (i % 2 > 0) {
|
|
xi = x + 0.8 * w * cosalpha;
|
|
yi = y + 0.8 * h * sinalpha;
|
|
} else {
|
|
xi = x + w * cosalpha;
|
|
yi = y + h * sinalpha;
|
|
};
|
|
|
|
if ((this._direction == DIR_DOWN && i == 6) ||
|
|
(this._direction == DIR_RIGHT && i == 0) ||
|
|
(this._direction == DIR_LEFT && i == 12) ||
|
|
(this._direction == DIR_UP && i == 18)) {
|
|
|
|
pos = this.getPointPosition(true);
|
|
xi = pos[0];
|
|
yi = pos[1];
|
|
};
|
|
|
|
if (i == 0) {
|
|
this._shape.graphics.moveTo(xi, yi);
|
|
} else {
|
|
this._shape.graphics.lineTo(xi, yi);
|
|
};
|
|
}
|
|
|
|
this._shape.graphics.closePath();
|
|
this._shape.graphics.endStroke();
|
|
|
|
this._shape.setTransform(0, 0, scale_x, scale_y);
|
|
|
|
};
|
|
|
|
this.createControls = function() {
|
|
var x = this._x;
|
|
var y = this._y;
|
|
var w = this._width;
|
|
var h = this._height;
|
|
|
|
if (this._shapeControls != null && this._shapeChanged) {
|
|
this._stage.removeChild(this._shapeControls);
|
|
this._shapeControls = null;
|
|
};
|
|
|
|
if (this._shapeControls == null) {
|
|
this._shapeControls = new createjs.Shape();
|
|
this._shapeControls.name = 'control_rect';
|
|
|
|
// draw dotted rectangle around the globe
|
|
this._shapeControls.graphics.setStrokeStyle(1, "round");
|
|
this._shapeControls.graphics.beginStroke(WHITE);
|
|
this._shapeControls.x = x;
|
|
this._shapeControls.y = y;
|
|
this._shapeControls.graphics.rect(- w ,- h, w * 2, h * 2);
|
|
this._shapeControls.graphics.setStrokeDash([2]);
|
|
this._shapeControls.graphics.beginFill("rgba(0, 0, 0, 0)");
|
|
this._shapeControls.graphics.beginStroke(BLACK);
|
|
this._shapeControls.graphics.rect(- w ,- h, w * 2, h * 2);
|
|
this._shapeControls.graphics.endStroke();
|
|
|
|
this._shapeControls.visible = this.getSelected();
|
|
this._stage.addChild(this._shapeControls);
|
|
} else {
|
|
this._shapeControls.visible = this.getSelected();
|
|
this._shapeControls.x = x;
|
|
this._shapeControls.y = y;
|
|
};
|
|
|
|
// point position
|
|
if (this._type != TYPE_RECTANGLE) {
|
|
|
|
if (this._pointerControl != null &&
|
|
(this._pointerChanged || this._shapeChanged)) {
|
|
this._stage.removeChild(this._pointerControl);
|
|
this._pointerControl = null;
|
|
};
|
|
|
|
if (this._pointerControl == null) {
|
|
this._pointerControl = new createjs.Shape();
|
|
this._pointerControl.x = x;
|
|
this._pointerControl.y = y;
|
|
point_pos = this.getPointPositionRelative();
|
|
this._pointerControl.graphics.beginStroke(BLACK);
|
|
this._pointerControl.graphics.arc(point_pos[0], point_pos[1],
|
|
SIZE_RESIZE_AREA / 2,
|
|
0, 2 * Math.PI);
|
|
this._pointerControl.graphics.endStroke();
|
|
|
|
var hitArea = new createjs.Shape();
|
|
hitArea.graphics.beginFill("#000").arc(
|
|
point_pos[0], point_pos[1], SIZE_RESIZE_AREA / 2,
|
|
0, 2 * Math.PI);
|
|
this._pointerControl.hitArea = hitArea;
|
|
|
|
this._pointerControl.visible = this.getSelected();
|
|
|
|
this._stage.addChild(this._pointerControl);
|
|
|
|
this._pointerControl.on("pressmove",function(event) {
|
|
this.setPointPosition(event.stageX, event.stageY);
|
|
this._box.selectGlobe(this);
|
|
this._pointerChanged = true;
|
|
this.update();
|
|
}, this);
|
|
} else {
|
|
this._pointerControl.x = x;
|
|
this._pointerControl.y = y;
|
|
this._pointerControl.visible = this.getSelected();
|
|
};
|
|
|
|
};
|
|
|
|
if (this._resizeButton == null) {
|
|
createAsyncBitmapButton(this, './icons/resize.svg',
|
|
function(globe, button) {
|
|
button.x = globe._x - globe._width - button.width / 2;
|
|
button.y = globe._y - globe._height - button.height / 2;
|
|
button.visible = globe.getSelected();
|
|
globe._resizeButton = button;
|
|
globe._stage.addChild(button);
|
|
globe._stage.update();
|
|
|
|
button.on('pressmove', function(event) {
|
|
this._width = Math.max(globe._x - event.stageX,
|
|
SIZE_RESIZE_AREA / 2);
|
|
this._height = Math.max(globe._y - event.stageY,
|
|
SIZE_RESIZE_AREA / 2);
|
|
this._shapeChanged = true;
|
|
this.update();
|
|
}, globe);
|
|
|
|
});
|
|
} else {
|
|
this._resizeButton.x = this._x - this._width - this._resizeButton.width / 2;
|
|
this._resizeButton.y = this._y - this._height - this._resizeButton.height / 2;
|
|
this._resizeButton.visible = this.getSelected();
|
|
};
|
|
|
|
if (this._editButton == null) {
|
|
createAsyncBitmapButton(this, './icons/edit.svg',
|
|
function(globe, button) {
|
|
button.x = globe._x + globe._width - button.width / 2;
|
|
button.y = globe._y - globe._height - button.height / 2;
|
|
button.visible = globe.getSelected();
|
|
globe._editButton = button;
|
|
globe._stage.addChild(button);
|
|
globe._stage.update();
|
|
|
|
button.on('click', function(event) {
|
|
globe._box.popupTextEditionPalette();
|
|
});
|
|
});
|
|
} else {
|
|
this._editButton.x = this._x + this._width - this._editButton.width / 2;
|
|
this._editButton.y = this._y - this._height - this._editButton.height / 2;
|
|
this._editButton.visible = this.getSelected();
|
|
};
|
|
|
|
if (this._type != TYPE_RECTANGLE) {
|
|
|
|
if (this._rotateButton == null) {
|
|
createAsyncBitmapButton(this, './icons/object_rotate_right.svg',
|
|
function(globe, button) {
|
|
button.x = globe._x + globe._width - button.width / 2;
|
|
button.y = globe._y + globe._height - button.height / 2;
|
|
button.visible = globe.getSelected();
|
|
globe._rotateButton = button;
|
|
globe._stage.addChild(button);
|
|
globe._stage.update();
|
|
|
|
button.on('click', function(event) {
|
|
globe.rotate();
|
|
});
|
|
});
|
|
} else {
|
|
this._rotateButton.x = this._x + this._width - this._rotateButton.width / 2;
|
|
this._rotateButton.y = this._y + this._height - this._rotateButton.height / 2;
|
|
this._rotateButton.visible = this.getSelected();
|
|
};
|
|
};
|
|
|
|
if (! this._isTitleGlobe) {
|
|
if (this._removeButton == null) {
|
|
createAsyncBitmapButton(this, './icons/remove.svg',
|
|
function(globe, button) {
|
|
button.x = globe._x - globe._width - button.width / 2;
|
|
button.y = globe._y + globe._height - button.height / 2;
|
|
button.visible = globe.getSelected();
|
|
globe._removeButton = button;
|
|
globe._stage.addChild(button);
|
|
globe._stage.update();
|
|
|
|
button.on('click', function(event) {
|
|
globe.remove();
|
|
});
|
|
});
|
|
} else {
|
|
this._removeButton.x = this._x - this._width - this._removeButton.width / 2;
|
|
this._removeButton.y = this._y + this._height - this._removeButton.height / 2;
|
|
this._removeButton.visible = this.getSelected();
|
|
};
|
|
};
|
|
|
|
this._shapeChanged = false;
|
|
this._pointerChanged = false;
|
|
};
|
|
|
|
this.rotate = function () {
|
|
switch (this._direction) {
|
|
case DIR_DOWN:
|
|
this._direction = DIR_LEFT;
|
|
break;
|
|
case DIR_RIGHT:
|
|
this._direction = DIR_DOWN;
|
|
break;
|
|
case DIR_LEFT:
|
|
this._direction = DIR_UP;
|
|
break;
|
|
case DIR_UP:
|
|
this._direction = DIR_RIGHT;
|
|
break;
|
|
};
|
|
var i = this._point[0];
|
|
this._point[0] = this._point[1]; this._point[1] = i;
|
|
this._pointerChanged = true;
|
|
this.update();
|
|
};
|
|
|
|
this.remove = function() {
|
|
var globeIndex = this._box.globes.indexOf(this);
|
|
if (globeIndex != -1) {
|
|
this._box.globes.splice(globeIndex, 1);
|
|
this._stage.removeChild(this._shape);
|
|
this._stage.removeChild(this._shapeControls);
|
|
if (this._type != TYPE_RECTANGLE) {
|
|
this._stage.removeChild(this._pointerControl);
|
|
this._stage.removeChild(this._rotateButton);
|
|
};
|
|
if (this._type == TYPE_CLOUD) {
|
|
this._stage.removeChild(this._shapeCircles);
|
|
};
|
|
this._stage.removeChild(this._resizeButton);
|
|
this._stage.removeChild(this._editButton);
|
|
this._stage.removeChild(this._removeButton);
|
|
this._textViewer.remove();
|
|
this._stage.update();
|
|
};
|
|
};
|
|
|
|
this.update = function() {
|
|
this.createShape();
|
|
this._textViewer.update();
|
|
this.createControls();
|
|
this._stage.update();
|
|
}
|
|
|
|
this.getPointPosition = function (scaled) {
|
|
var scale_x = 1;
|
|
var scale_y = 1;
|
|
if (scaled) {
|
|
scale_x = this._width / this._radio;
|
|
scale_y = this._height / this._radio;
|
|
};
|
|
|
|
var x = this._x / scale_x;
|
|
var y = this._y /scale_y;
|
|
var w = this._width / scale_x;
|
|
var h = this._height /scale_y;
|
|
|
|
switch (this._direction) {
|
|
case DIR_DOWN:
|
|
return [x + this._point[0] / scale_x,
|
|
y + h + this._point[1] / scale_y];
|
|
case DIR_RIGHT:
|
|
return [x + w + this._point[0] / scale_x,
|
|
y + this._point[1] / scale_y];
|
|
case DIR_LEFT:
|
|
return [x - w - this._point[0] / scale_x,
|
|
y + this._point[1] / scale_y];
|
|
case DIR_UP:
|
|
return [x + this._point[0] / scale_x,
|
|
y - h - this._point[1] / scale_y];
|
|
};
|
|
};
|
|
|
|
this.getPointPositionRelative = function () {
|
|
var w = this._width;
|
|
var h = this._height;
|
|
|
|
switch (this._direction) {
|
|
case DIR_DOWN:
|
|
return [this._point[0], h + this._point[1]];
|
|
case DIR_RIGHT:
|
|
return [w + this._point[0], this._point[1]];
|
|
case DIR_LEFT:
|
|
return [- w - this._point[0], this._point[1]];
|
|
case DIR_UP:
|
|
return [this._point[0], - h - this._point[1]];
|
|
};
|
|
};
|
|
|
|
this.setPointPosition = function (new_x, new_y) {
|
|
switch (this._direction) {
|
|
case DIR_DOWN:
|
|
this._point[0] = new_x - this._x;
|
|
this._point[1] = new_y - this._y - this._height;
|
|
break;
|
|
case DIR_RIGHT:
|
|
this._point[0] = new_x - this._x - this._width;
|
|
this._point[1] = new_y - this._y;
|
|
break;
|
|
case DIR_LEFT:
|
|
this._point[0] = - new_x + this._x - this._width;
|
|
this._point[1] = new_y - this._y;
|
|
break;
|
|
case DIR_UP:
|
|
this._point[0] = new_x - this._x;
|
|
this._point[1] = - new_y + this._y - this._height;
|
|
};
|
|
};
|
|
|
|
this.init();
|
|
this.update();
|
|
};
|
|
|
|
|
|
function BoxSorter(canvas, data) {
|
|
this.canvas = canvas;
|
|
this._data = data;
|
|
this._width = canvas.width - LINE_WIDTH * 2;
|
|
this._height = canvas.height - LINE_WIDTH * 2;
|
|
this._previewWidth = this._height * 4 / 3;
|
|
this._previewBitmaps = [];
|
|
this._deltaX = null;
|
|
|
|
this.stage = new createjs.Stage(canvas);
|
|
// Enable touch interactions if supported on the current device
|
|
createjs.Touch.enable(this.stage);
|
|
|
|
this.init = function () {
|
|
this.canvas.style.display = 'block';
|
|
this._backContainer = new createjs.Container();
|
|
var background = new createjs.Shape();
|
|
background.graphics.setStrokeStyle(LINE_WIDTH, "round");
|
|
background.graphics.beginStroke(
|
|
BLACK).drawRect(LINE_WIDTH, LINE_WIDTH,
|
|
this._width, this._height);
|
|
this.stage.addChild(this._backContainer);
|
|
this._backContainer.addChild(background);
|
|
this._backContainer.cache(0, 0, this.canvas.width, this.canvas.height);
|
|
|
|
this.loadPreviews();
|
|
this.stage.update();
|
|
};
|
|
|
|
this.hide = function() {
|
|
this.canvas.style.display = 'none';
|
|
};
|
|
|
|
this.loadPreviews = function () {
|
|
// create bitmaps for every box preview (if not avilable,
|
|
// use the background
|
|
for (var i = 0;i < this._data['boxs'].length; i++) {
|
|
var imageData = this._data['previews'][i];
|
|
if (imageData == undefined) {
|
|
var imageName = this._data['boxs'][i]['image_name'];
|
|
// if the preview was not loaded use the background
|
|
if (imageName != '' && imageName != undefined) {
|
|
imageData = this._data['images'][imageName];
|
|
};
|
|
};
|
|
if (imageData != undefined) {
|
|
this._createPreview(imageData, i);
|
|
};
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
this.getSortOrder = function() {
|
|
var newOrder = [0];
|
|
for (var i = 0; i < this._previewBitmaps.length; i++) {
|
|
newOrder.push(this._previewBitmaps[i]._order);
|
|
};
|
|
return newOrder;
|
|
};
|
|
|
|
this._createPreview = function(imageUrl, order) {
|
|
var img = new Image();
|
|
var that = this;
|
|
img.addEventListener("load", function() {
|
|
bitmap = new createjs.Bitmap(this);
|
|
bitmap.setBounds(0, 0, this.width, this.height);
|
|
bitmap._order = order;
|
|
// calculate scale
|
|
var scale_x = that._previewWidth / this.width;
|
|
var scale_y = that._height / this.height;
|
|
var scale = Math.min(scale_x, scale_y);
|
|
|
|
bitmap.x = that._previewWidth * order;
|
|
bitmap.y = LINE_WIDTH;
|
|
bitmap.scaleX = scale;
|
|
bitmap.scaleY = scale;
|
|
|
|
var hitArea = new createjs.Shape();
|
|
hitArea.graphics.beginFill("#000").drawRect(
|
|
0, 0, this.width, this.height);
|
|
bitmap.hitArea = hitArea;
|
|
|
|
// don't move first box
|
|
if (order > 0) {
|
|
that._previewBitmaps.push(bitmap);
|
|
|
|
bitmap.on('pressmove', function(event) {
|
|
console.log('TOON pressmove');
|
|
if (that._deltaX == null) {
|
|
that._deltaX = event.stageX - event.target.x;
|
|
// move the bitmap to the top
|
|
var thisBitmap = event.target;
|
|
that.stage.sortChildren(function (bitmapA, bitmapB) {
|
|
if (bitmapA == thisBitmap) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
};});
|
|
};
|
|
|
|
new_x = event.stageX - that._deltaX;
|
|
if (new_x > this._previewWidth / 2) {
|
|
event.target.x = new_x;
|
|
that.stage.update();
|
|
};
|
|
}, that);
|
|
|
|
bitmap.on('pressup', function(event) {
|
|
console.log('TOON pressup');
|
|
that._deltaX = null;
|
|
// sort the preview bitmaps
|
|
that._previewBitmaps.sort(function (bitmapA, bitmapB) {
|
|
return bitmapA.x - bitmapB.x;});
|
|
// adjust the positions
|
|
for (var i = 0; i < that._previewBitmaps.length; i++) {
|
|
that._previewBitmaps[i].x = that._previewWidth * (i + 1);
|
|
};
|
|
that.stage.update();
|
|
}, that);
|
|
|
|
};
|
|
|
|
that.stage.addChildAt(bitmap, 0);
|
|
that.stage.update();
|
|
|
|
});
|
|
img.src = imageUrl;
|
|
}
|
|
|
|
};
|
|
|
|
toon.Model = Model;
|
|
|
|
toon.TYPE_GLOBE = TYPE_GLOBE;
|
|
toon.TYPE_CLOUD = TYPE_CLOUD;
|
|
toon.TYPE_EXCLAMATION = TYPE_EXCLAMATION;
|
|
toon.TYPE_RECTANGLE = TYPE_RECTANGLE;
|
|
toon.TYPE_WHISPER = TYPE_WHISPER;
|
|
|
|
return toon;
|
|
});
|