portfolio / components /skill-bubble.js
Redhanuman's picture
make an portfolio
7469cbf verified
// Skill Bubble Web Component
class SkillBubble extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
const skill = this.getAttribute('skill') || 'JavaScript';
const level = this.getAttribute('level') || '80';
const icon = this.getAttribute('icon') || 'code';
this.shadowRoot.innerHTML = `
<style>
:host {
display: inline-block;
margin: 8px;
}
.bubble {
width: 120px;
height: 120px;
border-radius: 50%;
background: linear-gradient(135deg, #6366f1, #4f46e5);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: white;
text-align: center;
transition: transform 0.3s ease, box-shadow 0.3s ease;
cursor: pointer;
position: relative;
overflow: hidden;
}
{
transform: .bubble:hover scale(1.1);
box-shadow: 0 10px 25px rgba(99, 102, 241, 0.4);
}
.icon {
width: 32px;
height: 32px;
margin-bottom: 8px;
stroke: white;
}
.skill-name {
font-size: 12px;
font-weight: 600;
margin-bottom: 4px;
}
.skill-level {
font-size: 10px;
opacity: 0.8;
}
.progress {
position: absolute;
bottom: 0;
left: 0;
height: 4px;
background: rgba(255, 255, 255, 0.3);
width: 100%;
border-radius: 0 0 50% 50%;
}
.progress-fill {
height: 100%;
background: white;
border-radius: 0 0 50% 50%;
transition: width 1s ease;
}
</style>
<div class="bubble">
<svg class="icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"></path>
</svg>
<div class="skill-name">${skill}</div>
<div class="skill-level">${level}%</div>
<div class="progress">
<div class="progress-fill" style="width: ${level}%"></div>
</div>
</div>
`;
// Animate progress bar after a delay
setTimeout(() => {
const progressFill = this.shadowRoot.querySelector('.progress-fill');
if (progressFill) {
progressFill.style.width = `${level}%`;
}
}, 500);
}
}
// Register the custom element
customElements.define('skill-bubble', SkillBubble);
// Usage example:
// <skill-bubble skill="React" level="90" icon="code"></skill-bubble>
// <skill-bubble skill="Node.js" level="85" icon="server"></skill-bubble>
// <skill-bubble skill="Python" level="80" icon="cpu"></skill-bubble>