cleancut-portfolio / script.js
Messssss's picture
Remove all the link at the top of the website. They look unprofessional and jeopardizing the look of the overall website
cce5a2a verified
// Portfolio Data - In a real app, this would come from an API
const portfolioData = {
categories: [
{
id: 'ads',
title: 'Commercial Ads',
description: 'Professional advertising campaigns and promotional content',
videos: [
{
id: 1,
title: 'Tech Startup Launch',
thumbnail: 'http://static.photos/technology/320x240/1',
duration: '2:30',
views: '15.2K',
description: 'Dynamic product launch campaign for innovative tech company',
videoUrl: '#',
tags: ['Technology', 'Corporate', 'Branding']
},
{
id: 2,
title: 'Fashion Brand Campaign',
thumbnail: 'http://static.photos/retail/320x240/2',
duration: '1:45',
views: '23.7K',
description: 'High-fashion brand identity video for luxury clothing line',
videoUrl: '#',
tags: ['Fashion', 'Luxury', 'Lifestyle']
}
]
},
{
id: 'music-videos',
title: 'Music Videos',
description: 'Creative visual storytelling for musical artists',
videos: [
{
id: 3,
title: 'Indie Rock Journey',
thumbnail: 'http://static.photos/music/320x240/3',
duration: '4:15',
views: '89.4K',
description: 'Narrative music video following band tour experience',
videoUrl: '#',
tags: ['Music', 'Tour', 'Narrative']
},
{
id: 4,
title: 'Electronic Visualizer',
thumbnail: 'http://static.photos/abstract/320x240/4',
duration: '3:20',
views: '45.1K',
description: 'Abstract visual experience for electronic music track',
videoUrl: '#',
tags: ['Electronic', 'Abstract', 'Visual']
}
]
},
{
id: 'weddings',
title: 'Wedding Films',
description: 'Emotional storytelling for life\'s most precious moments',
videos: [
{
id: 5,
title: 'Mountain Wedding',
thumbnail: 'http://static.photos/nature/320x240/5',
duration: '8:30',
views: '12.8K',
description: 'Breathtaking outdoor wedding ceremony and celebration',
videoUrl: '#',
tags: ['Outdoor', 'Romantic', 'Nature']
},
{
id: 6,
title: 'Urban Celebration',
thumbnail: 'http://static.photos/cityscape/320x240/6',
duration: '6:45',
views: '9.3K',
description: 'Modern city wedding with rooftop reception',
videoUrl: '#',
tags: ['Urban', 'Modern', 'Celebration']
}
]
},
{
id: 'travel',
title: 'Travel Content',
description: 'Capturing the beauty and essence of destinations worldwide',
videos: [
{
id: 7,
title: 'Japanese Adventure',
thumbnail: 'http://static.photos/travel/320x240/7',
duration: '5:10',
views: '67.2K',
description: 'Cultural exploration through Japan\'s most iconic locations',
videoUrl: '#',
tags: ['Japan', 'Culture', 'Adventure']
},
{
id: 8,
title: 'European Summer',
thumbnail: 'http://static.photos/aerial/320x240/8',
duration: '4:45',
views: '52.9K',
description: 'Summer journey across Mediterranean coastlines',
videoUrl: '#',
tags: ['Europe', 'Summer', 'Coastal']
}
]
},
{
id: 'corporate',
title: 'Corporate Videos',
description: 'Professional business communication and brand storytelling',
videos: [
{
id: 9,
title: 'Company Culture',
thumbnail: 'http://static.photos/office/320x240/9',
duration: '3:15',
views: '8.7K',
description: 'Internal culture video showcasing team values and environment',
videoUrl: '#',
tags: ['Corporate', 'Culture', 'Internal']
},
{
id: 10,
title: 'Annual Report',
thumbnail: 'http://static.photos/finance/320x240/10',
duration: '2:50',
views: '6.3K',
description: 'Animated financial report with company achievements',
videoUrl: '#',
tags: ['Finance', 'Report', 'Animation']
}
]
},
{
id: 'reels',
title: 'Social Media Reels',
description: 'Engaging short-form content optimized for social platforms',
videos: [
{
id: 11,
title: 'Viral Challenge',
thumbnail: 'http://static.photos/gaming/320x240/11',
duration: '0:45',
views: '245K',
description: 'Trending dance challenge with creative transitions',
videoUrl: '#',
tags: ['Trending', 'Dance', 'Viral']
},
{
id: 12,
title: 'Brand Awareness',
thumbnail: 'http://static.photos/minimal/320x240/12',
duration: '0:30',
views: '189K',
description: 'Quick brand message with engaging visual effects',
videoUrl: '#',
tags: ['Brand', 'Awareness', 'Effects']
}
]
},
{
id: 'documentary',
title: 'Documentary',
description: 'In-depth storytelling and real-life narratives',
videos: [
{
id: 13,
title: 'Environmental Impact',
thumbnail: 'http://static.photos/science/320x240/13',
duration: '12:30',
views: '34.6K',
description: 'Climate change documentary featuring expert interviews',
videoUrl: '#',
tags: ['Environment', 'Science', 'Interview']
},
{
id: 14,
title: 'Community Stories',
thumbnail: 'http://static.photos/people/320x240/14',
duration: '15:45',
views: '28.9K',
description: 'Local community resilience and cultural preservation',
videoUrl: '#',
tags: ['Community', 'Culture', 'Resilience']
}
]
}
]
};
// Initialize the portfolio
document.addEventListener('DOMContentLoaded', function() {
initializePortfolio();
setupEventListeners();
});
function initializePortfolio() {
const container = document.getElementById('portfolio-container');
portfolioData.categories.forEach(category => {
const categorySection = createCategorySection(category);
container.appendChild(categorySection);
});
}
function createCategorySection(category) {
const section = document.createElement('section');
section.className = 'mb-12 fade-in-up';
section.innerHTML = `
<div class="mb-6">
<h2 class="text-3xl font-bold text-white mb-2">${category.title}</h2>
<p class="text-gray-400">${category.description}</p>
</div>
<div class="category-row flex space-x-4 overflow-x-auto pb-6">
${category.videos.map(video => `
<div class="video-thumbnail flex-shrink-0 w-64 bg-gray-800 rounded-lg overflow-hidden cursor-pointer group"
data-video-id="${video.id}">
<div class="relative">
<img src="${video.thumbnail}" alt="${video.title}" class="w-full h-36 object-cover">
<div class="absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-30 transition-all duration-300"></div>
<div class="absolute bottom-2 right-2 bg-black bg-opacity-75 px-2 py-1 rounded text-xs">
${video.duration}
</div>
</div>
<div class="p-4">
<h3 class="font-semibold text-white mb-1 group-hover:text-primary-400 transition-colors">
${video.title}
</h3>
<p class="text-gray-400 text-sm mb-2">${video.views} views</p>
<div class="flex flex-wrap gap-1">
${video.tags.map(tag => `
<span class="bg-gray-700 text-gray-300 px-2 py-1 rounded text-xs">${tag}</span>
`).join('')}
</div>
</div>
</div>
`).join('')}
</div>
`;
return section;
}
function setupEventListeners() {
// Video thumbnail click handler
document.addEventListener('click', function(e) {
const thumbnail = e.target.closest('.video-thumbnail');
if (thumbnail) {
const videoId = thumbnail.getAttribute('data-video-id');
openVideoModal(videoId);
}
});
// Navigation scroll behavior
window.addEventListener('scroll', throttle(handleScroll, 100));
}
function openVideoModal(videoId) {
const modal = document.querySelector('custom-video-modal');
if (modal) {
modal.setAttribute('video-id', videoId);
modal.setAttribute('open', 'true');
}
}
function handleScroll() {
const nav = document.querySelector('custom-navigation');
if (window.scrollY > 100) {
nav.setAttribute('scrolled', 'true');
} else {
nav.setAttribute('scrolled', 'false');
}
}
// Utility function to throttle events
function throttle(func, limit) {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
}
}
// Export for use in components if needed
window.portfolioData = portfolioData;