mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Gif export panel first draft
This commit is contained in:
@@ -15,9 +15,10 @@
|
||||
var SEL_SETTING_CLS = 'has-expanded-drawer';
|
||||
var EXP_DRAWER_CLS = 'expanded';
|
||||
|
||||
ns.SettingsController = function () {
|
||||
ns.SettingsController = function (framesheet) {
|
||||
this.framesheet = framesheet;
|
||||
this.drawerContainer = document.getElementById("drawer-container");
|
||||
this.settingsContainer = $('.right-sticky-section');
|
||||
this.settingsContainer = $('[data-pskl-controller=settings]');
|
||||
this.expanded = false;
|
||||
this.currentSetting = null;
|
||||
};
|
||||
@@ -28,7 +29,7 @@
|
||||
ns.SettingsController.prototype.init = function() {
|
||||
// Expand drawer when clicking 'Settings' tab.
|
||||
$('[data-setting]').click(function(evt) {
|
||||
var el = event.currentTarget;
|
||||
var el = evt.originalEvent.currentTarget;
|
||||
var setting = el.dataset.setting;
|
||||
if (this.currentSetting != setting) {
|
||||
this.loadSetting(setting);
|
||||
@@ -36,17 +37,25 @@
|
||||
this.closeDrawer();
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
$('body').click(function (evt) {
|
||||
var isInSettingsContainer = $.contains(this.settingsContainer.get(0), evt.target);
|
||||
if (this.expanded && !isInSettingsContainer) {
|
||||
this.closeDrawer();
|
||||
}
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
ns.SettingsController.prototype.loadSetting = function (setting) {
|
||||
this.drawerContainer.innerHTML = this.getTemplate_(settings[setting].template);
|
||||
(new settings[setting].controller()).init();
|
||||
this.drawerContainer.innerHTML = pskl.utils.Template.get(settings[setting].template);
|
||||
(new settings[setting].controller(this.framesheet)).init();
|
||||
|
||||
this.settingsContainer.addClass(EXP_DRAWER_CLS);
|
||||
|
||||
$('.' + SEL_SETTING_CLS).removeClass(SEL_SETTING_CLS);
|
||||
$('[data-setting='+setting+']').addClass(SEL_SETTING_CLS);
|
||||
|
||||
this.expanded = true;
|
||||
this.currentSetting = setting;
|
||||
};
|
||||
|
||||
@@ -54,16 +63,8 @@
|
||||
this.settingsContainer.removeClass(EXP_DRAWER_CLS);
|
||||
$('.' + SEL_SETTING_CLS).removeClass(SEL_SETTING_CLS);
|
||||
|
||||
this.expanded = false;
|
||||
this.currentSetting = null;
|
||||
};
|
||||
|
||||
ns.SettingsController.prototype.getTemplate_ = function (templateId) {
|
||||
var template = document.getElementById(templateId);
|
||||
if (template) {
|
||||
return template.innerHTML;
|
||||
} else {
|
||||
console.error("Could not find template for id :", templateId);
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
@@ -1,8 +1,107 @@
|
||||
(function () {
|
||||
var ns = $.namespace("pskl.controller.settings");
|
||||
ns.GifExportController = function () {
|
||||
|
||||
ns.GifExportController = function (framesheet) {
|
||||
this.framesheet = framesheet;
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.init = function () {};
|
||||
ns.GifExportController.prototype.init = function () {
|
||||
this.initRadioElements_();
|
||||
|
||||
this.previewContainer = document.querySelectorAll(".export-gif-preview div")[0];
|
||||
this.uploadForm = $("[name=gif-export-upload-form]");
|
||||
|
||||
this.uploadForm.submit(this.upload.bind(this));
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.upload = function (evt) {
|
||||
evt.originalEvent.preventDefault();
|
||||
var selectedDpi = this.getSelectedDpi_(),
|
||||
fps = pskl.app.animationController.fps,
|
||||
dpi = selectedDpi;
|
||||
|
||||
this.renderAsImageDataAnimatedGIF(dpi, fps, function (imageData) {
|
||||
this.updatePreview_(imageData);
|
||||
this.previewContainer.classList.add("preview-upload-ongoing");
|
||||
pskl.app.imageUploadService.upload(imageData, function (imageUrl) {
|
||||
this.updatePreview_(imageUrl);
|
||||
this.previewContainer.classList.remove("preview-upload-ongoing");
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.updatePreview_ = function (src) {
|
||||
this.previewContainer.innerHTML = "<img style='max-width:240px;' src='"+src+"'/>";
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.getSelectedDpi_ = function () {
|
||||
var radiosColl = this.uploadForm.get(0).querySelectorAll("[name=gif-dpi]"),
|
||||
radios = Array.prototype.slice.call(radiosColl,0);
|
||||
var selectedRadios = radios.filter(function(radio) {return !!radio.checked;});
|
||||
|
||||
if (selectedRadios.length == 1) {
|
||||
return selectedRadios[0].value;
|
||||
} else {
|
||||
throw "Unexpected error when retrieving selected dpi";
|
||||
}
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.initRadioElements_ = function () {
|
||||
var dpis = [
|
||||
[1],
|
||||
[5],
|
||||
[10,true] //default
|
||||
];
|
||||
|
||||
var radioTpl = $("#export-gif-radio-template").get(0);
|
||||
for (var i = 0 ; i < dpis.length ; i++) {
|
||||
var dpi = dpis[i];
|
||||
var radio = this.createRadioForDpi_(dpi, radioTpl.innerHTML);
|
||||
radioTpl.parentNode.insertBefore(radio, radioTpl);
|
||||
}
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.createRadioForDpi_ = function (dpi, template) {
|
||||
var label = dpi[0]*this.framesheet.getWidth() + "x" + dpi[0]*this.framesheet.getHeight();
|
||||
var value = dpi[0];
|
||||
var radioHTML = pskl.utils.Template.replace(template, {value : value, label : label});
|
||||
var radio = pskl.utils.Template.createFromHTML(radioHTML);
|
||||
|
||||
if (dpi[1]) {
|
||||
radio.getElementsByTagName("input")[0].setAttribute("checked", "checked");
|
||||
}
|
||||
|
||||
return radio;
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.blobToBase64_ = function(blob, cb) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function() {
|
||||
var dataUrl = reader.result;
|
||||
cb(dataUrl);
|
||||
};
|
||||
reader.readAsDataURL(blob);
|
||||
};
|
||||
|
||||
ns.GifExportController.prototype.renderAsImageDataAnimatedGIF = function(dpi, fps, cb) {
|
||||
var gif = new window.GIF({
|
||||
workers: 2,
|
||||
quality: 10,
|
||||
width: this.framesheet.getWidth()*dpi,
|
||||
height: this.framesheet.getHeight()*dpi
|
||||
});
|
||||
|
||||
for (var i = 0; i < this.framesheet.frames.length; i++) {
|
||||
var frame = this.framesheet.frames[i];
|
||||
var renderer = new pskl.rendering.CanvasRenderer(frame, dpi);
|
||||
gif.addFrame(renderer.render(), {
|
||||
delay: 1000 / fps
|
||||
});
|
||||
}
|
||||
|
||||
gif.on('finished', function(blob) {
|
||||
this.blobToBase64_(blob, cb);
|
||||
}.bind(this));
|
||||
|
||||
gif.render();
|
||||
};
|
||||
})();
|
29
js/piskel.js
29
js/piskel.js
@@ -34,7 +34,7 @@
|
||||
this.previewsController = new pskl.controller.PreviewFilmController(frameSheet, $('#preview-list'));
|
||||
this.previewsController.init();
|
||||
|
||||
this.settingsController = new pskl.controller.SettingsController();
|
||||
this.settingsController = new pskl.controller.SettingsController(frameSheet);
|
||||
this.settingsController.init();
|
||||
|
||||
this.selectionManager = new pskl.selection.SelectionManager(frameSheet);
|
||||
@@ -52,6 +52,9 @@
|
||||
this.localStorageService = new pskl.service.LocalStorageService(frameSheet);
|
||||
this.localStorageService.init();
|
||||
|
||||
this.imageUploadService = new pskl.service.ImageUploadService();
|
||||
this.imageUploadService.init();
|
||||
|
||||
this.toolController = new pskl.controller.ToolController();
|
||||
this.toolController.init();
|
||||
|
||||
@@ -211,34 +214,18 @@
|
||||
return false;
|
||||
},
|
||||
|
||||
uploadToScreenletstore : function (imageData) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var formData = new FormData();
|
||||
formData.append('data', imageData);
|
||||
xhr.open('POST', "http://screenletstore.appspot.com/__/upload", true);
|
||||
var cloudURL;
|
||||
var that = this;
|
||||
xhr.onload = function (e) {
|
||||
if (this.status == 200) {
|
||||
cloudURL = "http://screenletstore.appspot.com/img/" + this.responseText;
|
||||
that.openWindow(cloudURL);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(formData);
|
||||
},
|
||||
|
||||
uploadAsAnimatedGIF : function () {
|
||||
var fps = pskl.app.animationController.fps;
|
||||
var renderer = new pskl.rendering.SpritesheetRenderer(frameSheet);
|
||||
var cb = this.uploadToScreenletstore.bind(this);
|
||||
|
||||
renderer.renderAsImageDataAnimatedGIF(fps, cb);
|
||||
renderer.renderAsImageDataAnimatedGIF(fps, function (imageData) {
|
||||
this.imageUploadService.upload(imageData, this.openWindow);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
uploadAsSpritesheetPNG : function () {
|
||||
var imageData = (new pskl.rendering.SpritesheetRenderer(frameSheet)).renderAsImageDataSpritesheetPNG();
|
||||
this.uploadToScreenletstore(imageData);
|
||||
this.imageUploadService.upload(imageData, this.openWindow);
|
||||
},
|
||||
|
||||
openWindow : function (url) {
|
||||
|
@@ -15,40 +15,6 @@
|
||||
return canvas.toDataURL("image/png");
|
||||
};
|
||||
|
||||
ns.SpritesheetRenderer.prototype.blobToBase64_ = function(blob, cb) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function() {
|
||||
var dataUrl = reader.result;
|
||||
cb(dataUrl);
|
||||
};
|
||||
reader.readAsDataURL(blob);
|
||||
};
|
||||
|
||||
ns.SpritesheetRenderer.prototype.renderAsImageDataAnimatedGIF = function(fps, cb) {
|
||||
var dpi = 10;
|
||||
var gif = new window.GIF({
|
||||
workers: 2,
|
||||
quality: 10,
|
||||
width: 320,
|
||||
height: 320
|
||||
});
|
||||
|
||||
for (var i = 0; i < this.framesheet.frames.length; i++) {
|
||||
var frame = this.framesheet.frames[i];
|
||||
var renderer = new pskl.rendering.CanvasRenderer(frame, dpi);
|
||||
gif.addFrame(renderer.render(), {
|
||||
delay: 1000 / fps
|
||||
});
|
||||
}
|
||||
|
||||
gif.on('finished', function(blob) {
|
||||
this.blobToBase64_(blob, cb);
|
||||
}.bind(this));
|
||||
|
||||
gif.render();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* TODO(juliandescottes): Mutualize with code already present in FrameRenderer
|
||||
*/
|
||||
|
34
js/service/ImageUploadService.js
Normal file
34
js/service/ImageUploadService.js
Normal file
@@ -0,0 +1,34 @@
|
||||
(function () {
|
||||
var ns = $.namespace("pskl.service");
|
||||
ns.ImageUploadService = function () {
|
||||
this.serviceUrl_ = "http://screenletstore.appspot.com/__/upload";
|
||||
};
|
||||
|
||||
ns.ImageUploadService.prototype.init = function () {
|
||||
// service interface
|
||||
};
|
||||
|
||||
/**
|
||||
* Upload a base64 image data to distant service. If successful, will call provided callback with the image URL as first argument;
|
||||
* @param {String} imageData base64 image data (such as the return value of canvas.toDataUrl())
|
||||
* @param {Function} cbSuccess success callback. 1st argument will be the uploaded image URL
|
||||
* @param {Function} cbError error callback
|
||||
*/
|
||||
ns.ImageUploadService.prototype.upload = function (imageData, cbSuccess, cbError) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
var formData = new FormData();
|
||||
formData.append('data', imageData);
|
||||
xhr.open('POST', this.serviceUrl_, true);
|
||||
xhr.onload = function (e) {
|
||||
if (this.status == 200) {
|
||||
var imageUrl = "http://screenletstore.appspot.com/img/" + this.responseText;
|
||||
cbSuccess(imageUrl);
|
||||
} else {
|
||||
cbError();
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(formData);
|
||||
};
|
||||
|
||||
})();
|
30
js/utils/Template.js
Normal file
30
js/utils/Template.js
Normal file
@@ -0,0 +1,30 @@
|
||||
(function () {
|
||||
var ns = $.namespace("pskl");
|
||||
|
||||
ns.utils.Template = {
|
||||
get : function (templateId) {
|
||||
var template = document.getElementById(templateId);
|
||||
if (template) {
|
||||
return template.innerHTML;
|
||||
} else {
|
||||
console.error("Could not find template for id :", templateId);
|
||||
}
|
||||
},
|
||||
|
||||
createFromHTML : function (html) {
|
||||
var dummyEl = document.createElement("div");
|
||||
dummyEl.innerHTML = html;
|
||||
return dummyEl.children[0];
|
||||
},
|
||||
|
||||
replace : function (template, dict) {
|
||||
for (var key in dict) {
|
||||
if (dict.hasOwnProperty(key)) {
|
||||
var value = dict[key];
|
||||
template = template.replace(new RegExp('\\{\\{'+key+'\\}\\}', 'g'), value);
|
||||
}
|
||||
}
|
||||
return template;
|
||||
}
|
||||
};
|
||||
})();
|
Reference in New Issue
Block a user