How would I make an image flip over like a card
Posted: Thu Jul 25, 2024 5:57 pm
I can't just set its scale to negative no? Please is this possible? Maybe with shaders?
I mean, did you try that?Gunroar:Cannon() wrote: ↑Thu Jul 25, 2024 5:57 pm I can't just set its scale to negative no? Please is this possible? Maybe with shaders?
That would just slide, zorg. Won't ...really look like a card flipping over. Just maybe at best like a 2D sprite turning around if that makes sense. (It won't look like a card flip. In short. Yes, of course I tried that).zorg wrote: ↑Fri Jul 26, 2024 9:40 amI mean, did you try that?Gunroar:Cannon() wrote: ↑Thu Jul 25, 2024 5:57 pm I can't just set its scale to negative no? Please is this possible? Maybe with shaders?
Because yes, you absolutely can. Negative scale shows the image mirrored on whatever axis you're scaling it negatively.
I forgot to say that you also need to fix the center constantly, so it doesn't slide, but rather vanishes into the centerpoint, then appears again; there might be a simple solution to this by setting the ox and oy parameters, but i'm not sure. Still, if that's not enough, then go for the options pgimeno gave you above.Gunroar:Cannon() wrote: ↑Thu Aug 01, 2024 12:53 amThat would just slide, zorg. Won't ...really look like a card flipping over. Just maybe at best like a 2D sprite turning around if that makes sense. (It won't look like a card flip. In short. Yes, of course I tried that).zorg wrote: ↑Fri Jul 26, 2024 9:40 amI mean, did you try that?Gunroar:Cannon() wrote: ↑Thu Jul 25, 2024 5:57 pm I can't just set its scale to negative no? Please is this possible? Maybe with shaders?
Because yes, you absolutely can. Negative scale shows the image mirrored on whatever axis you're scaling it negatively.
Code: Select all
-- CSS-like 3D card flipping effect.
-- By Rafael Navega (2024).
--
-- Public Domain.
io.stdout:setvbuf('no')
local img
local img_tf
local img_size
local SPEED = 0.03
local s = 0.0
local dir = nil
function love.load()
img = love.graphics.newImage('temp.png')
img_tf = love.math.newTransform(400 - img:getWidth() / 2.0,
300 - img:getHeight() / 2.0)
img_size = {img:getDimensions()}
end
function love.update(dt)
if dir then
s = s + SPEED * dir
if s <= 0.0 then
s = 0.0
dir = nil
elseif s >= 1.0 then
s = 1.0
dir = nil
end
end
if love.keyboard.isDown('right') then
s = s + 0.01
if s >= 1.0 then s = 1.0 end
end
if love.keyboard.isDown('left') then
s = s - 0.01
if s <= 0.0 then s = 0.0 end
end
end
local myShader = love.graphics.newShader(
[[// Angle in radians.
uniform float a;
// Transform that you want the image to be drawn with.
uniform mat4 image_tf;
// Image size in pixels.
uniform vec2 image_size;
vec4 position(mat4 transform_projection, vec4 vertex_position)
{
float xc = image_size.x / 2.0;
float yc = image_size.y / 2.0;
mat4 origin_mat = mat4(1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
-xc, -yc, 0.0, 1.0);
mat4 rotate_y_mat = mat4( cos(a), 0.0, sin(a), 0.0,
0.0, 1.0, 0.0, 0.0,
-sin(a), 0.0, cos(a), 0.0,
0.0, 0.0, 0.0, 1.0);
// Setting this to -1.0 will flip the direction of rotation.
const float ROTATION_SIGN = 1.0;
// A factor that controls the foreshortening (the perspective effect).
// Suggested numbers: 500.0, 1000.0, 5000.0, 10000.0 etc.
const float FORESHORTENING = 1000.0;
// A large number to keep Z coordinates from clipping out of the screen.
// Try setting this to like 10.0 to see why it's needed.
const float Z_COMPRESSION = 10000.0;
mat4 css_projection_mat = mat4(
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0 / Z_COMPRESSION, ROTATION_SIGN / FORESHORTENING,
0.0, 0.0, 0.0, 1.0);
mat4 restore_mat = mat4(1.0);
restore_mat[3] = vec4(xc, yc, 0.0, 1.0);
vec4 perspective_position = restore_mat * css_projection_mat * rotate_y_mat
* origin_mat * vertex_position;
return transform_projection * image_tf * perspective_position;
}]]
)
function love.draw()
love.graphics.setShader(myShader)
myShader:send('a', s * math.pi)
myShader:send('image_tf', img_tf)
myShader:send('image_size', img_size)
-- NOTE: do not position the image, or else it'll be offset from the origin.
-- Use the "img_tf" transform to control where you want to draw it.
love.graphics.draw(img)
love.graphics.setShader()
love.graphics.print('- Press Space to flip the card.', 10, 10)
love.graphics.print('- Press Left or Right to manually rotate the card.', 10, 30)
love.graphics.print('- Press Esc to quit.', 10, 50)
love.graphics.print(('Angle: %.2f'):format(s * 180.0), 10, 70)
end
function love.keypressed(key)
if key == 'escape' then
love.event.quit()
elseif key == 'space' then
if not dir then
if s > 0.5 then
dir = -1
else
dir = 1
end
else
dir = -dir
end
end
end