image and animation progress
This commit is contained in:
147
modules/Transform.lua
Normal file
147
modules/Transform.lua
Normal file
@@ -0,0 +1,147 @@
|
||||
--- Transform module for 2D transformations (rotate, scale, translate, skew)
|
||||
---@class Transform
|
||||
---@field rotate number? Rotation in radians (default: 0)
|
||||
---@field scaleX number? X-axis scale (default: 1)
|
||||
---@field scaleY number? Y-axis scale (default: 1)
|
||||
---@field translateX number? X translation in pixels (default: 0)
|
||||
---@field translateY number? Y translation in pixels (default: 0)
|
||||
---@field skewX number? X-axis skew in radians (default: 0)
|
||||
---@field skewY number? Y-axis skew in radians (default: 0)
|
||||
---@field originX number? Transform origin X (0-1, default: 0.5)
|
||||
---@field originY number? Transform origin Y (0-1, default: 0.5)
|
||||
local Transform = {}
|
||||
Transform.__index = Transform
|
||||
|
||||
--- Create a new transform instance
|
||||
---@param props TransformProps?
|
||||
---@return Transform transform
|
||||
function Transform.new(props)
|
||||
props = props or {}
|
||||
|
||||
local self = setmetatable({}, Transform)
|
||||
|
||||
self.rotate = props.rotate or 0
|
||||
self.scaleX = props.scaleX or 1
|
||||
self.scaleY = props.scaleY or 1
|
||||
self.translateX = props.translateX or 0
|
||||
self.translateY = props.translateY or 0
|
||||
self.skewX = props.skewX or 0
|
||||
self.skewY = props.skewY or 0
|
||||
self.originX = props.originX or 0.5
|
||||
self.originY = props.originY or 0.5
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Apply transform to LÖVE graphics context
|
||||
---@param transform Transform Transform instance
|
||||
---@param x number Element x position
|
||||
---@param y number Element y position
|
||||
---@param width number Element width
|
||||
---@param height number Element height
|
||||
function Transform.apply(transform, x, y, width, height)
|
||||
if not transform then
|
||||
return
|
||||
end
|
||||
|
||||
-- Calculate transform origin
|
||||
local ox = x + width * transform.originX
|
||||
local oy = y + height * transform.originY
|
||||
|
||||
-- Apply transform in correct order: translate → rotate → scale → skew
|
||||
love.graphics.push()
|
||||
love.graphics.translate(ox, oy)
|
||||
|
||||
if transform.rotate ~= 0 then
|
||||
love.graphics.rotate(transform.rotate)
|
||||
end
|
||||
|
||||
if transform.scaleX ~= 1 or transform.scaleY ~= 1 then
|
||||
love.graphics.scale(transform.scaleX, transform.scaleY)
|
||||
end
|
||||
|
||||
if transform.skewX ~= 0 or transform.skewY ~= 0 then
|
||||
love.graphics.shear(transform.skewX, transform.skewY)
|
||||
end
|
||||
|
||||
love.graphics.translate(-ox, -oy)
|
||||
love.graphics.translate(transform.translateX, transform.translateY)
|
||||
end
|
||||
|
||||
--- Remove transform from LÖVE graphics context
|
||||
function Transform.unapply()
|
||||
love.graphics.pop()
|
||||
end
|
||||
|
||||
--- Interpolate between two transforms
|
||||
---@param from Transform Starting transform
|
||||
---@param to Transform Ending transform
|
||||
---@param t number Interpolation factor (0-1)
|
||||
---@return Transform interpolated
|
||||
function Transform.lerp(from, to, t)
|
||||
-- Sanitize inputs
|
||||
if type(from) ~= "table" then
|
||||
from = Transform.new()
|
||||
end
|
||||
if type(to) ~= "table" then
|
||||
to = Transform.new()
|
||||
end
|
||||
if type(t) ~= "number" or t ~= t or t == math.huge or t == -math.huge then
|
||||
t = 0
|
||||
end
|
||||
|
||||
-- Clamp t to 0-1 range
|
||||
t = math.max(0, math.min(1, t))
|
||||
|
||||
return Transform.new({
|
||||
rotate = (from.rotate or 0) * (1 - t) + (to.rotate or 0) * t,
|
||||
scaleX = (from.scaleX or 1) * (1 - t) + (to.scaleX or 1) * t,
|
||||
scaleY = (from.scaleY or 1) * (1 - t) + (to.scaleY or 1) * t,
|
||||
translateX = (from.translateX or 0) * (1 - t) + (to.translateX or 0) * t,
|
||||
translateY = (from.translateY or 0) * (1 - t) + (to.translateY or 0) * t,
|
||||
skewX = (from.skewX or 0) * (1 - t) + (to.skewX or 0) * t,
|
||||
skewY = (from.skewY or 0) * (1 - t) + (to.skewY or 0) * t,
|
||||
originX = (from.originX or 0.5) * (1 - t) + (to.originX or 0.5) * t,
|
||||
originY = (from.originY or 0.5) * (1 - t) + (to.originY or 0.5) * t,
|
||||
})
|
||||
end
|
||||
|
||||
--- Check if transform is identity (no transformation)
|
||||
---@param transform Transform
|
||||
---@return boolean isIdentity
|
||||
function Transform.isIdentity(transform)
|
||||
if not transform then
|
||||
return true
|
||||
end
|
||||
|
||||
return transform.rotate == 0
|
||||
and transform.scaleX == 1
|
||||
and transform.scaleY == 1
|
||||
and transform.translateX == 0
|
||||
and transform.translateY == 0
|
||||
and transform.skewX == 0
|
||||
and transform.skewY == 0
|
||||
end
|
||||
|
||||
--- Clone a transform
|
||||
---@param transform Transform
|
||||
---@return Transform clone
|
||||
function Transform.clone(transform)
|
||||
if not transform then
|
||||
return Transform.new()
|
||||
end
|
||||
|
||||
return Transform.new({
|
||||
rotate = transform.rotate,
|
||||
scaleX = transform.scaleX,
|
||||
scaleY = transform.scaleY,
|
||||
translateX = transform.translateX,
|
||||
translateY = transform.translateY,
|
||||
skewX = transform.skewX,
|
||||
skewY = transform.skewY,
|
||||
originX = transform.originX,
|
||||
originY = transform.originY,
|
||||
})
|
||||
end
|
||||
|
||||
return Transform
|
||||
Reference in New Issue
Block a user