Effects

With the Effect "class", you can "tween" properties of objects or functions with different transitions

Its a port of the Mootools Fx classes

Usage
Simple use (for tweening the opacity):

fx = Effect.create(client_instance, {  duration = 0.8, -- seconds   fps = 60, -- frames per second (defaults to 40)   transition = Effect.Transitions.easeOut.Quint -- defaults to Effect.Transitions.linear }) fx:start({  opacity = 1 })

When using a function instead of an object it is important that the function can set and return your properties via a table

Example (asuming you want to tween x and y of a client instance c):

fx = Effect.create(function (geom) {  return c:geometry(geom) end fx:start({x = 10, y = 10})

my currently use:
You can find a video of it on vimeo

function initEffect (c, options, name) if not name then name = 'fx' end if not awful.client.property.get(c, name) then require("effect"); if not options then options = { duration = 1, transition = Effect.Transitions.easeIn.Bounce } 		end awful.client.property.set(c, name, Effect.create( function (props) return c:geometry(props) end, options )) 	end return awful.client.property.get(c, name) end -- Vogel functionality vogel = nil function vogelEffect if not vogel then return awful.util.spawn(terminal .. " -title vogel") end vogel.screen = mouse.screen client.focus = vogel vogel:raise vogel:tags({awful.tag.selected(mouse.screen)}) initEffect(vogel):start({ 		x = mouse.coords.x - vogel:geometry.width/2, 		y = mouse.coords.y - vogel:geometry.height/2 	}) end globalkeys = awful.util.table.join(globalkeys, 	awful.key({ "Shift" }, "F1", vogelEffect) ) client.add_signal("manage", function (c, startup) 	if c.name == 'vogel' then 		vogel = c 		vogelEffect 	end end) client.add_signal("unmanage", function (c, startup) 	if c.name == 'vogel' then 		vogel = nil 	end end) -- Move windows clientkeys = awful.util.table.join(clientkeys, 	-- move client to right screen edge 	awful.key({ modkey, "Control" }, "Right",		function (c) initEffect(c):start({x = screen[c.screen].workarea.width - c:geometry.width}); end), 	-- move client to left screen edge 	awful.key({ modkey, "Control" }, "Left",		function (c) initEffect(c):start({x = 0}); end), 	-- move client to top screen edge 	awful.key({ modkey, "Control" }, "Up",		function (c) initEffect(c):start({y = 0}); end), 	-- move client to bottom screen edge 	awful.key({ modkey, "Control" }, "Down",		function (c) initEffect(c):start({y = screen[c.screen].workarea.height - c:geometry.height}); end), 	-- make client height smaller 	awful.key({ modkey, "Control", "Shift" }, "Up",		function (c) initEffect(c, { 			duration = 0.2, 			transition = Effect.Transitions.linear 		}, 'fx-size'):start({height = c:geometry.height - 50}); end), 	-- make client height bigger 	awful.key({ modkey, "Control", "Shift" }, "Down",		function (c) initEffect(c, { 			duration = 0.2, 			transition = Effect.Transitions.linear 		}, 'fx-size'):start({height = c:geometry.height + 50}); end), 	-- make client width smaller 	awful.key({ modkey, "Control", "Shift" }, "Left",		function (c) initEffect(c, { 			duration = 0.2, 			transition = Effect.Transitions.linear 		}, 'fx-size'):start({width = c:geometry.width - 50}); end), 	-- make client width bigger 	awful.key({ modkey, "Control", "Shift" }, "Right",		function (c) initEffect(c, { 			duration = 0.2, 			transition = Effect.Transitions.linear 		}, 'fx-size'):start({width = c:geometry.width + 50}); end) )

The class
I dont know if it is the best lua coding practices. If there are bugs or anything please tell me :)

Put this in ~/.config/awesome/effect.lua or ~/.config/awesome/effect/init.lua

--- -- Effect class for the awesome window manager -- A port of mootools Fx Library --- -- Licensed under MIT License -- * (c) 2010, Georg Nagel  --- Effect = {} Effect.__index = Effect function Effect.create(obj, options) local fx = { options = { fps = 40, duration = 0.5 } 	} 	setmetatable(fx,Effect) fx._obj = obj if type(options) == 'table' then fx:setOptions(options) end fx._timer = timer({ timeout = 1/fx.options.fps }) fx._timer:add_signal("timeout", function fx:step end) fx._is_func = (type(fx._obj) == 'function') fx._props = {} return fx end function Effect:setOptions (options) tmp = self.options for k,v in pairs(options) do self.options[k] = v end end function Effect:start (properties) self._time = 0 o = self._obj if self._is_func then o = self._obj end if (self._timer.started) then self._timer:stop end for k,v in pairs(self._props) do 		if not properties[k] and properties[k] ~= 0 then properties[k] = v.to 		end end for k,v in pairs(properties) do 		if o[k] then self._props[k] = { from = o[k], to = v } end end self:validateTransition self._timer:start end function Effect:stop self._timer:stop end function Effect:step self._time = self._time + self._timer.timeout local newProps = {} if (self._time < self.options.duration) then for k,v in pairs(self._props) do 			local delta = self.transition(self._time / self.options.duration) newProps[k] = self:compute(v.from, v.to, delta) end else for k,v in pairs(self._props) do 			newProps[k] = v.to 			self._timer:stop end end self:set(newProps) end function Effect:set (props) if self._is_func then self._obj(props); else for k,v in pairs(self._props) do 			self._obj[prop] = value end end end function Effect:compute (from, to, delta) return (to - from) * delta + from end function Effect:validateTransition local trans = self.options.transition; if type(trans) ~= 'function' then trans = Effect.Transitions.linear end self.transition = trans; end Effect.Transitions = {} function Effect.Transitions.linear (zero) return zero end local transitions = {} function transitions.Pow (p, x) 	if type(x) == 'table' and x[0] then x = x[0] else x = 6 end return math.pow(p, x); end function transitions.Expo (p) return math.pow(2, 8 * (p - 1)); end function transitions.Circ (p) return 1 - math.sin(math.acos(p)); end function Effect.Transitions.Sine (p) return 1 - math.sin((1 - p) * math.pi / 2); end function transitions.Back (p, x) 	if type(x) == 'table' and x[0] then x = x[0] else x = 1.618 end return math.pow(p, 2) * ((x + 1) * p - x); end function transitions.Bounce (p) if p < 1/2.75 then return 7.5625*p*p end if p < 2/2.75 then p = p - (1.5/2.75) return 7.5625*p*p + 0.75 end if p < 2.5/2.75 then p = p - (2.25/2.75) return 7.5625*p*p + 0.9375 end p = p - (2.625/2.75) return 7.5625*p*p + 0.984375 end function transitions.Elastic (p, x) 	p = p - 1 if type(x) == 'table' and x[0] then x = x[0] else x = 3 end return match.pow(2, 10 * p) * math.cos(20 * p * math.pi * x / 3); end for i, name in pairs({'Quad', 'Cubic', 'Quart', 'Quint'}) do 	transitions[name] = function (p) return math.pow(p, i + 2) end end Effect.Transitions.easeIn = {} Effect.Transitions.easeOut = {} Effect.Transitions.easeInOut = {} for name,transition in pairs(transitions) do 	Effect.Transitions.easeIn[name] = transition Effect.Transitions.easeOut[name] = function (p) return 1 - transitions[name](1 - p); end Effect.Transitions.easeInOut[name] = function (p) local x = p <= 0.5 and transitions[name](2 * p, params) / 2 or (2 - transitions[name](2 * (1 - p))) / 2 return x 	end end