mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Import panel
This commit is contained in:
parent
61419f0bba
commit
6c0f54032d
@ -115,4 +115,40 @@
|
||||
-moz-box-sizing:border-box;
|
||||
background: rgba(0,0,0,0.5);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Import panel */
|
||||
.import-section {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.import-resize-field {
|
||||
width: 30px;
|
||||
margin: 0px 8px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.file-input-button {
|
||||
margin: 0px 8px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.file-input-status {
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
text-shadow : none;
|
||||
}
|
||||
|
||||
.import-button {
|
||||
float: right;
|
||||
padding : 8px 10px;
|
||||
height: auto;
|
||||
background: gold;
|
||||
color: black;
|
||||
text-shadow: 0px 1px 0 #fff;
|
||||
border-radius: 2px;
|
||||
font-size : 1.2rem;
|
||||
border-color: rgb(179, 164, 0);
|
||||
border-top-color: white;
|
||||
border-bottom-color: rgb(151, 133, 0);
|
||||
}
|
@ -246,35 +246,19 @@ body {
|
||||
}
|
||||
|
||||
.layers-button {
|
||||
height: 24px;
|
||||
margin: 0;
|
||||
width: 25%;
|
||||
float : left;
|
||||
border: none;
|
||||
box-sizing: border-box;
|
||||
border-top: 1px solid #666;
|
||||
border-right: 1px solid #333;
|
||||
border-bottom: 1px solid #333;
|
||||
background-color: #3f3f3f;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
font-size: 0.7em;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
text-shadow: 0px -1px 0 #000;
|
||||
transition: background-color 0.2s linear;
|
||||
}
|
||||
|
||||
/* @override */
|
||||
.button.layers-button {
|
||||
border-left-width: 0;
|
||||
}
|
||||
|
||||
.layers-button:last-child {
|
||||
border-right-width: 0;
|
||||
}
|
||||
|
||||
.layers-button:hover {
|
||||
text-decoration: none;
|
||||
background-color: #484848;
|
||||
color: gold;
|
||||
}
|
||||
/**
|
||||
* User messages
|
||||
*/
|
||||
|
@ -9,6 +9,7 @@
|
||||
<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/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/forms.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/bootstrap/bootstrap.css">
|
||||
|
@ -1,46 +1,47 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.settings');
|
||||
|
||||
var DEFAULT_FILE_STATUS = 'No file selected ...';
|
||||
ns.ImportController = function (piskelController) {
|
||||
this.piskelController = piskelController;
|
||||
this.importedImage_ = null;
|
||||
};
|
||||
|
||||
ns.ImportController.prototype.init = function () {
|
||||
this.fileUploadInput = $("[name=file-upload-input]");
|
||||
this.urlInput = $("[name=url-input]");
|
||||
this.importForm = $("[name=import-form]");
|
||||
this.hiddenFileInput = $("[name=file-upload-input]");
|
||||
this.fileInputButton = $(".file-input-button");
|
||||
this.fileInputStatus=$(".file-input-status");
|
||||
this.fileInputStatus.html(DEFAULT_FILE_STATUS);
|
||||
|
||||
this.resizeWidth = $("[name=resize-width]");
|
||||
this.resizeHeight = $("[name=resize-height]");
|
||||
|
||||
this.importForm.submit(this.onImportFormSubmit_.bind(this));
|
||||
this.hiddenFileInput.change(this.onFileUploadChange_.bind(this));
|
||||
this.fileInputButton.click(this.onFileInputClick_.bind(this));
|
||||
};
|
||||
|
||||
ns.ImportController.prototype.reset_ = function () {
|
||||
this.importForm.get(0).reset();
|
||||
this.fileInputStatus.html(DEFAULT_FILE_STATUS);
|
||||
|
||||
};
|
||||
|
||||
ns.ImportController.prototype.onImportFormSubmit_ = function (evt) {
|
||||
evt.originalEvent.preventDefault();
|
||||
var importType = this.getSelectedRadioValue_();
|
||||
if (importType === 'FILE') {
|
||||
this.importFromFile_();
|
||||
} else if (importType === 'URL') {
|
||||
this.importFromUrl_();
|
||||
}
|
||||
this.importImageToPiskel_();
|
||||
};
|
||||
|
||||
ns.ImportController.prototype.getSelectedRadioValue_ = function () {
|
||||
var radios = this.getRadios_();
|
||||
var selectedRadios = radios.filter(function(radio) {
|
||||
return !!radio.checked;
|
||||
});
|
||||
ns.ImportController.prototype.onFileUploadChange_ = function (evt) {
|
||||
this.importFromFile_();
|
||||
};
|
||||
|
||||
if (selectedRadios.length == 1) {
|
||||
return selectedRadios[0].value;
|
||||
} else {
|
||||
throw "Unexpected error when retrieving selected radio";
|
||||
}
|
||||
ns.ImportController.prototype.onFileInputClick_ = function (evt) {
|
||||
this.hiddenFileInput.click();
|
||||
};
|
||||
|
||||
ns.ImportController.prototype.importFromFile_ = function () {
|
||||
var files = this.fileUploadInput.get(0).files;
|
||||
var files = this.hiddenFileInput.get(0).files;
|
||||
if (files.length == 1) {
|
||||
var file = files[0];
|
||||
if (this.isImage_(file)) {
|
||||
@ -52,35 +53,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
ns.ImportController.prototype.importFromUrl_ = function () {
|
||||
var url = this.urlInput.get(0).value;
|
||||
if (this.isUrl_(url)) {
|
||||
this.processImageSource_(url);
|
||||
} else {
|
||||
this.reset_();
|
||||
throw "Not a url : " + url;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO : implement it properly
|
||||
* @param {String} url potential url to test
|
||||
* @return {Boolean} true if url looks like a URL
|
||||
*/
|
||||
ns.ImportController.prototype.isUrl_ = function (url) {
|
||||
if (typeof url === 'string') {
|
||||
return (/^http/).test(url);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
ns.ImportController.prototype.getRadios_ = function () {
|
||||
var radiosColl = this.importForm.get(0).querySelectorAll("[name=upload-source-type]"),
|
||||
radios = Array.prototype.slice.call(radiosColl,0);
|
||||
return radios;
|
||||
};
|
||||
|
||||
ns.ImportController.prototype.readImageFile_ = function (imageFile) {
|
||||
pskl.utils.FileUtils.readFile(imageFile, this.processImageSource_.bind(this));
|
||||
};
|
||||
@ -91,24 +63,63 @@
|
||||
* @param {String} imageSource url or data-url, will be used as src for the image
|
||||
*/
|
||||
ns.ImportController.prototype.processImageSource_ = function (imageSource) {
|
||||
var image = new Image();
|
||||
image.onload = this.onImageLoaded_.bind(this);
|
||||
image.src = imageSource;
|
||||
this.importedImage_ = new Image();
|
||||
this.importedImage_.onload = this.onImageLoaded_.bind(this);
|
||||
this.importedImage_.src = imageSource;
|
||||
};
|
||||
|
||||
ns.ImportController.prototype.onImageLoaded_ = function (evt) {
|
||||
var image = evt.target;
|
||||
var w = this.importedImage_.width,
|
||||
h = this.importedImage_.height;
|
||||
this.resizeWidth.val(w);
|
||||
this.resizeHeight.val(h);
|
||||
|
||||
var w = image.width, h = image.height;
|
||||
var filePath = this.hiddenFileInput.val();
|
||||
var fileName = this.extractFileNameFromPath_(filePath);
|
||||
this.fileInputStatus.html(fileName);
|
||||
};
|
||||
|
||||
ns.ImportController.prototype.extractFileNameFromPath_ = function (path) {
|
||||
var parts = [];
|
||||
if (path.indexOf('/') !== -1) {
|
||||
parts = path.split('/');
|
||||
} else if (path.indexOf('\\') !== -1) {
|
||||
parts = path.split('\\');
|
||||
} else {
|
||||
parts = [path];
|
||||
}
|
||||
return parts[parts.length-1];
|
||||
};
|
||||
|
||||
ns.ImportController.prototype.importImageToPiskel_ = function () {
|
||||
if (this.importedImage_) {
|
||||
var image = this.importedImage_;
|
||||
var frames = this.createFramesFromImage(image);
|
||||
var confirmationMessage = "You are about to erase your current Piskel. " +
|
||||
"A new Piskel will be created from your picture, size : " + image.width + "x" + image.height;
|
||||
|
||||
if (window.confirm(confirmationMessage)) {
|
||||
var piskel = pskl.utils.Serializer.createPiskel([frames]);
|
||||
pskl.app.piskelController.setPiskel(piskel);
|
||||
pskl.app.animationController.setFPS(12);
|
||||
}
|
||||
|
||||
this.reset_();
|
||||
}
|
||||
};
|
||||
|
||||
ns.ImportController.prototype.createFramesFromImage = function (image) {
|
||||
var w = image.width,
|
||||
h = image.height;
|
||||
var canvas = pskl.CanvasUtils.createCanvas(w, h);
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
context.drawImage(image, 0,0,w,h,0,0,w,h);
|
||||
var imgData = context.getImageData(0,0,w,h).data;
|
||||
// Draw the zoomed-up pixels to a different canvas context
|
||||
var framesheet = [];
|
||||
var frames = [];
|
||||
for (var x=0;x<image.width;++x){
|
||||
framesheet[x] = [];
|
||||
frames[x] = [];
|
||||
for (var y=0;y<image.height;++y){
|
||||
// Find the starting index in the one-dimensional image data
|
||||
var i = (y*image.width + x)*4;
|
||||
@ -117,22 +128,13 @@
|
||||
var b = imgData[i+2];
|
||||
var a = imgData[i+3];
|
||||
if (a < 125) {
|
||||
framesheet[x][y] = "TRANSPARENT";
|
||||
frames[x][y] = "TRANSPARENT";
|
||||
} else {
|
||||
framesheet[x][y] = this.rgbToHex_(r,g,b);
|
||||
frames[x][y] = this.rgbToHex_(r,g,b);
|
||||
}
|
||||
}
|
||||
}
|
||||
var confirmationMessage = "You are about to erase your current Piskel. " +
|
||||
"A new Piskel will be created from your picture, size : " + w + "x" + h;
|
||||
|
||||
if (window.confirm(confirmationMessage)) {
|
||||
var piskel = pskl.utils.Serializer.createPiskel([framesheet]);
|
||||
pskl.app.piskelController.setPiskel(piskel);
|
||||
pskl.app.animationController.setFPS(12);
|
||||
}
|
||||
|
||||
this.reset_();
|
||||
return frames;
|
||||
};
|
||||
|
||||
ns.ImportController.prototype.rgbToHex_ = function (r, g, b) {
|
||||
|
@ -1,10 +1,10 @@
|
||||
<div class="layers-list-container">
|
||||
<h3 class="layers-title">Layers</h3>
|
||||
<div class="layers-button-container">
|
||||
<button class="layers-button" data-action="add" >Add</button>
|
||||
<button class="layers-button" data-action="delete" >Delete</button>
|
||||
<button class="layers-button layers-button-arrow" data-action="up" >↑</button>
|
||||
<button class="layers-button layers-button-arrow" data-action="down" >↓</button>
|
||||
<button class="button layers-button" data-action="add" >Add</button>
|
||||
<button class="button layers-button" data-action="delete" >Delete</button>
|
||||
<button class="button layers-button layers-button-arrow" data-action="up" >↑</button>
|
||||
<button class="button layers-button layers-button-arrow" data-action="down" >↓</button>
|
||||
</div>
|
||||
<script type="text/template" id="layer-item-template">
|
||||
<li class="layer-item" data-layer-name="{{layername}}">{{layername}}</li>
|
||||
|
@ -4,19 +4,24 @@
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<form action="" method="POST" name="import-form">
|
||||
<div>
|
||||
<input type="radio" name="upload-source-type" checked="checked " value="FILE"/>
|
||||
<label>From your computer :
|
||||
<input type="file" name="file-upload-input" value="file" />
|
||||
<div class="import-section">
|
||||
<input style="display:none" type="file" name="file-upload-input" value="file" />
|
||||
<label>File :
|
||||
<button type="button" class="button file-input-button">Browse</button>
|
||||
<span class="file-input-status"></span>
|
||||
</div>
|
||||
<div class="import-section">
|
||||
<label>Size :
|
||||
<input type="text" class="textfield import-resize-field" name="resize-width"/>x
|
||||
<input type="text" class="textfield import-resize-field" name="resize-height"/>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="upload-source-type" value="URL"/>
|
||||
<label>From the web :
|
||||
<input type="text" name="url-input" placeholder="url"/>
|
||||
<div class="import-section">
|
||||
<label>Smooth resize :
|
||||
<input type="checkbox" checked="checked" name="smooth-resize-checkbox"/>
|
||||
</label>
|
||||
</div>
|
||||
<input type="submit" class="export-gif-upload-button" value="Import" />
|
||||
<input type="submit" class="button import-button" value="Import" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user