Hey!
I’m trying to make a script that listens for changes to a sprite, then updates a special layer with an outlined version of it. Here’s the code:
-------------------------------------------
-- aseprite make outline layer
--
-- Creates a layer called "Outline" if there isn't one already
-- and for each frame of the current sprite, creates a filled
-- outline of it on this layer.
-------------------------------------------
local spr = app.sprite
-- Checks for a valid sprite
if not spr then
app.alert("There is no sprite")
return
end
function MakeOutlines(spr)
local self = {}
self.spr = spr
self.listener = nil
self.create_layer = function()
-- does the outline layer exist
local outline_layer = nil
for i,layer in ipairs(spr.layers) do
if layer.name == "AutoOutline" then
outline_layer = layer
break
end
end
if not outline_layer then
app.command.NewLayer{name="AutoOutline"}
end
for i,layer in ipairs(spr.layers) do
if layer.name == "AutoOutline" then
outline_layer = layer
break
end
end
return outline_layer
end
self.on_change = function(_)
--spr.events:off(self.listener)
local prev_layer = app.layer
local outline_layer = nil
for i,layer in ipairs(spr.layers) do
if layer.name == "AutoOutline" then
outline_layer = layer
end
end
if not outline_layer then create_layer() end
--app.command.clearCel(self.outline_layer:cel(app.frame.frameNumber))
spr:newCel(outline_layer, app.frame.frameNumber)
for i,layer in ipairs(spr.layers) do
if layer ~= outline_layer then
app.layer = layer
spr.selection:selectAll()
app.command.Copy()
app.layer = outline_layer
app.command.Paste()
end
end
print("complete")
spr.selection:deselect()
app.layer = prev_layer
--self.listener = spr.events:on('change', self.on_change)
end
self.start = function()
self.outline_layer = self.create_layer()
self.listener = spr.events:on('change', self.on_change)
end
return self
end
-- make an instance of it
local outliner = MakeOutlines(spr)
app.transaction(
function()
outliner.start()
end)
When I run this it works, that is, the current frame is copied to a new layer called AutoOutline. However, any subsequent action either crashes the app or brings up the error about being unable to modify the sprite because it’s in use by the script. “complete” is printed to the console so I know it gets out of the change callback.
What gives, anyone know?