2017-05-04 15:54:56 +00:00
|
|
|
"use strict";
|
|
|
|
|
2017-05-04 23:25:41 +00:00
|
|
|
function PixelEditor(parentDiv, fmt, palette, initialData, thumbnails) {
|
|
|
|
var self = this;
|
|
|
|
var width = fmt.w;
|
|
|
|
var height = fmt.h;
|
|
|
|
|
|
|
|
function createCanvas(parent) {
|
2017-05-04 15:54:56 +00:00
|
|
|
var c = document.createElement('canvas');
|
|
|
|
c.width = width;
|
|
|
|
c.height = height;
|
2017-05-04 23:25:41 +00:00
|
|
|
if (fmt.xform) c.style.transform = fmt.xform;
|
2017-05-04 15:54:56 +00:00
|
|
|
c.classList.add("pixels");
|
|
|
|
c.classList.add("pixelated");
|
|
|
|
//canvas.tabIndex = "-1"; // Make it focusable
|
|
|
|
$(parentDiv).empty().append(c);
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateImage() {
|
|
|
|
ctx.putImageData(pixdata, 0, 0);
|
|
|
|
}
|
|
|
|
|
2017-05-18 02:33:56 +00:00
|
|
|
function commit() {
|
2017-05-04 23:25:41 +00:00
|
|
|
if (!thumbnails) return;
|
|
|
|
for (var i=0; i<thumbnails.length; i++) {
|
|
|
|
thumbnails[i].copyImageFrom(self);
|
|
|
|
}
|
2017-05-25 19:49:30 +00:00
|
|
|
initialData.set(self.getImageColors());
|
2017-05-04 23:25:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
this.copyImageFrom = function(src) {
|
|
|
|
pixints.set(src.getImageData());
|
|
|
|
updateImage();
|
|
|
|
}
|
|
|
|
|
2017-05-18 02:33:56 +00:00
|
|
|
this.getImageData = function() { return pixints.slice(0); }
|
2017-05-04 23:25:41 +00:00
|
|
|
|
2017-05-04 15:54:56 +00:00
|
|
|
function fitCanvas() {
|
|
|
|
var w = $(parentDiv).width();
|
|
|
|
var h = $(parentDiv).height();
|
2017-05-18 02:33:56 +00:00
|
|
|
if (h > w)
|
|
|
|
pixcanvas.style.height = Math.floor(h)+"px";
|
|
|
|
else
|
|
|
|
pixcanvas.style.height = Math.floor(h/2)+"px";
|
2017-05-04 15:54:56 +00:00
|
|
|
// TODO
|
|
|
|
}
|
|
|
|
this.resize = fitCanvas;
|
|
|
|
|
|
|
|
var pixcanvas = createCanvas();
|
|
|
|
var ctx = pixcanvas.getContext('2d');
|
2017-05-05 13:51:47 +00:00
|
|
|
var pixdata = ctx.createImageData(width, height);
|
2017-05-04 15:54:56 +00:00
|
|
|
var pixints = new Uint32Array(pixdata.data.buffer);
|
|
|
|
for (var i=0; i<pixints.length; i++) {
|
|
|
|
pixints[i] = initialData ? palette[initialData[i]] : palette[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
updateImage();
|
|
|
|
|
|
|
|
function revrgb(x) {
|
|
|
|
var y = 0;
|
|
|
|
y |= ((x >> 0) & 0xff) << 16;
|
|
|
|
y |= ((x >> 8) & 0xff) << 8;
|
|
|
|
y |= ((x >> 16) & 0xff) << 0;
|
|
|
|
return y;
|
|
|
|
}
|
|
|
|
|
2017-05-04 23:25:41 +00:00
|
|
|
this.createPaletteButtons = function() {
|
2017-05-04 15:54:56 +00:00
|
|
|
var span = $("#palette_group").empty();
|
|
|
|
for (var i=0; i<palette.length; i++) {
|
|
|
|
var btn = $('<button class="palbtn">');
|
|
|
|
var rgb = palette[i] & 0xffffff;
|
|
|
|
var color = "#" + hex(revrgb(rgb), 6);
|
2017-05-04 23:25:41 +00:00
|
|
|
btn.click(self.setCurrentColor.bind(this, i));
|
2017-05-04 15:54:56 +00:00
|
|
|
btn.attr('id', 'palcol_' + i);
|
|
|
|
btn.css('backgroundColor', color).text(i.toString(16));
|
|
|
|
if ((rgb & 0x808080) != 0x808080) { btn.css('color', 'white'); }
|
|
|
|
span.append(btn);
|
|
|
|
}
|
2017-05-04 23:25:41 +00:00
|
|
|
self.setCurrentColor(1);
|
2017-05-04 15:54:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function getPixelByOffset(ofs) {
|
2017-05-04 23:25:41 +00:00
|
|
|
var oldrgba = pixints[ofs] & 0xffffff;
|
2017-05-04 15:54:56 +00:00
|
|
|
for (var i=0; i<palette.length; i++) {
|
2017-05-04 23:25:41 +00:00
|
|
|
if (oldrgba == (palette[i] & 0xffffff)) return i;
|
2017-05-04 15:54:56 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getPixel(x, y) {
|
2017-05-05 13:51:47 +00:00
|
|
|
var ofs = x+y*width;
|
2017-05-04 15:54:56 +00:00
|
|
|
return getPixelByOffset(ofs);
|
|
|
|
}
|
|
|
|
|
|
|
|
function setPixel(x, y, col) {
|
2017-05-05 13:51:47 +00:00
|
|
|
if (x < 0 || x >= width || y < 0 || y >= height) return;
|
|
|
|
var ofs = x+y*width;
|
2017-05-04 15:54:56 +00:00
|
|
|
var oldrgba = pixints[ofs];
|
|
|
|
var rgba = palette[col];
|
|
|
|
if (oldrgba != rgba) {
|
|
|
|
pixints[ofs] = rgba;
|
|
|
|
updateImage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.getImageColors = function() {
|
|
|
|
var pixcols = new Uint8Array(pixints.length);
|
|
|
|
for (var i=0; i<pixints.length; i++)
|
|
|
|
pixcols[i] = getPixelByOffset(i);
|
|
|
|
return pixcols;
|
|
|
|
}
|
|
|
|
|
2017-05-04 23:25:41 +00:00
|
|
|
///
|
|
|
|
|
|
|
|
this.makeEditable = function() {
|
|
|
|
var curpalcol = -1;
|
|
|
|
setCurrentColor(1);
|
|
|
|
|
|
|
|
function getPositionFromEvent(e) {
|
|
|
|
var x = Math.floor(e.offsetX * width / pxls.width());
|
|
|
|
var y = Math.floor(e.offsetY * height / pxls.height());
|
|
|
|
return {x:x, y:y};
|
|
|
|
}
|
|
|
|
|
|
|
|
function setCurrentColor(col) {
|
|
|
|
if (curpalcol != col) {
|
|
|
|
if (curpalcol >= 0)
|
|
|
|
$("#palcol_" + curpalcol).removeClass('selected');
|
|
|
|
curpalcol = col;
|
|
|
|
$("#palcol_" + col).addClass('selected');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.setCurrentColor = setCurrentColor;
|
|
|
|
|
|
|
|
var dragcol = 1;
|
|
|
|
var dragging = false;
|
|
|
|
|
|
|
|
var pxls = $(pixcanvas);
|
|
|
|
pxls.mousedown(function(e) {
|
|
|
|
var pos = getPositionFromEvent(e);
|
|
|
|
dragcol = getPixel(pos.x, pos.y) == curpalcol ? 0 : curpalcol;
|
|
|
|
setPixel(pos.x, pos.y, curpalcol);
|
|
|
|
dragging = true;
|
2017-05-05 13:51:47 +00:00
|
|
|
pixcanvas.setCapture();
|
2017-05-04 23:25:41 +00:00
|
|
|
})
|
|
|
|
.mousemove(function(e) {
|
|
|
|
var pos = getPositionFromEvent(e);
|
|
|
|
if (dragging) {
|
|
|
|
setPixel(pos.x, pos.y, dragcol);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.mouseup(function(e) {
|
|
|
|
var pos = getPositionFromEvent(e);
|
|
|
|
setPixel(pos.x, pos.y, dragcol);
|
|
|
|
dragging = false;
|
2017-05-18 02:33:56 +00:00
|
|
|
commit();
|
2017-05-05 13:51:47 +00:00
|
|
|
pixcanvas.releaseCapture();
|
2017-05-04 23:25:41 +00:00
|
|
|
});
|
|
|
|
}
|
2017-05-18 02:33:56 +00:00
|
|
|
|
|
|
|
this.rotate = function(deg) {
|
|
|
|
console.log("rotate " + deg);
|
|
|
|
var s1 = Math.sin(deg * Math.PI / 180);
|
|
|
|
var c1 = Math.cos(deg * Math.PI / 180);
|
|
|
|
var p = self.getImageColors();
|
|
|
|
var i = 0;
|
|
|
|
for (var y=0; y<height; y++) {
|
|
|
|
for (var x=0; x<width; x++) {
|
|
|
|
var xx = x + 0.5 - width/2.0;
|
|
|
|
var yy = y + 0.5 - height/2.0;
|
|
|
|
var xx2 = xx*c1 - yy*s1 + width/2.0 - 0.5;
|
|
|
|
var yy2 = yy*c1 + xx*s1 + height/2.0 - 0.5;
|
|
|
|
var col = getPixel(Math.round(xx2), Math.round(yy2));
|
|
|
|
p[i++] = col;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
i = 0;
|
|
|
|
for (var y=0; y<height; y++) {
|
|
|
|
for (var x=0; x<width; x++) {
|
|
|
|
setPixel(x, y, p[i++]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
commit();
|
|
|
|
}
|
2017-05-04 15:54:56 +00:00
|
|
|
}
|
|
|
|
|
2017-05-04 23:25:41 +00:00
|
|
|
/////////////////
|
|
|
|
|
2017-11-21 16:15:08 +00:00
|
|
|
var pixel_re = /([0#]?)([x$%]|\d'b)([0-9a-f]+)/gi;
|
2017-05-05 13:51:47 +00:00
|
|
|
|
2017-05-04 15:54:56 +00:00
|
|
|
function parseHexBytes(s) {
|
|
|
|
var arr = [];
|
|
|
|
var m;
|
2017-05-05 13:51:47 +00:00
|
|
|
while (m = pixel_re.exec(s)) {
|
|
|
|
var n;
|
2017-11-21 16:15:08 +00:00
|
|
|
if (m[2].startsWith('%') || m[2].endsWith("b"))
|
2017-05-05 13:51:47 +00:00
|
|
|
n = parseInt(m[3],2);
|
|
|
|
else if (m[2].startsWith('x') || m[2].startsWith('$'))
|
|
|
|
n = parseInt(m[3],16);
|
2017-05-04 15:54:56 +00:00
|
|
|
else
|
2017-05-05 13:51:47 +00:00
|
|
|
n = parseInt(m[3]);
|
|
|
|
arr.push(n);
|
2017-05-04 15:54:56 +00:00
|
|
|
}
|
|
|
|
return arr;
|
|
|
|
}
|
|
|
|
|
|
|
|
function replaceHexBytes(s, bytes) {
|
|
|
|
var result = "";
|
|
|
|
var m;
|
|
|
|
var li = 0;
|
|
|
|
var i = 0;
|
2017-05-05 13:51:47 +00:00
|
|
|
while (m = pixel_re.exec(s)) {
|
|
|
|
result += s.slice(li, pixel_re.lastIndex - m[0].length);
|
|
|
|
li = pixel_re.lastIndex;
|
|
|
|
if (m[2].startsWith('%'))
|
|
|
|
result += m[1] + "%" + bytes[i++].toString(2);
|
2017-11-21 16:15:08 +00:00
|
|
|
else if (m[2].endsWith('b'))
|
|
|
|
result += m[1] + m[2] + bytes[i++].toString(2); // TODO
|
2017-05-05 13:51:47 +00:00
|
|
|
else if (m[2].startsWith('x'))
|
|
|
|
result += m[1] + "x" + hex(bytes[i++]);
|
|
|
|
else if (m[2].startsWith('$'))
|
|
|
|
result += m[1] + "$" + hex(bytes[i++]);
|
2017-05-04 15:54:56 +00:00
|
|
|
else
|
2017-05-05 13:51:47 +00:00
|
|
|
result += m[1] + bytes[i++].toString();
|
2017-05-04 15:54:56 +00:00
|
|
|
}
|
|
|
|
result += s.slice(li);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-05-08 11:58:45 +00:00
|
|
|
function remapBits(x, arr) {
|
|
|
|
if (!arr) return x;
|
|
|
|
var y = 0;
|
|
|
|
for (var i=0; i<arr.length; i++) {
|
|
|
|
var s = arr[i];
|
|
|
|
if (s < 0) {
|
|
|
|
s = -s-1;
|
|
|
|
y ^= 1 << s;
|
|
|
|
}
|
|
|
|
if (x & (1 << i)) {
|
|
|
|
y ^= 1 << s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return y;
|
|
|
|
}
|
|
|
|
|
2017-05-04 15:54:56 +00:00
|
|
|
function convertBytesToImages(bytes, fmt) {
|
|
|
|
var width = fmt.w;
|
|
|
|
var height = fmt.h;
|
2017-05-08 11:58:45 +00:00
|
|
|
var count = fmt.count || 1;
|
|
|
|
var bpp = fmt.bpp || 1;
|
|
|
|
var nplanes = fmt.np || 1;
|
2017-12-04 21:40:10 +00:00
|
|
|
var bitsperword = fmt.bpw || 8;
|
|
|
|
var bytesperline = fmt.sl || Math.ceil(width * bpp / bitsperword);
|
2017-05-04 23:25:41 +00:00
|
|
|
var mask = (1 << bpp)-1;
|
2017-05-25 19:49:30 +00:00
|
|
|
var pofs = fmt.pofs || bytesperline*height*count;
|
2017-05-04 15:54:56 +00:00
|
|
|
var images = [];
|
|
|
|
for (var n=0; n<count; n++) {
|
|
|
|
var imgdata = [];
|
|
|
|
for (var y=0; y<height; y++) {
|
2017-05-08 11:58:45 +00:00
|
|
|
var ofs0 = n*bytesperline*height + y*bytesperline;
|
2017-05-04 15:54:56 +00:00
|
|
|
var shift = 0;
|
|
|
|
for (var x=0; x<width; x++) {
|
|
|
|
var color = 0;
|
2017-05-08 11:58:45 +00:00
|
|
|
var ofs = remapBits(ofs0, fmt.remap);
|
2017-05-04 15:54:56 +00:00
|
|
|
for (var p=0; p<nplanes; p++) {
|
2017-05-25 19:49:30 +00:00
|
|
|
var byte = bytes[ofs + p*pofs];
|
2017-12-04 21:40:10 +00:00
|
|
|
color |= ((fmt.brev ? byte>>(bitsperword-shift-bpp) : byte>>shift) & mask) << (p*bpp);
|
2017-05-04 15:54:56 +00:00
|
|
|
}
|
|
|
|
imgdata.push(color);
|
2017-05-04 23:25:41 +00:00
|
|
|
shift += bpp;
|
2017-12-04 21:40:10 +00:00
|
|
|
if (shift >= bitsperword) {
|
2017-05-08 11:58:45 +00:00
|
|
|
ofs0 += 1;
|
2017-05-04 15:54:56 +00:00
|
|
|
shift = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-05-25 19:49:30 +00:00
|
|
|
images.push(new Uint8Array(imgdata));
|
2017-05-04 15:54:56 +00:00
|
|
|
}
|
|
|
|
return images;
|
|
|
|
}
|
|
|
|
|
|
|
|
function convertImagesToBytes(images, fmt) {
|
|
|
|
var width = fmt.w;
|
|
|
|
var height = fmt.h;
|
2017-05-08 11:58:45 +00:00
|
|
|
var count = fmt.count || 1;
|
|
|
|
var bpp = fmt.bpp || 1;
|
|
|
|
var nplanes = fmt.np || 1;
|
2017-12-04 21:40:10 +00:00
|
|
|
var bitsperword = fmt.bpw || 8;
|
|
|
|
var bytesperline = fmt.sl || Math.ceil(fmt.w * bpp / bitsperword);
|
2017-05-04 23:25:41 +00:00
|
|
|
var mask = (1 << bpp)-1;
|
2017-05-25 19:49:30 +00:00
|
|
|
var pofs = fmt.pofs || bytesperline*height*count;
|
2017-12-04 21:40:10 +00:00
|
|
|
var bytes;
|
|
|
|
if (bitsperword <= 8)
|
|
|
|
bytes = new Uint8Array(bytesperline*height*count*nplanes);
|
|
|
|
else
|
|
|
|
bytes = new Uint32Array(bytesperline*height*count*nplanes);
|
2017-05-04 15:54:56 +00:00
|
|
|
for (var n=0; n<count; n++) {
|
|
|
|
var imgdata = images[n];
|
2017-05-04 23:25:41 +00:00
|
|
|
var i = 0;
|
2017-05-04 15:54:56 +00:00
|
|
|
for (var y=0; y<height; y++) {
|
2017-05-08 11:58:45 +00:00
|
|
|
var ofs0 = n*bytesperline*height + y*bytesperline;
|
2017-05-04 15:54:56 +00:00
|
|
|
var shift = 0;
|
|
|
|
for (var x=0; x<width; x++) {
|
|
|
|
var color = imgdata[i++];
|
2017-05-08 11:58:45 +00:00
|
|
|
var ofs = remapBits(ofs0, fmt.remap);
|
2017-05-04 15:54:56 +00:00
|
|
|
for (var p=0; p<nplanes; p++) {
|
2017-05-04 23:25:41 +00:00
|
|
|
var c = (color >> (p*bpp)) & mask;
|
2017-12-04 21:40:10 +00:00
|
|
|
bytes[ofs + p*pofs] |= (fmt.brev ? (c << (bitsperword-shift-bpp)) : (c << shift));
|
2017-05-04 15:54:56 +00:00
|
|
|
}
|
2017-05-04 23:25:41 +00:00
|
|
|
shift += bpp;
|
2017-12-04 21:40:10 +00:00
|
|
|
if (shift >= bitsperword) {
|
2017-05-08 11:58:45 +00:00
|
|
|
ofs0 += 1;
|
2017-05-04 15:54:56 +00:00
|
|
|
shift = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return bytes;
|
|
|
|
}
|
|
|
|
|
|
|
|
function convertPaletteBytes(arr,r0,r1,g0,g1,b0,b1) {
|
|
|
|
var result = [];
|
|
|
|
for (var i=0; i<arr.length; i++) {
|
|
|
|
var d = arr[i];
|
|
|
|
var rgb = 0xff000000;
|
|
|
|
rgb |= ((d >> r0) & ((1<<r1)-1)) << (0+8-r1);
|
|
|
|
rgb |= ((d >> g0) & ((1<<g1)-1)) << (8+8-g1);
|
|
|
|
rgb |= ((d >> b0) & ((1<<b1)-1)) << (16+8-b1);
|
|
|
|
result.push(rgb);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-05-10 02:43:42 +00:00
|
|
|
var palette;
|
|
|
|
var paletteSets;
|
|
|
|
var paletteSetIndex=0;
|
2017-05-04 15:54:56 +00:00
|
|
|
var currentPixelEditor;
|
|
|
|
var parentSource;
|
|
|
|
var parentOrigin;
|
|
|
|
var allimages;
|
|
|
|
var currentFormat;
|
|
|
|
var currentByteStr;
|
|
|
|
var currentPaletteStr;
|
|
|
|
var currentPaletteFmt;
|
2017-05-04 23:25:41 +00:00
|
|
|
var allthumbs;
|
2017-05-04 15:54:56 +00:00
|
|
|
|
2017-05-05 13:51:47 +00:00
|
|
|
function pixelEditorDecodeMessage(e) {
|
2017-05-04 15:54:56 +00:00
|
|
|
parentSource = e.source;
|
|
|
|
parentOrigin = e.origin;
|
|
|
|
currentFormat = e.data.fmt;
|
|
|
|
currentByteStr = e.data.bytestr;
|
|
|
|
currentPaletteFmt = e.data.palfmt;
|
|
|
|
currentPaletteStr = e.data.palstr;
|
|
|
|
var bytes = parseHexBytes(e.data.bytestr);
|
|
|
|
allimages = convertBytesToImages(bytes, e.data.fmt);
|
2017-05-04 23:25:41 +00:00
|
|
|
palette = [0xff000000, 0xffffffff]; // TODO
|
2017-05-04 15:54:56 +00:00
|
|
|
if (currentPaletteStr) {
|
|
|
|
var palbytes = parseHexBytes(e.data.palstr);
|
2017-05-21 21:34:57 +00:00
|
|
|
var pal = currentPaletteFmt.pal;
|
|
|
|
if (pal > 0) {
|
|
|
|
var rr = Math.floor(Math.abs(pal/100) % 10);
|
|
|
|
var gg = Math.floor(Math.abs(pal/10) % 10);
|
|
|
|
var bb = Math.floor(Math.abs(pal) % 10);
|
|
|
|
// TODO: n
|
|
|
|
if (currentPaletteFmt.pal >= 0)
|
|
|
|
palette = convertPaletteBytes(palbytes, 0, rr, rr, gg, rr+gg, bb);
|
|
|
|
else
|
|
|
|
palette = convertPaletteBytes(palbytes, rr+gg, bb, rr, gg, 0, rr);
|
|
|
|
} else {
|
|
|
|
var paltable = PREDEF_PALETTES[pal];
|
|
|
|
if (paltable) {
|
|
|
|
palette = palbytes.map(function(i) { return paltable[i]; });
|
|
|
|
} else {
|
|
|
|
alert("No palette named " + pal);
|
|
|
|
}
|
|
|
|
}
|
2017-05-10 02:43:42 +00:00
|
|
|
if (currentPaletteFmt.n) {
|
|
|
|
paletteSets = [];
|
|
|
|
for (var i=0; i<palette.length; i+=currentPaletteFmt.n) {
|
|
|
|
paletteSets.push(palette.slice(i, i+currentPaletteFmt.n));
|
|
|
|
}
|
|
|
|
palette = paletteSets[paletteSetIndex = 0];
|
|
|
|
// TODO: swap palettes
|
|
|
|
}
|
2017-05-04 23:25:41 +00:00
|
|
|
} else {
|
2017-05-25 19:49:30 +00:00
|
|
|
var ncols = (currentFormat.bpp || 1) * (currentFormat.np || 1);
|
2017-05-21 21:34:57 +00:00
|
|
|
switch (ncols) {
|
|
|
|
case 2:
|
2017-05-25 19:49:30 +00:00
|
|
|
palette = [0xff000000, 0xffff00ff, 0xffffff00, 0xffffffff];
|
2017-05-21 21:34:57 +00:00
|
|
|
break;
|
|
|
|
// TODO
|
|
|
|
}
|
2017-05-04 23:25:41 +00:00
|
|
|
// TODO: default palette?
|
|
|
|
}
|
|
|
|
palette = new Uint32Array(palette);
|
2017-05-05 13:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function pixelEditorCreateThumbnails(e) {
|
2017-05-04 23:25:41 +00:00
|
|
|
// create thumbnail for all images
|
|
|
|
$("#thumbnaildiv").empty();
|
|
|
|
var parentdiv;
|
|
|
|
var count = e.data.fmt.count || 1;
|
|
|
|
allthumbs = [];
|
|
|
|
for (var i=0; i<count; i++) {
|
|
|
|
if ((i & 15) == 0) {
|
|
|
|
parentdiv = $("#thumbnaildiv").append("<div>");
|
|
|
|
}
|
|
|
|
allthumbs.push(createThumbnailForImage(parentdiv, i));
|
2017-05-04 15:54:56 +00:00
|
|
|
}
|
2017-05-05 13:51:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function pixelEditorReceiveMessage(e) {
|
|
|
|
pixelEditorDecodeMessage(e);
|
|
|
|
pixelEditorCreateThumbnails(e);
|
2017-05-04 23:25:41 +00:00
|
|
|
// create initial editor
|
|
|
|
createEditorForImage(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
function createThumbnailForImage(parentdiv, i) {
|
|
|
|
var span = $('<span class="thumb">');
|
|
|
|
var thumb = new PixelEditor(span, currentFormat, palette, allimages[i]);
|
|
|
|
parentdiv.append(span);
|
|
|
|
span.click(function() { createEditorForImage(i) });
|
|
|
|
return thumb;
|
|
|
|
}
|
|
|
|
|
|
|
|
function createEditorForImage(i) {
|
|
|
|
currentPixelEditor = new PixelEditor(maineditor, currentFormat, palette, allimages[i], [allthumbs[i]]);
|
|
|
|
currentPixelEditor.resize();
|
|
|
|
currentPixelEditor.makeEditable();
|
|
|
|
currentPixelEditor.createPaletteButtons();
|
2017-05-04 15:54:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function postToParentWindow(data) {
|
|
|
|
if (data.save) {
|
2017-05-04 23:25:41 +00:00
|
|
|
var allimgs = [];
|
|
|
|
for (var i=0; i<allthumbs.length; i++) {
|
|
|
|
allimgs.push(allthumbs[i].getImageColors());
|
|
|
|
}
|
|
|
|
data.bytes = convertImagesToBytes(allimgs, currentFormat);
|
2017-05-04 15:54:56 +00:00
|
|
|
data.bytestr = replaceHexBytes(currentByteStr, data.bytes);
|
|
|
|
}
|
2017-05-04 23:25:41 +00:00
|
|
|
if (parentSource) parentSource.postMessage(data, "*");
|
|
|
|
return data;
|
2017-05-04 15:54:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function pixelEditorResize(e) {
|
|
|
|
if (currentPixelEditor) {
|
|
|
|
currentPixelEditor.resize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function pixelEditorKeypress(e) {
|
|
|
|
if (!currentPixelEditor) return;
|
|
|
|
var c = e.charCode;
|
|
|
|
if (c >= 48 && c <= 57) {
|
|
|
|
currentPixelEditor.setCurrentColor(c-48);
|
|
|
|
} else if (c >= 97 && c <= 102) {
|
|
|
|
currentPixelEditor.setCurrentColor(c-97+10);
|
2017-05-18 02:33:56 +00:00
|
|
|
} else {
|
|
|
|
switch (e.keyCode) {
|
|
|
|
case 33: // PgUp
|
|
|
|
currentPixelEditor.rotate(-90);
|
|
|
|
break;
|
|
|
|
case 34: // PgDn
|
|
|
|
currentPixelEditor.rotate(90);
|
|
|
|
break;
|
|
|
|
case 35: // PgUp
|
|
|
|
currentPixelEditor.rotate(-45);
|
|
|
|
break;
|
|
|
|
case 36: // PgDn
|
|
|
|
currentPixelEditor.rotate(45);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
console.log(e);
|
|
|
|
break;
|
|
|
|
}
|
2017-05-04 15:54:56 +00:00
|
|
|
}
|
|
|
|
}
|
2017-05-21 21:34:57 +00:00
|
|
|
|
|
|
|
var PREDEF_PALETTES = {
|
|
|
|
'nes':[
|
|
|
|
0xFF7C7C7C ,0xFF0000FC ,0xFF0000BC ,0xFF4428BC ,0xFF940084 ,0xFFA80020 ,0xFFA81000 ,0xFF881400
|
|
|
|
,0xFF503000 ,0xFF007800 ,0xFF006800 ,0xFF005800 ,0xFF004058 ,0xFF000000 ,0xFF000000 ,0xFF000000
|
|
|
|
,0xFFBCBCBC ,0xFF0078F8 ,0xFF0058F8 ,0xFF6844FC ,0xFFD800CC ,0xFFE40058 ,0xFFF83800 ,0xFFE45C10
|
|
|
|
,0xFFAC7C00 ,0xFF00B800 ,0xFF00A800 ,0xFF00A844 ,0xFF008888 ,0xFF000000 ,0xFF000000 ,0xFF000000
|
|
|
|
,0xFFF8F8F8 ,0xFF3CBCFC ,0xFF6888FC ,0xFF9878F8 ,0xFFF878F8 ,0xFFF85898 ,0xFFF87858 ,0xFFFCA044
|
|
|
|
,0xFFF8B800 ,0xFFB8F818 ,0xFF58D854 ,0xFF58F898 ,0xFF00E8D8 ,0xFF787878 ,0xFF000000 ,0xFF000000
|
|
|
|
,0xFFFCFCFC ,0xFFA4E4FC ,0xFFB8B8F8 ,0xFFD8B8F8 ,0xFFF8B8F8 ,0xFFF8A4C0 ,0xFFF0D0B0 ,0xFFFCE0A8
|
|
|
|
,0xFFF8D878 ,0xFFD8F878 ,0xFFB8F8B8 ,0xFFB8F8D8 ,0xFF00FCFC ,0xFFF8D8F8 ,0xFF000000 ,0xFF000000
|
|
|
|
]
|
|
|
|
};
|