9Slice [Problem]


--# Main
-- 9Slicd

-- Use this function to perform your initial setup
function setup()
    p = vec2(WIDTH/2,HEIGHT/2)
    o = p
    size = vec2(125,125)
    m = mesh()
    r = m:addRect(p.x,p.y,size.x,size.y)
    img = image(125,125)
    pushStyle()
    setContext(img)
    fill(100, 255, 0, 255)
    rect(0,0,25,25)
    fill(0, 144, 255, 255)
    rect(25,25,75,75)
    fill(246, 0, 255, 255)
    rect(25,0,75,25)
    fill(8, 227, 139, 255)
    rect(0,25,25,75)
    setContext()
    popStyle()
    m.texture = getTexture(img)
end


function touched(t)
    size = vec2(math.abs(t.x-o.x),math.abs(t.y-o.y))*2
    m.texture = getTexture(img)
    m:setRect(r,p.x,p.y,size.x,size.y)
end
-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(40, 40, 50)

    -- This sets the line thickness
    strokeWidth(5)

    -- Do your drawing here
    m:draw()
end

function getTexture(tex)
    local img = tex
    local s = vec2(size.x,size.y)
    local si = vec2(img.width,img.height)
    --if s.x<si.x-75 or s.y<si.y-75 then return img end
    local corners = {vec2(0,0),vec2(0,125),vec2(125,125),vec2(125,0)}
    local faces = {vec2(62.5,0),vec2(0,62.5),vec2(62.5,125),vec2(125,62.5)}
    local fa = {vec2(0,12.5),vec2(12.5,0),vec2(0,-12.5),vec2(-12.5,0)}
    local ca = {vec2(12.5,12.5),vec2(12.5,-12.5),vec2(-12.5,-12.5),vec2(-12.5,12.5)}
    
    pushStyle()
    pushMatrix()
    local bimg = image(75,75)
    setContext(bimg)
    sprite(tex,si.x/2-25,si.y/2-25)
    setContext()
    local cimg = image(25,25)
    setContext(cimg)
    sprite(tex,si.x/2,si.y/2)
    setContext()
    local mimg = image(75,25)
    setContext(mimg)
    sprite(tex,si.x/2-25,si.y/2)
    setContext()
    local imgt = image(s.x,s.y)
    local xd,yd = (s.x/si.x),(s.y/si.y)
    setContext(imgt)
        sprite(bimg,s.x/2,s.y/2,s.x-50,s.y-50)
        for k,d in pairs(corners) do
            local v = vec2(d.x*xd,d.y*yd)+ca[k]
            translate(v.x,v.y)
            rotate((k-1)*-90)
            sprite(cimg,0,0)
            resetMatrix()
            local f = vec2(faces[k].x*xd,faces[k].y*yd)+fa[k]
            translate(f.x,f.y)
            rotate((k-1)*-90)
            if k%2==1 then
                sprite(mimg,0,0,s.x-50,25)
            else
                sprite(mimg,0,0,s.y-50,25)
            end
            resetMatrix()
        end
        
    setContext()
    popMatrix()
    popStyle()
    return imgt
end

The above code uses 9 slice (rather 1slice + 4x1slice + 4x1slice it’s only for the same cornered/sided patterns) the problem is if you make the image too large then the creation of an image every frame is too much. I’m asking for a different approach or if you have a function to deal with this then please share.

i am using this:
It wont run alone, but you can figure out how to integrate it in your code. I use meshResize to resize, it is fully real time, because the texture image is created only once.

function RRectObj:meshCreate()
    -- the rect are fake and need resizing
    local i 
    local m = mesh()
    local x0,x1,x2 = 0,0.5,0.5
    local w0,w1,w2 = 0.5,0,0.5
    local y0,y1,y2 = 0,0.5,0.5
    local h0,h1,h2 = 0.5,0,0.5
    -- bottom line
    i = m:addRect(0,0,1,1)
    m:setRectTex(i,x0,y0,w0,h0)
    i = m:addRect(0,0,1,1)
    m:setRectTex(i,x1,y0,w1,h0)
    i = m:addRect(0,0,1,1)
    m:setRectTex(i,x2,y0,w2,h0)

    -- middle line
    i = m:addRect(0,0,1,1)
    m:setRectTex(i,x0,y1,w0,h1)
    i = m:addRect(0,0,1,1)
    m:setRectTex(i,x1,y1,w1,h1)
    i = m:addRect(0,0,1,1)
    m:setRectTex(i,x2,y1,w2,h1)

    -- top line
    i = m:addRect(0,0,1,1)
    m:setRectTex(i,x0,y2,w0,h2)
    i = m:addRect(0,0,1,1)
    m:setRectTex(i,x1,y2,w1,h2)
    i = m:addRect(0,0,1,1)
    m:setRectTex(i,x2,y2,w2,h2)

    self.mesh = m

end

function RRectObj:meshResize(w,h,r,strkWidth)
    -- texture image size must be 2rx2r
    local floor, ceil, min, max = math.floor, math.ceil, math.min, math.max
    w,h = ceil(w), ceil(h)
    r = min( floor(r), floor(w/2), floor(h/2) )
    local d = r
    local x0,x1,x2 = d/2, w/2, w-d/2
    local w0,w1,w2 = d, w-2*d, d
    local y0,y1,y2 = d/2, h/2, h-d/2
    local h0,h1,h2 = d, h-2*d, d
    local i 

    local m = self.mesh
    
    -- bottom line
    i=1
    m:setRect(i,x0,y0,w0,h0)
    i=i+1
    m:setRect(i,x1,y0,w1,h0)
    i=i+1
    m:setRect(i,x2,y0,w2,h0)
    
    -- middle line
    i=i+1
    m:setRect(i,x0,y1,w0,h1)
    i=i+1
    m:setRect(i,x1,y1,w1,h1)
    i=i+1
    m:setRect(i,x2,y1,w2,h1)

    -- top line
    i=i+1
    m:setRect(i,x0,y2,w0,h2)
    i=i+1
    m:setRect(i,x1,y2,w1,h2)
    i=i+1
    m:setRect(i,x2,y2,w2,h2)
    
end

@Jmv38 Perfect. A few changes and it’s exactly what I’m looking for. Thanks!

my pleasure.