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:
parent
069ccb0735
commit
4f6863eb8a
@ -37,8 +37,7 @@ module.exports = function(grunt) {
|
|||||||
undef : true,
|
undef : true,
|
||||||
latedef : true,
|
latedef : true,
|
||||||
browser : true,
|
browser : true,
|
||||||
jquery : true,
|
globals : {'$':true, 'jQuery' : true, 'pskl':true, 'Events':true, 'Constants':true, 'console' : true, 'module':true, 'require':true}
|
||||||
globals : {'pskl':true, 'Events':true, 'Constants':true, 'console' : true, 'module':true, 'require':true}
|
|
||||||
},
|
},
|
||||||
files: [
|
files: [
|
||||||
'Gruntfile.js',
|
'Gruntfile.js',
|
||||||
|
118
css/settings.css
Normal file
118
css/settings.css
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
|
||||||
|
/** Righty sticky drawer expanded state. */
|
||||||
|
|
||||||
|
.right-sticky-section.sticky-section {
|
||||||
|
right: 0;
|
||||||
|
width: 47px;
|
||||||
|
|
||||||
|
-webkit-transition: all 200ms ease-out;
|
||||||
|
-moz-transition: all 200ms ease-out;
|
||||||
|
-ms-transition: all 200ms ease-out;
|
||||||
|
transition: all 200ms ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-sticky-section.expanded {
|
||||||
|
right: 280px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-sticky-section .tool-icon {
|
||||||
|
float: right;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-content {
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #444;
|
||||||
|
height: 550px;
|
||||||
|
max-height: 100%;
|
||||||
|
width: 280px;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-sticky-section.expanded .tool-icon {
|
||||||
|
margin-right: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-sticky-section .tool-icon.has-expanded-drawer {
|
||||||
|
position: relative;
|
||||||
|
background-color: #444;
|
||||||
|
margin-right: 0;
|
||||||
|
padding-right: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-section {
|
||||||
|
margin: 10px 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ccc;
|
||||||
|
text-shadow: 1px 1px #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-title {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
border-bottom: 1px #aaa solid;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-item {}
|
||||||
|
|
||||||
|
.background-picker-wrapper {
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 10px 5px 20px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.background-picker {
|
||||||
|
cursor: pointer;
|
||||||
|
float: left;
|
||||||
|
height: 35px;
|
||||||
|
width: 35px;
|
||||||
|
background-color: transparent;
|
||||||
|
margin-right: 15px;
|
||||||
|
padding: 1px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.background-picker:after {
|
||||||
|
content: " ";
|
||||||
|
position: absolute;
|
||||||
|
top: -2px;
|
||||||
|
right: -2px;
|
||||||
|
bottom: -2px;
|
||||||
|
left: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.background-picker:hover:after {
|
||||||
|
border: #eee 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.background-picker.selected:after {
|
||||||
|
border: gold 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gif Export Setting panel*/
|
||||||
|
.export-gif-upload-button {
|
||||||
|
margin-top : 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.export-gif-preview {
|
||||||
|
margin-top:20px;
|
||||||
|
max-width:240px;
|
||||||
|
position:relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-upload-ongoing:before{
|
||||||
|
content: "Upload ongoing ...";
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 45%;
|
||||||
|
box-sizing:border-box;
|
||||||
|
-moz-box-sizing:border-box;
|
||||||
|
background: rgba(0,0,0,0.5);
|
||||||
|
color: white;
|
||||||
|
}
|
@ -98,103 +98,6 @@ body {
|
|||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.right-sticky-section.sticky-section {
|
|
||||||
right: 0;
|
|
||||||
width: 47px;
|
|
||||||
|
|
||||||
-webkit-transition: all 200ms ease-out;
|
|
||||||
-moz-transition: all 200ms ease-out;
|
|
||||||
-ms-transition: all 200ms ease-out;
|
|
||||||
transition: all 200ms ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-sticky-section .tool-icon {
|
|
||||||
float: right;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawer {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawer-content {
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #444;
|
|
||||||
height: 550px;
|
|
||||||
max-height: 100%;
|
|
||||||
width: 280px;
|
|
||||||
border-top-left-radius: 4px;
|
|
||||||
border-bottom-left-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Righty sticky drawer expanded state. */
|
|
||||||
|
|
||||||
.right-sticky-section.expanded {
|
|
||||||
right: 280px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-sticky-section.expanded .tool-icon {
|
|
||||||
margin-right: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-sticky-section .tool-icon.has-expanded-drawer {
|
|
||||||
position: relative;
|
|
||||||
background-color: #444;
|
|
||||||
margin-right: 0;
|
|
||||||
padding-right: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-section {
|
|
||||||
margin: 10px 20px;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #ccc;
|
|
||||||
text-shadow: 1px 1px #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-title {
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
border-bottom: 1px #aaa solid;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.settings-item {}
|
|
||||||
|
|
||||||
.background-picker-wrapper {
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 10px 5px 20px 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background-picker {
|
|
||||||
cursor: pointer;
|
|
||||||
float: left;
|
|
||||||
height: 35px;
|
|
||||||
width: 35px;
|
|
||||||
background-color: transparent;
|
|
||||||
margin-right: 15px;
|
|
||||||
padding: 1px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background-picker:after {
|
|
||||||
content: " ";
|
|
||||||
position: absolute;
|
|
||||||
top: -2px;
|
|
||||||
right: -2px;
|
|
||||||
bottom: -2px;
|
|
||||||
left: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background-picker:hover:after {
|
|
||||||
border: #eee 1px solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background-picker.selected:after {
|
|
||||||
border: gold 1px solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Canvases layout
|
* Canvases layout
|
||||||
*/
|
*/
|
||||||
|
30
index.html
30
index.html
@ -9,6 +9,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" type="text/css" href="css/reset.css">
|
<link rel="stylesheet" type="text/css" href="css/reset.css">
|
||||||
<link rel="stylesheet" type="text/css" href="css/style.css">
|
<link rel="stylesheet" type="text/css" href="css/style.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/settings.css">
|
||||||
<link rel="stylesheet" type="text/css" href="css/tools.css">
|
<link rel="stylesheet" type="text/css" href="css/tools.css">
|
||||||
<link rel="stylesheet" type="text/css" href="css/bootstrap/bootstrap.css">
|
<link rel="stylesheet" type="text/css" href="css/bootstrap/bootstrap.css">
|
||||||
<link rel="stylesheet" type="text/css" href="css/bootstrap/bootstrap-tooltip-custom.css">
|
<link rel="stylesheet" type="text/css" href="css/bootstrap/bootstrap-tooltip-custom.css">
|
||||||
@ -22,37 +23,34 @@
|
|||||||
<div id="main-wrapper" class="main-wrapper">
|
<div id="main-wrapper" class="main-wrapper">
|
||||||
<iframe src="templates/drawing-tools.html" class="_ctl" onload="_ctl(event)"></iframe>
|
<iframe src="templates/drawing-tools.html" class="_ctl" onload="_ctl(event)"></iframe>
|
||||||
|
|
||||||
<div id="application-action-section" class="sticky-section right-sticky-section">
|
|
||||||
<div class="sticky-section-wrap">
|
|
||||||
<iframe src="templates/settings.html" class="_ctl" onload="_ctl(event)"></iframe>
|
|
||||||
<div class="drawer vertical-centerer">
|
|
||||||
<div class="drawer-content" id="drawer-container">
|
|
||||||
<!-- these templates are only preloaded in script tags for reusing in JS later -->
|
|
||||||
<iframe src="templates/settings-application.html" onload="_ctp(event)"></iframe>
|
|
||||||
<iframe src="templates/settings-export-gif.html" onload="_ctp(event)"></iframe>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="column-wrapper" class="column-wrapper">
|
<div id="column-wrapper" class="column-wrapper">
|
||||||
<div class='column left-column'>
|
<div class='column left-column'>
|
||||||
<!-- List of frames: -->
|
|
||||||
<iframe src="templates/frames-list.html" class="_ctl" onload="_ctl(event)"></iframe>
|
<iframe src="templates/frames-list.html" class="_ctl" onload="_ctl(event)"></iframe>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='column main-column'>
|
<div class='column main-column'>
|
||||||
<!-- Drawing area: -->
|
|
||||||
<div id="drawing-canvas-container" class="drawing-canvas-container canvas-container">
|
<div id="drawing-canvas-container" class="drawing-canvas-container canvas-container">
|
||||||
<div class="canvas-background"></div>
|
<div class="canvas-background"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="column right-column">
|
<div class="column right-column">
|
||||||
<!-- Animation preview: -->
|
|
||||||
<iframe src="templates/preview.html" class="_ctl" onload="_ctl(event)"></iframe>
|
<iframe src="templates/preview.html" class="_ctl" onload="_ctl(event)"></iframe>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="application-action-section" data-pskl-controller="settings" class="sticky-section right-sticky-section">
|
||||||
|
<div class="sticky-section-wrap">
|
||||||
|
<iframe src="templates/settings.html" class="_ctl" onload="_ctl(event)"></iframe>
|
||||||
|
<div class="drawer vertical-centerer">
|
||||||
|
<div class="drawer-content" id="drawer-container">
|
||||||
|
<iframe src="templates/settings-application.html" onload="_ctp(event)"></iframe>
|
||||||
|
<iframe src="templates/settings-export-gif.html" onload="_ctp(event)"></iframe>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript" src="piskel-boot.js"></script>
|
<script type="text/javascript" src="piskel-boot.js"></script>
|
||||||
|
@ -15,9 +15,10 @@
|
|||||||
var SEL_SETTING_CLS = 'has-expanded-drawer';
|
var SEL_SETTING_CLS = 'has-expanded-drawer';
|
||||||
var EXP_DRAWER_CLS = 'expanded';
|
var EXP_DRAWER_CLS = 'expanded';
|
||||||
|
|
||||||
ns.SettingsController = function () {
|
ns.SettingsController = function (framesheet) {
|
||||||
|
this.framesheet = framesheet;
|
||||||
this.drawerContainer = document.getElementById("drawer-container");
|
this.drawerContainer = document.getElementById("drawer-container");
|
||||||
this.settingsContainer = $('.right-sticky-section');
|
this.settingsContainer = $('[data-pskl-controller=settings]');
|
||||||
this.expanded = false;
|
this.expanded = false;
|
||||||
this.currentSetting = null;
|
this.currentSetting = null;
|
||||||
};
|
};
|
||||||
@ -28,7 +29,7 @@
|
|||||||
ns.SettingsController.prototype.init = function() {
|
ns.SettingsController.prototype.init = function() {
|
||||||
// Expand drawer when clicking 'Settings' tab.
|
// Expand drawer when clicking 'Settings' tab.
|
||||||
$('[data-setting]').click(function(evt) {
|
$('[data-setting]').click(function(evt) {
|
||||||
var el = event.currentTarget;
|
var el = evt.originalEvent.currentTarget;
|
||||||
var setting = el.dataset.setting;
|
var setting = el.dataset.setting;
|
||||||
if (this.currentSetting != setting) {
|
if (this.currentSetting != setting) {
|
||||||
this.loadSetting(setting);
|
this.loadSetting(setting);
|
||||||
@ -36,17 +37,25 @@
|
|||||||
this.closeDrawer();
|
this.closeDrawer();
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.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) {
|
ns.SettingsController.prototype.loadSetting = function (setting) {
|
||||||
this.drawerContainer.innerHTML = this.getTemplate_(settings[setting].template);
|
this.drawerContainer.innerHTML = pskl.utils.Template.get(settings[setting].template);
|
||||||
(new settings[setting].controller()).init();
|
(new settings[setting].controller(this.framesheet)).init();
|
||||||
|
|
||||||
this.settingsContainer.addClass(EXP_DRAWER_CLS);
|
this.settingsContainer.addClass(EXP_DRAWER_CLS);
|
||||||
|
|
||||||
$('.' + SEL_SETTING_CLS).removeClass(SEL_SETTING_CLS);
|
$('.' + SEL_SETTING_CLS).removeClass(SEL_SETTING_CLS);
|
||||||
$('[data-setting='+setting+']').addClass(SEL_SETTING_CLS);
|
$('[data-setting='+setting+']').addClass(SEL_SETTING_CLS);
|
||||||
|
|
||||||
|
this.expanded = true;
|
||||||
this.currentSetting = setting;
|
this.currentSetting = setting;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -54,16 +63,8 @@
|
|||||||
this.settingsContainer.removeClass(EXP_DRAWER_CLS);
|
this.settingsContainer.removeClass(EXP_DRAWER_CLS);
|
||||||
$('.' + SEL_SETTING_CLS).removeClass(SEL_SETTING_CLS);
|
$('.' + SEL_SETTING_CLS).removeClass(SEL_SETTING_CLS);
|
||||||
|
|
||||||
|
this.expanded = false;
|
||||||
this.currentSetting = null;
|
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 () {
|
(function () {
|
||||||
var ns = $.namespace("pskl.controller.settings");
|
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 = new pskl.controller.PreviewFilmController(frameSheet, $('#preview-list'));
|
||||||
this.previewsController.init();
|
this.previewsController.init();
|
||||||
|
|
||||||
this.settingsController = new pskl.controller.SettingsController();
|
this.settingsController = new pskl.controller.SettingsController(frameSheet);
|
||||||
this.settingsController.init();
|
this.settingsController.init();
|
||||||
|
|
||||||
this.selectionManager = new pskl.selection.SelectionManager(frameSheet);
|
this.selectionManager = new pskl.selection.SelectionManager(frameSheet);
|
||||||
@ -52,6 +52,9 @@
|
|||||||
this.localStorageService = new pskl.service.LocalStorageService(frameSheet);
|
this.localStorageService = new pskl.service.LocalStorageService(frameSheet);
|
||||||
this.localStorageService.init();
|
this.localStorageService.init();
|
||||||
|
|
||||||
|
this.imageUploadService = new pskl.service.ImageUploadService();
|
||||||
|
this.imageUploadService.init();
|
||||||
|
|
||||||
this.toolController = new pskl.controller.ToolController();
|
this.toolController = new pskl.controller.ToolController();
|
||||||
this.toolController.init();
|
this.toolController.init();
|
||||||
|
|
||||||
@ -211,34 +214,18 @@
|
|||||||
return false;
|
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 () {
|
uploadAsAnimatedGIF : function () {
|
||||||
var fps = pskl.app.animationController.fps;
|
var fps = pskl.app.animationController.fps;
|
||||||
var renderer = new pskl.rendering.SpritesheetRenderer(frameSheet);
|
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 () {
|
uploadAsSpritesheetPNG : function () {
|
||||||
var imageData = (new pskl.rendering.SpritesheetRenderer(frameSheet)).renderAsImageDataSpritesheetPNG();
|
var imageData = (new pskl.rendering.SpritesheetRenderer(frameSheet)).renderAsImageDataSpritesheetPNG();
|
||||||
this.uploadToScreenletstore(imageData);
|
this.imageUploadService.upload(imageData, this.openWindow);
|
||||||
},
|
},
|
||||||
|
|
||||||
openWindow : function (url) {
|
openWindow : function (url) {
|
||||||
|
@ -15,40 +15,6 @@
|
|||||||
return canvas.toDataURL("image/png");
|
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
|
* 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
@ -9,6 +9,9 @@
|
|||||||
|
|
||||||
if (window.location.href.indexOf("debug") != -1) {
|
if (window.location.href.indexOf("debug") != -1) {
|
||||||
window.exports = {};
|
window.exports = {};
|
||||||
|
//debug shortcuts
|
||||||
|
cl = function () {console.log.apply(console, arguments)};
|
||||||
|
d = function () {debugger};
|
||||||
var scriptIndex = 0;
|
var scriptIndex = 0;
|
||||||
window.loadNextScript = function () {
|
window.loadNextScript = function () {
|
||||||
if (scriptIndex == exports.scripts.length) {
|
if (scriptIndex == exports.scripts.length) {
|
||||||
|
@ -13,6 +13,7 @@ exports.scripts = [
|
|||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
"js/utils/core.js",
|
"js/utils/core.js",
|
||||||
|
"js/utils/Template.js",
|
||||||
"js/utils/PixelUtils.js",
|
"js/utils/PixelUtils.js",
|
||||||
"js/utils/CanvasUtils.js",
|
"js/utils/CanvasUtils.js",
|
||||||
"js/utils/UserSettings.js",
|
"js/utils/UserSettings.js",
|
||||||
@ -49,6 +50,7 @@ exports.scripts = [
|
|||||||
"js/service/LocalStorageService.js",
|
"js/service/LocalStorageService.js",
|
||||||
"js/service/HistoryService.js",
|
"js/service/HistoryService.js",
|
||||||
"js/service/KeyboardEventService.js",
|
"js/service/KeyboardEventService.js",
|
||||||
|
"js/service/ImageUploadService.js",
|
||||||
|
|
||||||
// Tools
|
// Tools
|
||||||
"js/drawingtools/BaseTool.js",
|
"js/drawingtools/BaseTool.js",
|
||||||
|
@ -1 +1,16 @@
|
|||||||
LOLOLOLOL
|
<div class="settings-section">
|
||||||
|
<div class="settings-title">
|
||||||
|
Export to Animated GIF
|
||||||
|
</div>
|
||||||
|
<div class="settings-item">
|
||||||
|
<label>Select resolution:</label>
|
||||||
|
<form action="" method="POST" name="gif-export-upload-form">
|
||||||
|
<script type="text/template" id="export-gif-radio-template">
|
||||||
|
<label style="display:block"><input type="radio" name="gif-dpi" value="{{value}}"/>
|
||||||
|
{{label}}</label>
|
||||||
|
</script>
|
||||||
|
<input type="submit" class="export-gif-upload-button" value="Upload" />
|
||||||
|
</form>
|
||||||
|
<div class="export-gif-preview"><div></div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
Loading…
x
Reference in New Issue
Block a user