Skip to content

Commit 19e5eca

Browse files
committed
Merge pull request #39 from STRd6/bitblat
bitblat
2 parents fed64f3 + c17e0b2 commit 19e5eca

14 files changed

+534
-668
lines changed

TODO.md

Lines changed: 102 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,90 @@
11
TODO
22
====
33

4-
Transparancy Mode (index 0 or none)
4+
Opacity/Alpha
5+
6+
Polishing
7+
---------
8+
9+
Icons, Icon offsets for tools
10+
11+
Palette styling, editing palette colors
12+
13+
Preview window on large images
14+
15+
Thumbnail viewing mini-map rectangle
16+
17+
Responsive Design
18+
-----------------
19+
20+
Styling for mobile viewports.
21+
22+
Better Symmetry/Multi Modes
23+
---------------------------
24+
25+
Multiply events through symmetry so that flood fill and others
26+
can work better with symmetry modes.
27+
28+
Radial symmetry
29+
30+
Simple Replays
31+
--------------
32+
33+
Make sure replays can be saved and loaded
34+
35+
Vintage Replays
36+
---------------
37+
38+
Be able to display PixieEngine replays
39+
40+
Brush Options
41+
-------------
42+
43+
Should symmetry be a per-brush option, along with brush sizes, etc?
44+
45+
Memory Usage
46+
------------
47+
48+
Reduce memory usage in undo using dirty regions.
49+
50+
Platforms
51+
---------
52+
53+
Chrome Web Store
54+
Downloadable
55+
Others?
56+
57+
Promotional Media
58+
-----------------
59+
60+
Screenshots
61+
Promo images
62+
63+
Documentation
64+
-------------
65+
66+
Manual
67+
Tutorials
68+
Plugins
569

670
Bugs
771
----
872

73+
Eraser
74+
975
V2
10-
----
76+
====
77+
78+
True replays
79+
------------
80+
81+
Capture all user input as events, replay entire event stream.
82+
83+
Minimize Memory Footprint
84+
-------------------------
85+
86+
Use quadtrees for diffing regions in undo stack.
1187

12-
Selection Tool
1388

1489
Hot reload editor state / initial editor state
1590

@@ -19,8 +94,6 @@ Autosave
1994

2095
Analytics
2196

22-
Better Circle/Ellipse Tool
23-
2497
Layers
2598
Reorder Layers
2699
Delete Layers
@@ -50,6 +123,30 @@ Display transparent preview as transparent instead of white
50123

51124
Done
52125
====
126+
127+
Color Picker
128+
129+
Better performance
130+
------------------
131+
132+
Use true size canvas, not enlarged canvas. Avoid lots of pixel manipulation and
133+
let the canvas drawing functions do the work for us. Blit the 'work' canvas onto
134+
the active layer when the command completes.
135+
136+
Never call `repaint` on the whole editor, all the layers should always paint
137+
themselves, and only the regions necessary should be repainted.
138+
139+
Operate directly on imageData arrays where possible.
140+
141+
Better Circle Tool
142+
------------------
143+
144+
Calculate midpoint of [start, end], use that as center and radius as length/2
145+
146+
Selection Tool
147+
148+
Transparancy Mode (index 0 or none)
149+
53150
Prompt unsaved on exit
54151

55152
Palette

actions.coffee.md

Lines changed: 15 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -79,30 +79,23 @@ Actions
7979
8080
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACs0lEQVQ4T42SS0hUURjH/2fGO2MPTC3p6VQudBEt1Bm1UWgXCEW0LNpIlk5WYoq2UYseFAmaYaRNAy2KApMkq5lRepChjJqaiUJp4cKyRTgzPsZp7jl954xEK+teDt/HPff/+57MWuwpE2DbDQx5AFLIXwuIGMbAIOgLPUa6NNARgkPnmDVp+BwKLV3rbz7QymwO7x1nVV4h6P+0rWalEVwgHKHziyvxKrMBBMTcIsdcSBcT03P6PfeEf+zrTBWzOjrH71bmprX5gqg6lCTlOH2jD9eLMxHhQKzGYNIMWCKYf0EnKzA5swAjOC64BpYkYNZZmbvucW8AFQc3qJTPNvXjyokMaEaKbjJQ6kBgUcd8iINTdq6uH8jPjENZY4+QgPDtCrvW7gugJH+9AlQ7B3GpMB2rY43QqITFMBU+r1NGEgACzCB9hxl1D96DAF7eVG5nT6mE4/sSFYA0WGM2UnSGiE7RKfWFsK7Egl6X9zt2W0xoeDQIZjvpFY2ldjzrD+Db9BQ1izpOAC2GGkewCKUcoWYsD0QFiI9PxC6LGU2twwRweEV9aQ6e9/lVrVKl5qcUAqSnyASgSy4P+QYKkrqJoeXJSBRQdyoH7gG/ov8ZPoFkw6RQzl+lT1ZIh8ApSQyujo9RwFVHFrqGAtGtoUu5Q9LqEiCjy0zI51xXO0IeLIkC991jEuARl4uy8Go4iNoj25YhK5uKllEkJwg87BwHy6Ymni+04c1IALWHk9Hw7tiK6lK7E+XNH7AlXqDt5ScClHhFTYEV3aNB1BDAN/V6RYAteS/Kbg1hc5xA+1sCUAm8usDKesYkwPJfGZy5OYCNBOjonpCb6Jk8dzRjp5zh/uzoKv/ruejyqQa/6P3yk1mL3PXU11QwsYcJJNDw1Oio3Wpsf1sZJDpWIRh4UDDjyG82p2waquUVyAAAAABJRU5ErkJggg=="
8181

82-
"ctrl+e":
83-
name: "Export"
84-
description: """
85-
Export image in a chunky size
86-
"""
87-
method: ({editor}) ->
88-
if name = prompt("File name", "image")
89-
if size = prompt("Pixel Size", 4)
90-
editor.outputCanvas(parseInt(size, 10)).toBlob (blob) ->
91-
saveAs blob, "#{name}.png"
92-
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACFklEQVQ4T2NkoBAwgvRHVq7o/feXMfrt138cX35hMfEfqhgXGwMDD+f/+Zv6ogrBBoSVr3rZlm4iKiYqysjIyMLwHygGwhB9jAz/gRwQhvD/M/z984shsXHHh+0TwwXBBrhkL/+wtt2HP6tvEYOUrAADO/M/hr//2RkYmPgZmIAqwBhIMAPxoxuXGdqKMhmiqjZ/3DM1TABsgFXq8g87+wP4e9fvY9CxtAUqZAba+BdoOQsQMwINYARSTEBDmBiuHD/IkOhqxRBTg2bAdqAB07YdY9C1doS4Fwe4fOwAQ4KrJUMs2IBwhAu2Ag2YvGEfg66lA9jW////MfwDuuLfPyZgKIDM/M/AzPiX4dqpIwzJXo4McbVbUQ3Y0hfAX79oCYO+kTfD779/wJo//XzJ8OuvDNgAEBBjf8/w6OZFhpyQIIa4OjQXbO4N4M/oWccgq20JUQ0OeojNyODxteMMkwqDUQ2wAAbilp4A/uwJW4AGWOH0P0ji8dVjDH053gzxyC4AGbC5O4A/ZyKZBpgnL/2wtTeIP7Swk0FMQRuvC149uMqwpLuMIbZ288d906GxYAE0YEtvIP/rH8DEAw8yXOb8Z+Bj+QU0YBPCALec5Q+XNLjLsbFxQqIQmmTBgYhhDiPDnz8/GeIbdwKTchgkKQcWr+j685fJ8vvv/7r/0DIONnewATMTJ9P/Bev7IwpgUYzX3/gkAZ2z7hEMLct4AAAAAElFTkSuQmCC"
93-
9482
"ctrl+r":
9583
name: "Resize"
9684
description: """
9785
Resize
9886
"""
9987
method: ({editor}) ->
100-
{width, height} = editor.pixelExtent()
88+
{width, height} = size = editor.pixelExtent()
10189
10290
if newSize = prompt("New Size (WxH)", "#{width}x#{height}")
10391
[width, height] = newSize.split("x").map (v) -> parseInt v, 10
10492
105-
editor.execute editor.Command.Resize({width, height})
93+
command = editor.Command.Resize
94+
size: {width, height}
95+
sizePrevious: size
96+
imageDataPrevious: editor.getSnapshot()
97+
98+
editor.execute command
10699
107100
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACLElEQVQ4T91Tz2sTQRR+05hmTTeB0iS7h8ZjLyEKgoVehCLWFG0g0ahrMEpp6rH++EMUFH8UUbRIq7ZZ21qoh14UjfQiQkXpQWKSJmlcyzZmY3fj7DhjGklK+g/4YBjmzX7fvve9+dC15CUCNIhJgBC66H7j8H3EcjsjvhAlJr03TRNMXNsRIzjU2UcPGJaV5K5gRibNSoKjzVrwu/cDQgiSqXeArr4dJQc7e6FS1UDRFchpWflW/8Pwzr8zsI2QVS/vdXIWDuxWHpYz7wFdeRMnFmQFgRNBtImQKqcg/zMr3x543ERyQT6reB3dXZ4OAVIb3yC3uVZrYez1CNEMTeQQt9rN73Pqhg758tqru4MTgcYqzk9H5oUO8YSJTciVcvLUOTl86tEQ+SfWCC3Rutf6iYqUvBeYGGolojQVXqQiVxi4ft9S7Vbg3XL/G0FsJpLA2LQ/OT3TNIF6/8HxwXmCcV9Fx76ly0vrLI+G5yTyIDiJGNjFeUJstvlS/uXT6IumSQTHA4tu3nPMgiyQVjKlKiY9FiAFdFE+8/d9uzg3CHYRiloR0hvpH89js65G5Y/fGUi4HZ6Q6KTfbBZhXS2AXjUAxaYjxNflB/WXCjrWIatmSltbWs9cvFZiYwRuHknQKkLt7XuAtzlhJbUCKPrsJPG7DoDx24Av3z9DuaKKrcB1oqPX+4nP64M2aqYPXz8CkibDtAVmT7q2rSoPL7R8HwzM7G5u257Z/w969A/vqEbP0wAAAABJRU5ErkJggg=="
108101
@@ -112,12 +105,15 @@ Actions
112105
Clear image
113106
"""
114107
method: ({editor}) ->
115-
command = editor.Command.Composite()
116-
editor.execute command
108+
previous = editor.getSnapshot()
109+
editor.canvas.clear()
110+
111+
editor.execute editor.Command.PutImageData
112+
imageData: editor.getSnapshot()
113+
imageDataPrevious: previous
114+
x: 0
115+
y: 0
117116
118-
# Kind of a hack, just removing the top layer and adding a new one
119-
command.push editor.Command.RemoveLayer()
120-
command.push editor.Command.NewLayer()
121117
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAC4SURBVCjPdZFbDsIgEEWnrsMm7oGGfZrohxvU+Iq1TyjU60Bf1pac4Yc5YS4ZAtGWBMk/drQBOVwJlZrWYkLhsB8UV9K0BUrPGy9cWbng2CtEEUmLGppPjRwpbixUKHBiZRS0p+ZGhvs4irNEvWD8heHpbsyDXznPhYFOyTjJc13olIqzZCHBouE0FRMUjA+s1gTjaRgVFpqRwC8mfoXPPEVPS7LbRaJL2y7bOifRCTEli3U7BMWgLzKlW/CuebZPAAAAAElFTkSuQmCC"
122118
123119
"+":
@@ -151,52 +147,6 @@ Actions
151147
editor.grid.toggle()
152148
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAM0lEQVQ4T2NkoBAwUqifAZsB/4GGIovj5VPVAJBNpAJGqroAZvtoGDAwjIYBFcKApOQMANUmIRHQ0q3yAAAAAElFTkSuQmCC"
153149
154-
"t":
155-
name: "Transparency Mode"
156-
description: """
157-
Toggle palette 0 transparent
158-
"""
159-
method: ({editor}) ->
160-
editor.execute editor.Command.ChangeTransparencyMode()
161-
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA2ElEQVQ4T2NkAIKs6cejGZkY6qamW6pnzzjWxsDIED813UoaFztr5rEKoDauaelWdYxZM45mMTIy5ROrGWTofwbGmGkZlnKZ0454MmbPPPYQaJs8MTYjq8maebwF6AojRpAXSNWMrJ6REs0gV4C88BRfgBGyYGC9AHLdqBcY4imPhcwZR8uZGBmzyEnOmTOOVTJmTT+aOi3TejY4VTH8TyQ2UQFzZO3///9/Qb1wxIuBgalmaoaVFWbKY4wF5lTZ7BlHaxgYGcOAFuhlzTxazPifSXRqhmUFAKiWXyIxiUtgAAAAAElFTkSuQmCC"
162-
163-
"ctrl+shift+p":
164-
name: "Load Palette"
165-
description: """
166-
Load a JASC-PAL palette file (max 32 colors)
167-
"""
168-
method: ({editor}) ->
169-
Modal.show FileReading.readerInput
170-
accept: "*/*"
171-
image: (dataURL) ->
172-
# TODO: Load palette from image
173-
json: (data) ->
174-
# TODO: Load json palette
175-
alert "Unknown palette type"
176-
text: (text) ->
177-
if palette = Palette.load(text)
178-
# TODO: Check if palette is different from current palette
179-
editor.execute editor.Command.ChangePalette
180-
palette: palette
181-
else
182-
# TODO: Unknown palette type
183-
184-
chose: ->
185-
Modal.hide()
186-
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC/UlEQVQ4T4WTW0gUYRTH/98s4+66umYGdjHSXLesyMi18qEg7EHKsB6kIunBHoJuFBj4YNBDBEFBUUmUQS1FpaRlCEEldiEybdcSzLVMLc3bquvsdcaZ+Tq70eXBapgzhxm+8/v+3/+cYfjPdbhobVZ6WsqBOckJBeCaNioFnnweGrtWVe/6EC1l/6o/sWdjWVZa6nH7Ult66nwOcCu8I2H09XqGOvqGTje0N1f9DSBcPFLsXLYoaeeKhUbD7EwNhhQPdMWEqa+l0ONEfOpq1eqaWnfOCDh3cHP1Bkf+3uVzfWCyGxoXIGYbEJzWUT3AYTaYsU0vRFPri0czAmorS4JbwsnxPCCBFcrgphTIYj4GfR14au1A3DRDiboJ7n7PF+Z5uLrdaF2+jDHhlx3vngligV+EHg4hWFyArs4WyWoxipibbT78LQkWTcHtWR64vcOTrLvBEbEVtRgZIzHkU/TRcGovVq1bjwRRx4RPQpurUY8XBBafU8IqxtJgUQO4P9sN99iIn3Xfy/XZil8mKcNV0BQDIFjR3PgWSkCBqEewMicXfp8XokGASYng9aAX6fPSkJpowKN3rjvMczdPsm1/khgZcILrHLo8gfBoL4Kj41BHh//a5TYp403N444dBMhVFm9tFCddlyCP9FCrQjAYkzCv6AwNCcPAx3aYtBDMogmqNg1ZsEB6Wo6K+mB6XdOHfua5mafYd7eQYwrtppMFnJT4oUqvoEd6IctBjA/5ACrmLIRk+zF4a0thP9QW6yDzXHfIWaXP4/TQe5pUH4WfCvsIpNMdIWaYcoC+R4OUZJxHz9WtvwHdlx2RzLImo+ZvBlenaBGFSjtylYJmQAv+gKpSLFvsTvRcKfoDcMERtu17bJqefBArjEUM8hPmp/doMYFIkWXJLfTe2B+hI5hjR+g6u/rb4rKaeGWiJZG0C5xHZVNQ5ppMWSFbKEc94hqMC3bxfudRaUm5a1YM0Hky+wgThDWMs01gPPGff3d00BgUarczu7LzUHTtd5jOkNp6KQ05AAAAAElFTkSuQmCC"
187-
188-
"ctrl+shift+e":
189-
name: "Edit Palette"
190-
description: """
191-
Edit the color palette
192-
"""
193-
method: ({editor}) ->
194-
# Show palette editor text
195-
# Live update palette in image
196-
197-
$(".palette-editor").removeClass("hide").find("textarea").val editor.palette().join("\n")
198-
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADlElEQVQ4T1WTDWyTRRjH/9e3b/t27fr9sWqXNtRUKZDsgy3tCGY6cHVEqQnoxqZBFxUN6FA0JmiCSiAYFseysAwxI0jQqCSiRgMMMzUsBYENhmHTObdpG5d268fWdf16z2sjJF7y3JPcXX733P+5P8F/Y9vnk7UcuC6nTuFdyoooRFYUkcrm45SQBUJphB3NUyDK8hwF/eR2NHKe3AG0np7YVWFVd++pN91ZKuZkhsFYRJfzyGSBRDqPqcgivptIzlMx33EX0HJybH+dPr13dSqA6MzvAKFQlLngrNkAS7kDMgnASSTgOWA5RxH4cwnHAqHwXcCudw4MeIRQg6tcC8s9rFCqRmQ2heDsLHjXw3DXPQ4Jx+FeDYeOE9P4oM2OzoEpFACSno7NJ9127bbV5TKid+bBGcYhZgTE/2qDKOMxOX4dc7ZHcV/FQ1hh4vD6x6Pwr7ehZ3A6RLp2Nh1/cK23fVVZDCQ9zFRiZa7kkGQiHv+bPYNTwC/6cCUUh+ORPVhj5dHWdRUpqZgQRbqFfPH21uSmlK6ELiZAfGlQwYA070UwNoqL6lHIsgRbcxswEo6gdONBVNukaD16GfG5mOHcPt88+fr9Z2nDAg8xtYTk5gaMTdyEWi4FzE68EtJAmc/gU+04huMJqBo/RCUDNHf9iEQ4qx04tDFOzu7fTis866HiRczHEvj51ymo6CJ0qzx4K2yDMreIr/TDGI7GoW7qhttC4D94PndhX5OM6UdJ987G02ql4NWoVI7q6hosxCKsVRIImWUEghE4rDZYSjkMxRVY49sNtSyD7Z0Xgj8c8NsK/6TYRt/z79UYjaYrzdoheKvqkJoeZc1egkpvxjzbv55gwModcK8oRzQexe7egV9+6myuLQKqX+gzyuUlvU/UV225P3URDgRhVunZD0zin2gYf3B2mKpaYDJb4dBxuDYexLsnBr8d6n7msSLA8+JHT4FI+h02s8JuMcIZ/xJ6aQo3F6yYog8go1oJkVLoNRq81FiGkduTOHrmUv/lvvbnioC17b2H/PUVb+5t8/zPAwXXZNmUyRWkAnq+D+HJdWacG7qF/m8Ch6/1v/xGEVD59JEd66pcvbVuO7QqBbQaATqlHBoWpSUyyJkJ5FIJZuZyLAN9Zy7h7OCNjpFTrx4pAlwth40COOYqaieEGCilBgKiY9fqQIhGkPG8IPBQKxlcXYIbYzO/scJab3322tUC4F+pz2ZaFmudeAAAAABJRU5ErkJggg=="
199-
200150
"f5":
201151
name: "Replay"
202152
description: """

command.coffee.md

Lines changed: 6 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -27,63 +27,19 @@ versions.
2727
2828
return command
2929
30-
C "ChangePalette", (data) ->
31-
data.previous ?= self.palette()
32-
33-
execute: ->
34-
self.palette data.palette
35-
36-
undo: ->
37-
self.palette data.previous
38-
39-
C "ChangePixel", (data) ->
40-
data.previous ?= self.getPixel(data).index
41-
42-
execute: ->
43-
self.changePixel(data)
44-
45-
undo: ->
46-
self.changePixel extend {}, data, index: data.previous
47-
48-
C "ChangeTransparencyMode", (data) ->
49-
data.previous ?= self.paletteZeroTransparent()
50-
51-
execute: ->
52-
self.paletteZeroTransparent !data.previous
53-
54-
undo: ->
55-
self.paletteZeroTransparent data.previous
56-
5730
C "Resize", (data) ->
58-
{width, height, state} = data
59-
60-
data.previous ?= self.pixelExtent()
61-
62-
state ?= self.layerState()
63-
6431
execute: ->
65-
self.resize(data)
32+
self.resize(data.size, data.imageData)
6633
6734
undo: ->
68-
self.restoreLayerState state
35+
self.resize(data.sizePrevious, data.imageDataPrevious)
6936
70-
C "NewLayer", (data) ->
37+
C "PutImageData", (data) ->
38+
# TODO: Layers?
7139
execute: ->
72-
self.newLayer(data)
73-
74-
undo: ->
75-
# TODO: May need to know layer index and previously active layer
76-
# index
77-
self.removeLayer(data)
78-
79-
C "RemoveLayer", (data) ->
80-
data.previous ?= self.layer().toJSON()
81-
82-
execute: ->
83-
self.removeLayer()
84-
40+
self.putImageData(data.imageData, data.x, data.y)
8541
undo: ->
86-
self.newLayer(data.previous)
42+
self.putImageData(data.imageDataPrevious, data.x, data.y)
8743
8844
C "Composite", (data) ->
8945
if data.commands

0 commit comments

Comments
 (0)