Skip to content

add animated card #6521

Open
Open
@vishalvivekm

Description

@vishalvivekm

Desired Behavior

A new card component can be created to be used in a couple of different section on the site. The HTML code is attached below.

Screen.Recording.2025-05-25.at.9.49.34.AM.mov

Code

HTML code
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Meshery Schemas</title>
  <script src="https://cdn.tailwindcss.com"></script>
  <link href="https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500&display=swap" rel="stylesheet">
  <script>
    tailwind.config = {
      theme: {
        extend: {
          fontFamily: { geist: ['Geist', 'sans-serif'] },
          animation: {
            'float': 'float 6s ease-in-out infinite',
            'data-stream': 'dataStream 3s linear infinite',
            'schema-pulse': 'schemaPulse 4s ease-in-out infinite',
          },
          keyframes: {
            float: { 
              '0%, 100%': { transform: 'translateY(0px)' },
              '50%': { transform: 'translateY(-10px)' }
            },
            dataStream: {
              '0%': { strokeDashoffset: 20 },
              '100%': { strokeDashoffset: 0 }
            },
            schemaPulse: {
              '0%, 100%': { transform: 'scale(1)', opacity: 0.8 },
              '50%': { transform: 'scale(1.03)', opacity: 1 }
            }
          }
        }
      }
    }
  </script>
  <style>
    .glass {
      background: rgba(255, 255, 255, 0.05);
      backdrop-filter: blur(20px);
      -webkit-backdrop-filter: blur(20px);
    }
    .connector {
      stroke-dasharray: 8;
      animation: dataStream 2s linear infinite;
    }
    .table-float {
      animation: float 6s ease-in-out infinite;
    }
    .table-float:nth-child(2) { animation-delay: -1s; }
    .table-float:nth-child(3) { animation-delay: -2s; }
    .table-float:nth-child(4) { animation-delay: -3s; }
    
    .gradient-border {
      position: relative;
      background: linear-gradient(135deg, rgba0, 179, 159, 0.1), rgba(59, 130, 246, 0.1), rgba(0, 211, 169, 0.1);
    }
    
    .gradient-border::before {
      content: '';
      position: absolute;
      inset: 0;
      padding: 2px;
      background: linear-gradient(135deg, #EBC017, #477E96, #477E96,  #EBC017);
      border-radius: inherit;
      mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
      mask-composite: xor;
      -webkit-mask-composite: xor;
    }
    
    .inner-glow {
      box-shadow: 
        inset 0 0 20px rgba(0, 179, 159,  0.3),
        inset 0 0 40px rgba(59, 130, 246, 0.2),
        0 0 30px rgba(0, 211, 169,  0.4);
    }
    
    .card-border {
      background: rgba(0, 179, 159, 0.08);
      border: 1px solid rgba(0, 179, 159, 0.3);
      backdrop-filter: blur(20px);
      -webkit-backdrop-filter: blur(20px);
      box-shadow: 
        0 0 0 1px rgba(0, 179, 159, 0.3),
        inset 0 0 30px rgba(0, 179, 159, 0.1),
        inset 0 0 60px rgba(0, 211, 169, 0.05),
        0 0 50px rgba(0, 211, 169,  0.2);
    }
  </style>
</head>
<body class="bg-black m-0 p-0 overflow-hidden h-screen w-screen font-geist">
  <!-- Wave Visualizer Background -->
  <canvas id="visualizer" class="fixed inset-0 w-full h-full"></canvas>
  
  <!-- Glass Database Card -->
  <div class="fixed inset-0 flex items-center justify-center p-4 z-10">
    <div class="w-full relative max-w-xs">
      <!-- Card content -->
      <div class="relative card-border overflow-hidden rounded-2xl flex flex-col animate-float">
        <!-- Database Schema Preview -->
        <div class="p-4 flex justify-center relative">
          <div class="w-full h-48 rounded-xl gradient-border inner-glow overflow-hidden relative">
            <!-- Animated grid background -->
            <div class="absolute inset-0 opacity-10">
              <div class="w-full h-full animate-pulse" style="background-image: linear-gradient(90deg, rgba(255,255,255,0.3) 1px, transparent 1px), linear-gradient(rgba(255,255,255,0.3) 1px, transparent 1px); background-size: 15px 15px;"></div>
            </div>
            
            <!-- Database connections -->
            <svg class="absolute inset-0 w-full h-full pointer-events-none" viewBox="0 0 320 180">
              <defs>
                <linearGradient id="connectionGradient" x1="0%" y1="0%" x2="100%" y2="0%">
                  <stop offset="0%" style="stop-color:#4f46e5;stop-opacity:0.8" />
                  <stop offset="50%" style="stop-color:#00b39f;stop-opacity:1" />
                  <stop offset="100%" style="stop-color:#8b5cf6;stop-opacity:0.8" />
                </linearGradient>
              </defs>
              
              <g stroke="url(#connectionGradient)" stroke-width="1.5" fill="none">
                <!-- Primary data flow -->
                <path class="connector animate-pulse" d="M75,40 L140,60 L140,90 L200,90" />
                <path class="connector animate-pulse" d="M225,90 L240,90 L240,60 L240,60" />
                <path class="connector animate-pulse" d="M140,90 L140,120 L220,120" />
                <path class="connector animate-pulse" d="M225,120 L240,120 L240,150 L220,150" />
                
                <!-- Connection nodes -->
                <circle cx="75" cy="40" r="3" fill="#4f46e5"/>
                <circle cx="225" cy="90" r="3" fill="#3b82f6"/>
                <circle cx="245" cy="60" r="3" fill="#8b5cf6"/>
                <circle cx="225" cy="120" r="3" fill="#f59e0b"/>
                <circle cx="225" cy="150" r="3" fill="#ef4444"/>
              </g>
            </svg>
            
            <!-- Animated Database Tables -->
            <div class="absolute inset-0 w-full h-full">
              <!-- Kanvas icon hub -->
              <div class="absolute bottom-2 left-2 transform -translate-x-1/2 animate-schema-pulse">
                <div class="w-8 h-8 glass rounded-xl flex items-center justify-center border border-indigo-400/30 inner-glow">
                  <?xml version="1.0" encoding="UTF-8"?>
                  <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
                    <defs><style>
                        .cls-1 {fill: #00b39f;}
                        .cls-2 {fill: #00d3a9;}
                    </style></defs>
                    <polygon class="cls-2" points="261.82 30.1 261.82 228.75 433.99 129.07 261.82 30.1"/>
                    <polygon class="cls-2" points="261.82 270.3 261.82 469.9 435.56 370.56 261.82 270.3"/>
                    <polygon class="cls-1" points="237.03 227.38 237.03 31.77 66.97 129.25 237.03 227.38"/>
                    <polygon class="cls-1" points="237.03 468.98 237.03 271.74 66.56 370.43 237.03 468.98"/>
                    <polygon class="cls-1" points="447.37 348.75 447.37 149.97 275.4 249.52 447.37 348.75"/>
                    <polygon class="cls-2" points="52.63 149.59 52.63 349.85 225.87 249.56 52.63 149.59"/>
                  </svg>
                </div>
              </div>
              
              <!-- Floating table cards -->
              <div class="absolute left-3 top-12 table-float">
                <div class="w-16 h-12 glass rounded-lg gradient-border shadow-lg overflow-hidden">
                  <div class="bg-gradient-to-r from-indigo-500/20 to-blue-500/20 text-white text-[7px] px-1.5 py-0.5 font-medium border-b border-white/10">designs</div>
                  <div class="px-1.5 py-0.5 space-y-0.5">
                    <div class="flex items-center space-x-0.5">
                      <div class="w-1 h-1 bg-yellow-400 rounded-full"></div>
                      <div class="h-0.5 w-6 bg-white/30 rounded"></div>
                    </div>
                    <div class="h-0.5 w-4 bg-white/20 rounded"></div>
                    <div class="h-0.5 w-7 bg-white/20 rounded"></div>
                  </div>
                </div>
              </div>
              
              <div class="absolute right-3 top-12 table-float">
                <div class="w-16 h-12 glass rounded-lg gradient-border shadow-lg overflow-hidden">
                  <div class="bg-gradient-to-r from-blue-500/20 to-purple-500/20 text-white text-[7px] px-1.5 py-0.5 font-medium border-b border-white/10">relationships</div>
                  <div class="px-1.5 py-0.5 space-y-0.5">
                    <div class="flex items-center space-x-0.5">
                      <div class="w-1 h-1 bg-blue-400 rounded-full"></div>
                      <div class="h-0.5 w-6 bg-white/30 rounded"></div>
                    </div>
                    <div class="h-0.5 w-3 bg-white/20 rounded"></div>
                    <div class="h-0.5 w-5 bg-white/20 rounded"></div>
                  </div>
                </div>
              </div>
              
              <div class="absolute left-1/2 transform -translate-x-1/2 top-24 table-float">
                <div class="w-16 h-12 glass rounded-lg gradient-border shadow-lg overflow-hidden">
                  <div class="bg-gradient-to-r from-purple-500/20 to-pink-500/20 text-white text-[7px] px-1.5 py-0.5 font-medium border-b border-white/10">models</div>
                  <div class="px-1.5 py-0.5 space-y-0.5">
                    <div class="flex items-center space-x-0.5">
                      <div class="w-1 h-1 bg-green-400 rounded-full"></div>
                      <div class="h-0.5 w-6 bg-white/30 rounded"></div>
                    </div>
                    <div class="h-0.5 w-6 bg-white/20 rounded"></div>
                    <div class="h-0.5 w-4 bg-white/20 rounded"></div>
                  </div>
                </div>
              </div>
              
              <div class="absolute left-1/2 transform -translate-x-1/2 bottom-3 table-float">
                <div class="w-16 h-12 glass rounded-lg gradient-border shadow-lg overflow-hidden">
                  <div class="bg-gradient-to-r from-orange-500/20 to-red-500/20 text-white text-[7px] px-1.5 py-0.5 font-medium border-b border-white/10">components</div>
                  <div class="px-1.5 py-0.5 space-y-0.5">
                    <div class="flex items-center space-x-0.5">
                      <div class="w-1 h-1 bg-orange-400 rounded-full"></div>
                      <div class="h-0.5 w-6 bg-white/30 rounded"></div>
                    </div>
                    <div class="h-0.5 w-3 bg-white/20 rounded"></div>
                    <div class="h-0.5 w-5 bg-white/20 rounded"></div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        
        <!-- Glass divider -->
        <div class="w-full h-px bg-gradient-to-r from-transparent via-white/30 to-transparent"></div>
        
        <!-- Content -->
        <div class="p-4">
          <span class="inline-block px-3 py-1 glass text-orange-300 rounded-full text-xs font-medium mb-3 border border-orange-400/30">AWS</span>
          <span class="inline-block px-3 py-1 glass text-indigo-300 rounded-full text-xs font-medium mb-3 border border-indigo-400/30">Azure</span>
          <span class="inline-block px-3 py-1 glass text-sky-300 rounded-full text-xs font-medium mb-3 border border-sky-400/30">GCP</span>
          <h3 class="text-lg font-medium text-white mb-2">Model your infrastructure</h3>
          <p class="text-white/70 mb-4 leading-relaxed text-xs">
            Design, optimize and maintain your infrastructure with Kanvas' intelligent inference.
          </p>
          <div class="flex justify-between items-center">
            <a href="#" class="text-green-400 hover:text-green-300 transition flex items-center text-xs font-medium glass px-3 py-1.5 rounded-lg border border-green-400/30">
              Manage
              <svg class="w-3 h-3 ml-1" viewBox="0 0 24 24" fill="none"><path d="M5 12H19M19 12L12 5M19 12L12 19" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
            </a>
            <span class="text-black-400/50 text-xs glass px-2 py-1 rounded-full border border-gray-400/10">Live</span>
          </div>
        </div>
      </div>
    </div>
  </div>

  <script>
    const canvas = document.getElementById('visualizer');
    const ctx = canvas.getContext('2d');
    let time = 0;
    let waveData = Array(8).fill(0).map(() => ({
        value: Math.random() * 0.5 + 0.1,
        targetValue: Math.random() * 0.15 + 0.1,
        speed: Math.random() * .02 + 0.01
    }));
    
    function resizeCanvas() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
    }
    
    function updateWaveData() {
        waveData.forEach(data => {
            if (Math.random() < 0.01) {
                data.targetValue = Math.random() * 0.7 + 0.1;
            }
            const diff = data.targetValue - data.value;
            data.value += diff * data.speed;
        });
    }
    
    function draw() {
        ctx.fillStyle = 'black';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        
        for (let i = 0; i < 8; i++) {
            const freq = waveData[i].value * 7.0;
            ctx.beginPath();
            
            for (let x = 0; x < canvas.width; x += 1) {
                const normalizedX = (x / canvas.width) * 2 - 1;
                let px = normalizedX + i * 0.04 + freq * 0.03;
                let py = Math.sin(px * 10 + time) * Math.cos(px * 2) * freq * 0.1 * ((i + 1) / 8);
                const canvasY = (py + 1) * canvas.height / 2;
                
                if (x === 0) {
                    ctx.moveTo(x, canvasY);
                } else {
                    ctx.lineTo(x, canvasY);
                }
            }
            
            const intensity = Math.min(1, freq * 0.3);
            const r = 255 + intensity * 100;
            const g = 243 + intensity * 130;
            const b = 197;
            
            ctx.lineWidth = .1 + (i * 0.3);
            ctx.strokeStyle = `rgba(${r}, ${g}, ${b}, 0.6)`;
            ctx.shadowColor = `rgba(${r}, ${g}, ${b}, 0.5)`;
            ctx.shadowBlur = 5;
            ctx.stroke();
            ctx.shadowBlur = 0;
        }
    }
    
    function animate() {
        time += 0.02;
        updateWaveData();
        draw();
        requestAnimationFrame(animate);
    }
    
    window.addEventListener('resize', resizeCanvas);
    resizeCanvas();
    animate();
  </script>
</body>
</html>

Implementation

  • refer to the html code above

Acceptance Tests

  • reusable react card component created
  • animated card used in suitable sections on the site

Contributor Resources and Handbook

The layer5.io website uses Gatsby, React, and GitHub Pages. Site content is found under the master branch.

Join the Layer5 Community by submitting your community member form.

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions