Auto-indexing service and GraphQL API for AT Protocol Records
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 112 lines 4.0 kB view raw
1/// Backfill Animation Component 2/// 3/// Animated SVG showing pulsing ellipses to indicate backfill in progress 4import lustre/attribute 5import lustre/element.{type Element} 6import lustre/element/svg 7 8/// Render the backfill animation SVG 9pub fn view(class: String) -> Element(msg) { 10 svg.svg( 11 [ 12 attribute.attribute("viewBox", "0 0 128 128"), 13 attribute.attribute("xmlns", "http://www.w3.org/2000/svg"), 14 attribute.attribute("overflow", "visible"), 15 attribute.class(class), 16 ], 17 [ 18 // Define gradients 19 svg.defs([], [ 20 svg.linear_gradient( 21 [ 22 attribute.id("backfill-board1"), 23 attribute.attribute("x1", "0%"), 24 attribute.attribute("y1", "0%"), 25 attribute.attribute("x2", "100%"), 26 attribute.attribute("y2", "100%"), 27 ], 28 [ 29 svg.stop([ 30 attribute.attribute("offset", "0%"), 31 attribute.attribute("stop-color", "#FF6347"), 32 attribute.attribute("stop-opacity", "1"), 33 ]), 34 svg.stop([ 35 attribute.attribute("offset", "100%"), 36 attribute.attribute("stop-color", "#FF4500"), 37 attribute.attribute("stop-opacity", "1"), 38 ]), 39 ], 40 ), 41 svg.linear_gradient( 42 [ 43 attribute.id("backfill-board2"), 44 attribute.attribute("x1", "0%"), 45 attribute.attribute("y1", "0%"), 46 attribute.attribute("x2", "100%"), 47 attribute.attribute("y2", "100%"), 48 ], 49 [ 50 svg.stop([ 51 attribute.attribute("offset", "0%"), 52 attribute.attribute("stop-color", "#00CED1"), 53 attribute.attribute("stop-opacity", "1"), 54 ]), 55 svg.stop([ 56 attribute.attribute("offset", "100%"), 57 attribute.attribute("stop-color", "#4682B4"), 58 attribute.attribute("stop-opacity", "1"), 59 ]), 60 ], 61 ), 62 // Inline style for animations 63 element.element("style", [], [ 64 element.text( 65 " 66 .backfill-ellipse1 { animation: backfill-pulse 1.5s ease-in-out infinite; } 67 .backfill-ellipse2 { animation: backfill-pulse 1.5s ease-in-out infinite 0.2s; } 68 .backfill-ellipse3 { animation: backfill-pulse 1.5s ease-in-out infinite 0.4s; } 69 @keyframes backfill-pulse { 70 0%, 100% { transform: scale(1); opacity: 1; } 71 50% { transform: scale(1.1); opacity: 0.8; } 72 } 73 ", 74 ), 75 ]), 76 ]), 77 // Pulsing ellipses 78 svg.g([attribute.attribute("transform", "translate(64, 64)")], [ 79 // Top ellipse 80 svg.ellipse([ 81 attribute.class("backfill-ellipse1"), 82 attribute.attribute("cx", "0"), 83 attribute.attribute("cy", "-28"), 84 attribute.attribute("rx", "50"), 85 attribute.attribute("ry", "20"), 86 attribute.attribute("fill", "url(#backfill-board1)"), 87 attribute.attribute("style", "transform-origin: 0 -28px;"), 88 ]), 89 // Middle ellipse 90 svg.ellipse([ 91 attribute.class("backfill-ellipse2"), 92 attribute.attribute("cx", "0"), 93 attribute.attribute("cy", "0"), 94 attribute.attribute("rx", "60"), 95 attribute.attribute("ry", "20"), 96 attribute.attribute("fill", "url(#backfill-board2)"), 97 attribute.attribute("style", "transform-origin: 0 0;"), 98 ]), 99 // Bottom ellipse 100 svg.ellipse([ 101 attribute.class("backfill-ellipse3"), 102 attribute.attribute("cx", "0"), 103 attribute.attribute("cy", "28"), 104 attribute.attribute("rx", "40"), 105 attribute.attribute("ry", "20"), 106 attribute.attribute("fill", "#32CD32"), 107 attribute.attribute("style", "transform-origin: 0 28px;"), 108 ]), 109 ]), 110 ], 111 ) 112}