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
Raw History Blame Contribute Delete
11.4 kB
// 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;