Module: Studio::FizzHelper
- Defined in:
- app/helpers/studio/fizz_helper.rb
Overview
The bubble table behind the hold-to-confirm button's fizz layers.
The CodePen this adapts scattered its particles with Sass random() at
compile time. There is no Sass here, and a runtime rand would re-scatter
the bubbles on every render — which fights Turbo's page cache (a restored
page would not match the one it replaced) and leaves the markup untestable.
So the scatter is SEEDED: stable for a given button across renders, and
different between two buttons on one page.
ZONES. The button is cut into a 3x2 grid — three zones along the top edge, three along the bottom, numbered left to right, top row first. A bubble only ever wears the colours of the zone it sits in, so a six-item palette reads as six things standing around the button rather than one shaken bag of confetti. The outer columns also own the spray off the left and right sides, each within its own half.
COLOURS. Each zone carries three slots — 1..18 across the six zones — and the
two layers split them: the resting layer wears the FIRST of its zone's three,
and the layer that fades in on hover alternates the second and third. A
caller binds them as --fizz-c-1..18 on the stack (turf-monster's board maps
the six picked teams' light / dark / alt colours onto them, in pick order);
anything unbound falls back to the bubble's own hue, so the effect is never
colourless.
Constant Summary collapse
- HUES =
Candy hues a bubble falls back to. Deliberately narrow — the source material spanned the whole wheel and read as confetti.
[ 262, 276, 292, 318, 336, 190, 168, 46 ].freeze
- ZONE_COLUMNS =
3- ZONE_ROWS =
2- ZONES =
ZONE_COLUMNS * ZONE_ROWS
- COLORS_PER_ZONE =
3- SLOTS =
ZONES * COLORS_PER_ZONE
- LAYER_OFFSETS =
Which of its zone's three slots a layer's bubbles take.
{ base: [ 0 ].freeze, # the first colour hover: [ 1, 2 ].freeze # the second and third, alternating }.freeze
Instance Method Summary collapse
-
#fizz_bit_style(bit) ⇒ Object
The inline style one bubble carries.
-
#fizz_bits(seed, layer: :base, per_zone: 5) ⇒ Object
One layer's bubbles.
-
#fizz_color(bit) ⇒ Object
One bubble's colour: its slot's bound colour, else its own hue.
Instance Method Details
#fizz_bit_style(bit) ⇒ Object
The inline style one bubble carries. Kept here rather than in the partial so the property names and the CSS that reads them stay in one place.
70 71 72 73 74 |
# File 'app/helpers/studio/fizz_helper.rb', line 70 def fizz_bit_style(bit) "left:#{bit[:x]}%;top:#{bit[:y]}%;" \ "--fs:#{bit[:size]}px;--fx:#{bit[:dx]}px;--fy:#{bit[:dy]}px;" \ "--fd:#{bit[:delay]}s;--ft:#{bit[:duration]}s;--fc:#{fizz_color(bit)}" end |
#fizz_bits(seed, layer: :base, per_zone: 5) ⇒ Object
One layer's bubbles. Each is a hash the partial writes out as inline custom properties: x/y place it (%), dx/dy are the drift it travels before fading (dy negative = rises off the top edge), size is px, delay and duration are seconds, hue is its fallback colour, zone and slot are its place in the palette.
49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'app/helpers/studio/fizz_helper.rb', line 49 def fizz_bits(seed, layer: :base, per_zone: 5) offsets = LAYER_OFFSETS.fetch(layer) prng = Random.new(seed.to_s.each_byte.sum * 7919 + per_zone) ZONES.times.flat_map do |zone| Array.new(per_zone) do |i| fizz_zone_bit(prng, zone: zone, index: i).merge( zone: zone + 1, slot: (zone * COLORS_PER_ZONE) + offsets[i % offsets.size] + 1 ) end end end |
#fizz_color(bit) ⇒ Object
One bubble's colour: its slot's bound colour, else its own hue.
64 65 66 |
# File 'app/helpers/studio/fizz_helper.rb', line 64 def fizz_color(bit) "var(--fizz-c-#{bit[:slot]}, hsl(#{bit[:hue]} 92% 70%))" end |