Something went wrong. Try again.
google balls
Something went wrong. Try again.
8.7 kB · 280 lines
Lua
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281-- Vector class for 3D positionsVector = {}Vector.__index = Vector
function Vector.new(x, y, z) local self = setmetatable({}, Vector) self.x = x or 0 self.y = y or 0 self.z = z or 0 return selfend
function Vector:addX(x) self.x = self.x + xend
function Vector:addY(y) self.y = self.y + yend
function Vector:addZ(z) self.z = self.z + zend
function Vector:set(x, y, z) self.x = x self.y = y or self.y self.z = z or self.zend
-- Point class for individual animated pointsPoint = {}Point.__index = Point
function Point.new(x, y, z, size, colour) local self = setmetatable({}, Point) self.colour = colour self.curPos = Vector.new(x, y, z) self.friction = 0.8 self.originalPos = Vector.new(x, y, z) self.radius = size self.size = size self.springStrength = 0.1 self.targetPos = Vector.new(x, y, z) self.velocity = Vector.new(0, 0, 0) return selfend
function Point:update() -- X axis spring physics local dx = self.targetPos.x - self.curPos.x local ax = dx * self.springStrength self.velocity.x = self.velocity.x + ax self.velocity.x = self.velocity.x * self.friction self.curPos.x = self.curPos.x + self.velocity.x
-- Y axis spring physics local dy = self.targetPos.y - self.curPos.y local ay = dy * self.springStrength self.velocity.y = self.velocity.y + ay self.velocity.y = self.velocity.y * self.friction self.curPos.y = self.curPos.y + self.velocity.y
-- Z axis for scaling effect local dox = self.originalPos.x - self.curPos.x local doy = self.originalPos.y - self.curPos.y local dd = (dox * dox) + (doy * doy) local d = math.sqrt(dd)
self.targetPos.z = d / 100 + 1 local dz = self.targetPos.z - self.curPos.z local az = dz * self.springStrength self.velocity.z = self.velocity.z + az self.velocity.z = self.velocity.z * self.friction self.curPos.z = self.curPos.z + self.velocity.z
-- Update radius based on Z position self.radius = self.size * self.curPos.z if self.radius < 1 then self.radius = 1 endend
function Point:draw(ctx) ctx:setFillStyle(self.colour) ctx:beginPath() ctx:arc(self.curPos.x, self.curPos.y, self.radius, 0, 2 * math.pi, false) ctx:fill()end
-- PointCollection class to manage all pointsPointCollection = {}PointCollection.__index = PointCollection
function PointCollection.new() local self = setmetatable({}, PointCollection) self.mousePos = Vector.new(0, 0, 0) self.points = {} return selfend
function PointCollection:addPoint(x, y, z, size, colour) local point = Point.new(x, y, z, size, colour) table.insert(self.points, point) return pointend
function PointCollection:update() for i, point in ipairs(self.points) do if point then local dx = self.mousePos.x - point.curPos.x local dy = self.mousePos.y - point.curPos.y local dd = (dx * dx) + (dy * dy) local d = math.sqrt(dd)
if d < 150 then -- Mouse is close, repel the point point.targetPos.x = point.curPos.x - dx point.targetPos.y = point.curPos.y - dy else -- Mouse is far, return to original position point.targetPos.x = point.originalPos.x point.targetPos.y = point.originalPos.y end
point:update() end endend
function PointCollection:draw(ctx) for i, point in ipairs(self.points) do if point then point:draw(ctx) end endend
function PointCollection:recenter(canvasWidth, canvasHeight) local offsetX = (canvasWidth / 2 - 180) local offsetY = (canvasHeight / 2 - 65)
for i, point in ipairs(self.points) do -- Calculate relative position from original center local relX = point.originalPos.x - (canvasWidth / 2 - 180) local relY = point.originalPos.y - (canvasHeight / 2 - 65)
-- Update positions point.originalPos.x = offsetX + relX point.originalPos.y = offsetY + relY point.curPos.x = point.originalPos.x point.curPos.y = point.originalPos.y endend
-- Global variableslocal canvaslocal ctxlocal pointCollectionlocal canvasWidth, canvasHeightlocal reloadMsg
-- Initialize the applicationfunction init() canvas = gurt.select('#canvas') ctx = canvas:withContext('2d') reloadMsg = gurt.select('#reload-msg')
updateCanvasDimensions() createPoints() initEventListeners() showReloadMessage() -- Start animation loop gurt.timer.setInterval(30, function() draw() update() end)end
function updateCanvasDimensions() canvasWidth = gurt.window.innerWidth canvasHeight = gurt.window.innerHeight canvas:attr('width', canvasWidth) canvas:attr('height', canvasHeight) if pointCollection then pointCollection:recenter(canvasWidth, canvasHeight) endend
function createPoints() -- Original Google logo point data local pointData = { {202, 78, 0.0, 9, "#ed9d33"}, {348, 83, 0.0, 9, "#d44d61"}, {256, 69, 0.0, 9, "#4f7af2"}, {214, 59, 0.0, 9, "#ef9a1e"}, {265, 36, 0.0, 9, "#4976f3"}, {300, 78, 0.0, 9, "#269230"}, {294, 59, 0.0, 9, "#1f9e2c"}, {45, 88, 0.0, 9, "#1c48dd"}, {268, 52, 0.0, 9, "#2a56ea"}, {73, 83, 0.0, 9, "#3355d8"}, {294, 6, 0.0, 9, "#36b641"}, {235, 62, 0.0, 9, "#2e5def"}, {353, 42, 0.0, 8, "#d53747"}, {336, 52, 0.0, 8, "#eb676f"}, {208, 41, 0.0, 8, "#f9b125"}, {321, 70, 0.0, 8, "#de3646"}, {8, 60, 0.0, 8, "#2a59f0"}, {180, 81, 0.0, 8, "#eb9c31"}, {146, 65, 0.0, 8, "#c41731"}, {145, 49, 0.0, 8, "#d82038"}, {246, 34, 0.0, 8, "#5f8af8"}, {169, 69, 0.0, 8, "#efa11e"}, {273, 99, 0.0, 8, "#2e55e2"}, {248, 120, 0.0, 8, "#4167e4"}, {294, 41, 0.0, 8, "#0b991a"}, {267, 114, 0.0, 8, "#4869e3"}, {78, 67, 0.0, 8, "#3059e3"}, {294, 23, 0.0, 8, "#10a11d"}, {117, 83, 0.0, 8, "#cf4055"}, {137, 80, 0.0, 8, "#cd4359"}, {14, 71, 0.0, 8, "#2855ea"}, {331, 80, 0.0, 8, "#ca273c"}, {25, 82, 0.0, 8, "#2650e1"}, {233, 46, 0.0, 8, "#4a7bf9"}, {73, 13, 0.0, 8, "#3d65e7"}, {327, 35, 0.0, 6, "#f47875"}, {319, 46, 0.0, 6, "#f36764"}, {256, 81, 0.0, 6, "#1d4eeb"}, {244, 88, 0.0, 6, "#698bf1"}, {194, 32, 0.0, 6, "#fac652"}, {97, 56, 0.0, 6, "#ee5257"}, {105, 75, 0.0, 6, "#cf2a3f"}, {42, 4, 0.0, 6, "#5681f5"}, {10, 27, 0.0, 6, "#4577f6"}, {166, 55, 0.0, 6, "#f7b326"}, {266, 88, 0.0, 6, "#2b58e8"}, {178, 34, 0.0, 6, "#facb5e"}, {100, 65, 0.0, 6, "#e02e3d"}, {343, 32, 0.0, 6, "#f16d6f"}, {59, 5, 0.0, 6, "#507bf2"}, {27, 9, 0.0, 6, "#5683f7"}, {233, 116, 0.0, 6, "#3158e2"}, {123, 32, 0.0, 6, "#f0696c"}, {6, 38, 0.0, 6, "#3769f6"}, {63, 62, 0.0, 6, "#6084ef"}, {6, 49, 0.0, 6, "#2a5cf4"}, {108, 36, 0.0, 6, "#f4716e"}, {169, 43, 0.0, 6, "#f8c247"}, {137, 37, 0.0, 6, "#e74653"}, {318, 58, 0.0, 6, "#ec4147"}, {226, 100, 0.0, 5, "#4876f1"}, {101, 46, 0.0, 5, "#ef5c5c"}, {226, 108, 0.0, 5, "#2552ea"}, {17, 17, 0.0, 5, "#4779f7"}, {232, 93, 0.0, 5, "#4b78f1"} }
pointCollection = PointCollection.new()
-- Create points with centered positioning for i, data in ipairs(pointData) do local x = (canvasWidth / 2 - 180) + data[1] local y = (canvasHeight / 2 - 65) + data[2] local z = data[3] local size = data[4] local color = data[5] pointCollection:addPoint(x, y, z, size, color) endend
function initEventListeners() -- Mouse movement tracking gurt.body:on('mousemove', function(event) if pointCollection then pointCollection.mousePos:set(event.x, event.y, 0) end end)
-- Window resize handling gurt.window:on('resize', function() updateCanvasDimensions() end)
-- Keyboard shortcuts gurt.body:on('keydown', function(event) if event.ctrl and event.key == 'r' then -- Ctrl+R to reset points createPoints() trace.log('Points reset!') end end)end
function showReloadMessage() reloadMsg:style('display', 'block') -- Fade out after 3 seconds gurt.timer.setTimeout(3000, function() reloadMsg:style('display', 'none') end)end
function draw() -- Clear canvas ctx:clearRect(0, 0, canvasWidth, canvasHeight) -- Draw all points if pointCollection then pointCollection:draw(ctx) endend
function update() -- Update all points if pointCollection then pointCollection:update() endend