[SOLVED] Resizing a canvas

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
nyenye
Citizen
Posts: 62
Joined: Fri Dec 02, 2016 1:44 pm

[SOLVED] Resizing a canvas

Post by nyenye »

First of all say that I wanted to post this on the thread for 'Questions that don't deserve their own thread', but I found it locked. Also say that I've search for the 'canvas resize' on the forums and couldn't find the answer that I was expecting/wanted.

Question: Can you resize a Canvas without creating a new one? On the wiki there is not a single method dedicated to resizing the canvas, and doesn't mention anything about width and height fields which can be set with '=' assignation.
Last edited by nyenye on Sun Jan 22, 2017 3:42 pm, edited 1 time in total.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Resizing a canvas

Post by bartbes »

No, you'll have to create a new one. Is there a particular reason why you want to resize instead?
nyenye
Citizen
Posts: 62
Joined: Fri Dec 02, 2016 1:44 pm

Re: Resizing a canvas

Post by nyenye »

Hi thanks for the response. I'm not aware of all the ways that Canvas can be used yet, but I personally use it to draw whatever I need to draw on screen, but scaled (if needed). Then I draw the Canvas centered leaving blank bars on the sides (or top/bottom, depending of the aspect ratio and window dimensions. Hope I've made myself clear enough.

I guess that the love.resize callback is not called very often, right? Maybe when going full screen, when loading the window for the first time and when exiting fullscreen? And in Android, the resizing only takes place the first time too?
MrFariator
Party member
Posts: 512
Joined: Wed Oct 05, 2016 11:53 am

Re: Resizing a canvas

Post by MrFariator »

When you draw your canvas with love.graphics.draw(), you can give it extra arguments to scale it up (sx, sy). Not sure if that's what you're looking for.

So for instance if your game runs natively at 320x240 and window is then resized to 640x480, you can just pass 2 for both sx and sy. Thus in the event your game window gets resized to 740x480 you can just center the canvas and draw two black 50px bars around it. You'll just have to find the center-most (x,y) point and scaling factor for the canvas based on the current screen dimensions (adjust as necessary if you want to keep the aspect ratio or not).
nyenye wrote:I guess that the love.resize callback is not called very often, right? Maybe when going full screen, when loading the window for the first time and when exiting fullscreen? And in Android, the resizing only takes place the first time too?
love.resize is invoked only when the resolution of your game window changes, yes. I don't think it's invoked on application start, though.
nyenye
Citizen
Posts: 62
Joined: Fri Dec 02, 2016 1:44 pm

Re: Resizing a canvas

Post by nyenye »

When you draw your canvas with love.graphics.draw(), you can give it extra arguments to scale it up (sx, sy).
Oh man now I feel a little more stupid than before :awesome:. So till now I was doing it wrong I guess, let me explain. What I was doing is scaling everything and draw it to the canvas, then draw the canvas. And as you say, I'd would have a fixed canvas, fixed objects, and then scale the canvas before drawing it to the screen.

Thanks for the help guys!
nyenye
Citizen
Posts: 62
Joined: Fri Dec 02, 2016 1:44 pm

Re: [SOLVED] Resizing a canvas

Post by nyenye »

Hey me again. This is how it all turned out:

This is a simple tool to calculate scaling and position of the canvas:

Code: Select all

local AspectRatio = {
    win_w = 0, win_h = 0,
    dig_w = 0, dig_h = 0,
    game_w = 0, game_h = 0,
    scale = 0,
    x = 0, y = 0
}

function AspectRatio:init(win_w, win_h, dig_w, dig_h)
    self.win_w, self.win_h = win_w, win_h
    self.dig_w, self.dig_h = dig_w, dig_h

    self:calc_values(self)
end

function AspectRatio:resize(w, h)
    self.win_w, self.win_h = w, h
    self:calc_values()
end

function AspectRatio:calc_values()
    local scale_w, scale_h = self.win_w / self.dig_w, self.win_h / self.dig_h
    self.scale = math.min(scale_w, scale_h)

    self.game_w = self.dig_w * self.scale
    self.game_h = self.dig_h * self.scale
    
    self.x = math.floor((self.win_w / 2) - (self.game_w / 2))
    self.y = math.floor((self.win_h / 2) - (self.game_h / 2))
end

return AspectRatio
and this is main.lua:

Code: Select all

local aspect_ratio = require('lib/aspect_ratio')
local canvas
function love.load()
    local w, h = love.graphics.getDimensions()
    aspect_ratio:init(w, h, 320, 240) -- 320, 240 is the native resolution
    canvas = love.graphics.newCanvas(aspect_ratio.dig_w, aspect_ratio.dig_h)
end
function love.update(dt)
    canvas:renderTo(
        function()
            love.graphics.clear(255, 0, 0, 255)
            love.graphics.rectangle('fill', 10, 10, 40, 100)
        end
    )
end
function love.draw()
    love.graphics.clear()
    love.graphics.draw(canvas, aspect_ratio.x, aspect_ratio.y, 0, aspect_ratio.scale)
end
function love.resize(w, h)
end
example.png
example.png (74.33 KiB) Viewed 6955 times
Again thanks for the help!
Post Reply

Who is online

Users browsing this forum: No registered users and 193 guests