button.lua 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. local g = love.graphics
  2. require 'lib/component'
  3. Button = extend(Component)
  4. function Button:activate()
  5. self.hoverActive = false
  6. self.hoverFactor = 0
  7. self.prevHoverFactor = 0
  8. self.prevHoverFade = 0
  9. self.hoverX = nil
  10. self.hoverY = nil
  11. self.hoverDistance = 0
  12. self.hoverFade = 0
  13. self.disabled = false
  14. end
  15. function Button:update()
  16. self.prevHoverFactor = self.hoverFactor
  17. self.prevHoverFade = self.hoverFade
  18. if self.hoverActive then
  19. self.hoverFactor = lume.lerp(self.hoverFactor, 1, math.min(8 * ls.tickrate, 1))
  20. if self.hoverFactor > .999 then
  21. self.hoverFade = math.min(self.hoverFade + ls.tickrate, 1)
  22. end
  23. else
  24. self.hoverFactor = 0
  25. self.hoverFade = 0
  26. end
  27. end
  28. function Button:mousepressed(mx, my, b)
  29. if b == 'l' and self:contains(mx, my) and not self.disabled then
  30. self.gooey.hot = self
  31. end
  32. end
  33. function Button:mousereleased(mx, my, b)
  34. if b == 'l' and self.gooey.hot == self and self:contains(mx, my) and not self.disabled then
  35. self:emit('click')
  36. ctx.sound:play('juju1', function(sound) sound:setPitch(1) end)
  37. end
  38. end
  39. function Button:render()
  40. local x, y, w, h = unpack(self.geometry())
  41. local text = self.text
  42. local mx, my = self:getMousePosition()
  43. local hover = self:contains(mx, my)
  44. local active = hover and love.mouse.isDown('l') and self.gooey.hot == self
  45. -- Button
  46. g.setColor(0, 0, 0, 85)
  47. g.rectangle('fill', x, y, w, h)
  48. local fade = lume.lerp(self.prevHoverFade, self.hoverFade, ls.accum / ls.tickrate)
  49. g.setColor(0, 0, 0, 200)
  50. g.setLineWidth(2)
  51. local xx, yy = lume.round(x) + .5, lume.round(y) + .5
  52. w, h = math.floor(w), math.floor(h)
  53. g.line(xx, yy + h, xx + w, yy + h)
  54. g.line(xx + w, yy, xx + w, yy + h)
  55. g.setLineWidth(1)
  56. if hover then
  57. if not self.hoverActive then
  58. self.hoverX = mx
  59. self.hoverY = my
  60. local d = lume.distance
  61. self.hoverDistance = math.max(d(mx, my, x, y), d(mx, my, x + w, y), d(mx, my, x, y + h), d(mx, my, x + w, y + h))
  62. ctx.sound:play('juju1', function(sound) sound:setPitch(.75) end)
  63. end
  64. g.setColor(255, 255, 255)
  65. g.setStencil(function()
  66. g.rectangle('fill', x, y, w, h)
  67. end)
  68. local factor = lume.lerp(self.prevHoverFactor, self.hoverFactor, ls.accum / ls.tickrate)
  69. g.setColor(255, 255, 255, 40 * (1 - fade))
  70. g.setBlendMode('alpha')
  71. g.circle('fill', self.hoverX, self.hoverY, factor * self.hoverDistance)
  72. g.setBlendMode('alpha')
  73. g.setStencil()
  74. self.hoverActive = true
  75. else
  76. self.hoverActive = false
  77. end
  78. -- Text
  79. if active then y = y + 2 end
  80. g.setFont('mesmerize', h * .55)
  81. g.setColor(0, 0, 0, 100)
  82. g.printCenter(text, x + w / 2 + 1, y + h / 2 + 1)
  83. g.setColor(255, 255, 255)
  84. g.printCenter(text, x + w / 2, y + h / 2)
  85. end
  86. function Button:contains(x, y)
  87. return math.inside(x, y, unpack(self.geometry())) and not self.disabled
  88. end