| <!DOCTYPE html>
|
| <html lang="en">
|
|
|
| <head>
|
| <meta charset="UTF-8">
|
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| <title>N Priva Comment Generator</title>
|
|
|
|
|
| <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
|
|
|
|
| <style>
|
| |
| |
|
|
|
|
|
|
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
|
|
|
|
|
|
| :root {
|
| --bg-primary: #ffffff;
|
| --bg-secondary: #f5f5f5;
|
| --bg-card: #ffffff;
|
| --text-primary: #161823;
|
| --text-secondary: #545454;
|
| --text-muted: #8a8a8a;
|
| --border-color: #e3e3e3;
|
| --accent-color: #fe2c55;
|
| --accent-hover: #e91e45;
|
| --verified-color: #20d5ec;
|
| --shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
|
| --input-bg: #f1f1f2;
|
| }
|
|
|
| [data-theme="dark"] {
|
| --bg-primary: #121212;
|
| --bg-secondary: #1e1e1e;
|
| --bg-card: #1e1e1e;
|
| --text-primary: #ffffff;
|
| --text-secondary: #b0b0b0;
|
| --text-muted: #6a6a6a;
|
| --border-color: #2f2f2f;
|
| --shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
|
| --input-bg: #2a2a2a;
|
| }
|
|
|
|
|
|
|
|
|
| * {
|
| margin: 0;
|
| padding: 0;
|
| box-sizing: border-box;
|
| }
|
|
|
| body {
|
| font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
| background: var(--bg-primary);
|
| color: var(--text-primary);
|
| min-height: 100vh;
|
| transition: all 0.3s ease;
|
| }
|
|
|
|
|
|
|
|
|
| .header {
|
| background: linear-gradient(135deg, #fe2c55 0%, #25f4ee 100%);
|
| padding: 30px 20px;
|
| text-align: center;
|
| position: relative;
|
| }
|
|
|
| .header h1 {
|
| color: white;
|
| font-size: 2.5rem;
|
| font-weight: 700;
|
| text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2);
|
| display: flex;
|
| align-items: center;
|
| justify-content: center;
|
| gap: 15px;
|
| }
|
|
|
| .header h1 .logo-icon {
|
| width: 50px;
|
| height: 50px;
|
| background: white;
|
| border-radius: 12px;
|
| display: flex;
|
| align-items: center;
|
| justify-content: center;
|
| font-size: 1.8rem;
|
| }
|
|
|
| .header p {
|
| color: rgba(255, 255, 255, 0.9);
|
| margin-top: 10px;
|
| font-size: 1.1rem;
|
| }
|
|
|
| .theme-toggle {
|
| position: absolute;
|
| top: 20px;
|
| right: 20px;
|
| background: rgba(255, 255, 255, 0.2);
|
| border: none;
|
| padding: 12px 20px;
|
| border-radius: 25px;
|
| color: white;
|
| cursor: pointer;
|
| font-size: 1rem;
|
| display: flex;
|
| align-items: center;
|
| gap: 8px;
|
| transition: all 0.3s ease;
|
| backdrop-filter: blur(10px);
|
| }
|
|
|
| .theme-toggle:hover {
|
| background: rgba(255, 255, 255, 0.3);
|
| transform: scale(1.05);
|
| }
|
|
|
|
|
|
|
|
|
| .container {
|
| max-width: 1200px;
|
| margin: 0 auto;
|
| padding: 40px 20px;
|
| display: grid;
|
| grid-template-columns: 1fr 1fr;
|
| gap: 40px;
|
| }
|
|
|
| @media (max-width: 900px) {
|
| .container {
|
| grid-template-columns: 1fr;
|
| }
|
| }
|
|
|
|
|
|
|
|
|
| .card {
|
| background: var(--bg-card);
|
| border-radius: 20px;
|
| padding: 30px;
|
| box-shadow: var(--shadow);
|
| border: 1px solid var(--border-color);
|
| }
|
|
|
| .card-title {
|
| font-size: 1.4rem;
|
| font-weight: 600;
|
| margin-bottom: 25px;
|
| display: flex;
|
| align-items: center;
|
| gap: 10px;
|
| color: var(--text-primary);
|
| }
|
|
|
| .card-title .icon {
|
| width: 35px;
|
| height: 35px;
|
| background: linear-gradient(135deg, #fe2c55, #ff6b81);
|
| border-radius: 10px;
|
| display: flex;
|
| align-items: center;
|
| justify-content: center;
|
| color: white;
|
| }
|
|
|
|
|
|
|
|
|
| .form-group {
|
| margin-bottom: 20px;
|
| }
|
|
|
| .form-group label {
|
| display: block;
|
| margin-bottom: 8px;
|
| font-weight: 500;
|
| color: var(--text-secondary);
|
| font-size: 0.95rem;
|
| }
|
|
|
| .form-group input[type="text"],
|
| .form-group textarea {
|
| width: 100%;
|
| padding: 14px 18px;
|
| border: 2px solid var(--border-color);
|
| border-radius: 12px;
|
| font-size: 1rem;
|
| background: var(--input-bg);
|
| color: var(--text-primary);
|
| transition: all 0.3s ease;
|
| }
|
|
|
| .form-group input[type="text"]:focus,
|
| .form-group textarea:focus {
|
| outline: none;
|
| border-color: var(--accent-color);
|
| box-shadow: 0 0 0 4px rgba(254, 44, 85, 0.1);
|
| }
|
|
|
| .form-group textarea {
|
| resize: vertical;
|
| min-height: 100px;
|
| }
|
|
|
|
|
|
|
|
|
| .toggle-group {
|
| display: flex;
|
| align-items: center;
|
| justify-content: space-between;
|
| padding: 15px;
|
| background: var(--input-bg);
|
| border-radius: 12px;
|
| margin-bottom: 15px;
|
| }
|
|
|
| .toggle-label {
|
| display: flex;
|
| align-items: center;
|
| gap: 10px;
|
| font-weight: 500;
|
| color: var(--text-primary);
|
| }
|
|
|
| .toggle-switch {
|
| position: relative;
|
| width: 55px;
|
| height: 30px;
|
| }
|
|
|
| .toggle-switch input {
|
| opacity: 0;
|
| width: 0;
|
| height: 0;
|
| }
|
|
|
| .toggle-slider {
|
| position: absolute;
|
| cursor: pointer;
|
| top: 0;
|
| left: 0;
|
| right: 0;
|
| bottom: 0;
|
| background-color: var(--border-color);
|
| transition: 0.3s;
|
| border-radius: 30px;
|
| }
|
|
|
| .toggle-slider:before {
|
| position: absolute;
|
| content: "";
|
| height: 24px;
|
| width: 24px;
|
| left: 3px;
|
| bottom: 3px;
|
| background-color: white;
|
| transition: 0.3s;
|
| border-radius: 50%;
|
| box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
| }
|
|
|
| .toggle-switch input:checked+.toggle-slider {
|
| background: linear-gradient(135deg, #20d5ec, #25f4ee);
|
| }
|
|
|
| .toggle-switch input:checked+.toggle-slider:before {
|
| transform: translateX(25px);
|
| }
|
|
|
|
|
|
|
|
|
| .identity-section {
|
| margin-bottom: 25px;
|
| }
|
|
|
| .identity-section h3 {
|
| font-size: 1rem;
|
| color: var(--text-secondary);
|
| margin-bottom: 15px;
|
| font-weight: 500;
|
| }
|
|
|
| .identity-buttons {
|
| display: grid;
|
| grid-template-columns: repeat(4, 1fr);
|
| gap: 12px;
|
| }
|
|
|
| .identity-btn {
|
| padding: 15px 10px;
|
| border: 2px solid var(--border-color);
|
| border-radius: 12px;
|
| background: var(--input-bg);
|
| color: var(--text-primary);
|
| cursor: pointer;
|
| font-size: 0.9rem;
|
| font-weight: 500;
|
| display: flex;
|
| flex-direction: column;
|
| align-items: center;
|
| gap: 8px;
|
| transition: all 0.3s ease;
|
| }
|
|
|
| .identity-btn:hover {
|
| border-color: var(--accent-color);
|
| transform: translateY(-3px);
|
| box-shadow: 0 5px 15px rgba(254, 44, 85, 0.2);
|
| }
|
|
|
| .identity-btn .icon {
|
| font-size: 1.8rem;
|
| }
|
|
|
| .identity-btn.male:hover {
|
| border-color: #3b82f6;
|
| background: rgba(59, 130, 246, 0.1);
|
| }
|
|
|
| .identity-btn.female:hover {
|
| border-color: #ec4899;
|
| background: rgba(236, 72, 153, 0.1);
|
| }
|
|
|
| .identity-btn.celebrity:hover {
|
| border-color: #f59e0b;
|
| background: rgba(245, 158, 11, 0.1);
|
| }
|
|
|
| .identity-btn.realistic:hover {
|
| border-color: #10b981;
|
| background: rgba(16, 185, 129, 0.1);
|
| }
|
|
|
|
|
|
|
|
|
| .profile-upload {
|
| display: flex;
|
| align-items: center;
|
| gap: 20px;
|
| padding: 20px;
|
| background: var(--input-bg);
|
| border-radius: 15px;
|
| margin-bottom: 20px;
|
| }
|
|
|
| .profile-preview {
|
| width: 70px;
|
| height: 70px;
|
| border-radius: 50%;
|
| object-fit: cover;
|
| border: 3px solid var(--accent-color);
|
| }
|
|
|
| .profile-upload-area {
|
| flex: 1;
|
| }
|
|
|
| .upload-btn {
|
| padding: 12px 20px;
|
| background: var(--accent-color);
|
| color: white;
|
| border: none;
|
| border-radius: 10px;
|
| cursor: pointer;
|
| font-weight: 500;
|
| transition: all 0.3s ease;
|
| }
|
|
|
| .upload-btn:hover {
|
| background: var(--accent-hover);
|
| }
|
|
|
| .upload-hint {
|
| font-size: 0.85rem;
|
| color: var(--text-muted);
|
| margin-top: 8px;
|
| }
|
|
|
| #profileInput {
|
| display: none;
|
| }
|
|
|
|
|
|
|
|
|
| .message-style-section {
|
| margin-bottom: 25px;
|
| }
|
|
|
| .message-style-section h3 {
|
| font-size: 1rem;
|
| color: var(--text-secondary);
|
| margin-bottom: 15px;
|
| font-weight: 500;
|
| }
|
|
|
| .style-buttons {
|
| display: grid;
|
| grid-template-columns: repeat(3, 1fr);
|
| gap: 12px;
|
| }
|
|
|
| .style-btn {
|
| padding: 15px 10px;
|
| border: 2px solid var(--border-color);
|
| border-radius: 12px;
|
| background: var(--input-bg);
|
| color: var(--text-primary);
|
| cursor: pointer;
|
| font-size: 0.85rem;
|
| font-weight: 500;
|
| display: flex;
|
| flex-direction: column;
|
| align-items: center;
|
| gap: 8px;
|
| transition: all 0.3s ease;
|
| }
|
|
|
| .style-btn:hover {
|
| border-color: var(--accent-color);
|
| transform: translateY(-2px);
|
| }
|
|
|
| .style-btn.active {
|
| border-color: var(--accent-color);
|
| background: rgba(254, 44, 85, 0.1);
|
| }
|
|
|
| .style-btn .icon {
|
| font-size: 1.5rem;
|
| }
|
|
|
|
|
|
|
|
|
| .advanced-section {
|
| border-top: 1px solid var(--border-color);
|
| padding-top: 20px;
|
| margin-top: 20px;
|
| }
|
|
|
| .advanced-toggle {
|
| display: flex;
|
| align-items: center;
|
| justify-content: space-between;
|
| cursor: pointer;
|
| padding: 15px;
|
| background: var(--input-bg);
|
| border-radius: 12px;
|
| margin-bottom: 15px;
|
| }
|
|
|
| .advanced-toggle:hover {
|
| background: var(--border-color);
|
| }
|
|
|
| .advanced-content {
|
| display: none;
|
| padding: 15px;
|
| background: var(--input-bg);
|
| border-radius: 12px;
|
| margin-top: 10px;
|
| }
|
|
|
| .advanced-content.show {
|
| display: block;
|
| animation: slideDown 0.3s ease;
|
| }
|
|
|
| @keyframes slideDown {
|
| from {
|
| opacity: 0;
|
| transform: translateY(-10px);
|
| }
|
|
|
| to {
|
| opacity: 1;
|
| transform: translateY(0);
|
| }
|
| }
|
|
|
| .blur-slider {
|
| width: 100%;
|
| margin-top: 10px;
|
| }
|
|
|
| .blur-value {
|
| text-align: center;
|
| font-weight: 600;
|
| color: var(--accent-color);
|
| margin-top: 5px;
|
| }
|
|
|
|
|
|
|
|
|
| .preview-section {
|
| position: sticky;
|
| top: 20px;
|
| }
|
|
|
| .comment-preview {
|
| background: var(--bg-card);
|
| border-radius: 20px;
|
| padding: 25px;
|
| border: 1px solid var(--border-color);
|
| }
|
|
|
|
|
| .comment-container {
|
| display: flex;
|
| gap: 15px;
|
| padding: 20px;
|
| background: var(--input-bg);
|
| border-radius: 15px;
|
| transition: all 0.3s ease;
|
| }
|
|
|
|
|
| .comment-container.style-bubble {
|
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| border-radius: 20px 20px 20px 5px;
|
| position: relative;
|
| box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
|
| }
|
|
|
| .comment-container.style-bubble::after {
|
| content: '';
|
| position: absolute;
|
| bottom: 0;
|
| left: -10px;
|
| width: 0;
|
| height: 0;
|
| border: 15px solid transparent;
|
| border-right-color: #764ba2;
|
| border-bottom-color: #764ba2;
|
| border-left: 0;
|
| margin-bottom: -5px;
|
| }
|
|
|
| .comment-container.style-bubble .comment-username,
|
| .comment-container.style-bubble .comment-text,
|
| .comment-container.style-bubble .comment-time,
|
| .comment-container.style-bubble .comment-action {
|
| color: white !important;
|
| }
|
|
|
|
|
| .comment-container.style-card {
|
| background: var(--bg-card);
|
| border: 2px solid var(--accent-color);
|
| border-radius: 16px;
|
| box-shadow: 0 8px 30px rgba(254, 44, 85, 0.15);
|
| padding: 25px;
|
| }
|
|
|
| .comment-avatar {
|
| width: 48px;
|
| height: 48px;
|
| border-radius: 50%;
|
| object-fit: cover;
|
| flex-shrink: 0;
|
| }
|
|
|
| .comment-content {
|
| flex: 1;
|
| }
|
|
|
| .comment-header {
|
| display: flex;
|
| align-items: center;
|
| gap: 8px;
|
| margin-bottom: 6px;
|
| }
|
|
|
| .comment-username {
|
| font-weight: 600;
|
| font-size: 0.95rem;
|
| color: var(--text-primary);
|
| }
|
|
|
| .verified-badge {
|
| width: 16px;
|
| height: 16px;
|
| display: none;
|
| }
|
|
|
| .verified-badge.show {
|
| display: inline-block;
|
| }
|
|
|
| .comment-time {
|
| font-size: 0.8rem;
|
| color: var(--text-muted);
|
| }
|
|
|
| .comment-text {
|
| font-size: 0.95rem;
|
| color: var(--text-primary);
|
| line-height: 1.5;
|
| word-wrap: break-word;
|
| }
|
|
|
| .comment-text.blurred {
|
| filter: blur(var(--blur-amount, 0px));
|
| }
|
|
|
| .comment-actions {
|
| display: flex;
|
| align-items: center;
|
| gap: 20px;
|
| margin-top: 12px;
|
| }
|
|
|
| .comment-action {
|
| display: flex;
|
| align-items: center;
|
| gap: 5px;
|
| color: var(--text-muted);
|
| font-size: 0.85rem;
|
| }
|
|
|
| .comment-action .heart {
|
| color: #fe2c55;
|
| }
|
|
|
| .like-action {
|
| display: flex;
|
| align-items: center;
|
| gap: 5px;
|
| }
|
|
|
| .like-action.hidden {
|
| display: none;
|
| }
|
|
|
|
|
|
|
|
|
| .export-section {
|
| display: grid;
|
| grid-template-columns: 1fr 1fr;
|
| gap: 15px;
|
| margin-top: 25px;
|
| }
|
|
|
| .export-btn {
|
| padding: 16px 25px;
|
| border: none;
|
| border-radius: 12px;
|
| font-size: 1rem;
|
| font-weight: 600;
|
| cursor: pointer;
|
| display: flex;
|
| align-items: center;
|
| justify-content: center;
|
| gap: 10px;
|
| transition: all 0.3s ease;
|
| }
|
|
|
| .export-btn.download {
|
| background: linear-gradient(135deg, #fe2c55, #ff6b81);
|
| color: white;
|
| }
|
|
|
| .export-btn.download:hover {
|
| transform: translateY(-3px);
|
| box-shadow: 0 8px 25px rgba(254, 44, 85, 0.4);
|
| }
|
|
|
| .export-btn.copy {
|
| background: linear-gradient(135deg, #25f4ee, #20d5ec);
|
| color: white;
|
| }
|
|
|
| .export-btn.copy:hover {
|
| transform: translateY(-3px);
|
| box-shadow: 0 8px 25px rgba(32, 213, 236, 0.4);
|
| }
|
|
|
|
|
|
|
|
|
| .toast {
|
| position: fixed;
|
| bottom: 30px;
|
| left: 50%;
|
| transform: translateX(-50%) translateY(100px);
|
| background: #1e1e1e;
|
| color: white;
|
| padding: 16px 30px;
|
| border-radius: 12px;
|
| font-weight: 500;
|
| z-index: 1000;
|
| opacity: 0;
|
| transition: all 0.4s ease;
|
| display: flex;
|
| align-items: center;
|
| gap: 10px;
|
| }
|
|
|
| .toast.show {
|
| transform: translateX(-50%) translateY(0);
|
| opacity: 1;
|
| }
|
|
|
| .toast.success {
|
| background: linear-gradient(135deg, #10b981, #059669);
|
| }
|
|
|
|
|
|
|
|
|
| .footer {
|
| text-align: center;
|
| padding: 30px;
|
| color: var(--text-muted);
|
| font-size: 0.9rem;
|
| }
|
|
|
| .footer a {
|
| color: var(--accent-color);
|
| text-decoration: none;
|
| }
|
|
|
|
|
|
|
|
|
| .style-switcher {
|
| display: flex;
|
| gap: 10px;
|
| margin-bottom: 20px;
|
| justify-content: center;
|
| }
|
|
|
| .style-switch-btn {
|
| padding: 10px 20px;
|
| border: 2px solid var(--border-color);
|
| border-radius: 25px;
|
| background: var(--input-bg);
|
| color: var(--text-primary);
|
| cursor: pointer;
|
| font-size: 0.85rem;
|
| font-weight: 500;
|
| transition: all 0.3s ease;
|
| }
|
|
|
| .style-switch-btn:hover {
|
| border-color: var(--accent-color);
|
| }
|
|
|
| .style-switch-btn.active {
|
| background: var(--accent-color);
|
| color: white;
|
| border-color: var(--accent-color);
|
| }
|
|
|
|
|
|
|
|
|
| @media (max-width: 600px) {
|
| .header h1 {
|
| font-size: 1.8rem;
|
| }
|
|
|
| .theme-toggle {
|
| position: static;
|
| margin-top: 15px;
|
| }
|
|
|
| .identity-buttons {
|
| grid-template-columns: repeat(2, 1fr);
|
| }
|
|
|
| .style-buttons {
|
| grid-template-columns: 1fr;
|
| }
|
|
|
| .export-section {
|
| grid-template-columns: 1fr;
|
| }
|
|
|
| .card {
|
| padding: 20px;
|
| }
|
|
|
| .style-switcher {
|
| flex-wrap: wrap;
|
| }
|
| }
|
|
|
|
|
|
|
| |
| |
|
|
| </style>
|
| </head>
|
|
|
| <body data-theme="light">
|
|
|
| |
| |
|
|
| <header class="header">
|
| <h1>
|
| <span class="logo-icon">🎵</span>
|
| N Priva Comment Generator
|
| </h1>
|
| <p>Create realistic TikTok-style comments in seconds</p>
|
| <button class="theme-toggle" onclick="toggleTheme()">
|
| <span id="themeIcon">🌙</span>
|
| <span id="themeText">Dark Mode</span>
|
| </button>
|
| </header>
|
| |
| |
|
|
|
|
| |
| |
|
|
| <main class="container">
|
|
|
| |
| |
|
|
| <div class="card editor-panel">
|
| <h2 class="card-title">
|
| <span class="icon">✏️</span>
|
| Comment Editor
|
| </h2>
|
|
|
|
|
| <div class="identity-section">
|
| <h3>🎲 Random Identity Generator</h3>
|
| <div class="identity-buttons">
|
| <button class="identity-btn male" onclick="generateIdentity('male')">
|
| <span class="icon">👨</span>
|
| Male
|
| </button>
|
| <button class="identity-btn female" onclick="generateIdentity('female')">
|
| <span class="icon">👩</span>
|
| Female
|
| </button>
|
| <button class="identity-btn celebrity" onclick="generateIdentity('celebrity')">
|
| <span class="icon">⭐</span>
|
| Celebrity
|
| </button>
|
|
|
| <button class="identity-btn realistic" onclick="generateIdentity('realistic')">
|
| <span class="icon">📸</span>
|
| Realistic
|
| </button>
|
|
|
| </div>
|
| </div>
|
|
|
|
|
|
|
| <div class="profile-upload">
|
| <img src="https://api.dicebear.com/7.x/avataaars/svg?seed=default" alt="Profile" class="profile-preview"
|
| id="profilePreview">
|
| <div class="profile-upload-area">
|
| <button class="upload-btn" onclick="document.getElementById('profileInput').click()">
|
| 📷 Upload Photo
|
| </button>
|
| <p class="upload-hint">Or use Random Identity above</p>
|
| <input type="file" id="profileInput" accept="image/*" onchange="handleImageUpload(event)">
|
| </div>
|
| </div>
|
|
|
|
|
|
|
| <div class="form-group">
|
| <label for="username">Username</label>
|
| <input type="text" id="username" placeholder="Enter username..." value="user_name"
|
| oninput="updatePreview()">
|
| </div>
|
|
|
|
|
|
|
| <div class="form-group">
|
| <label for="commentText">Comment Text</label>
|
| <textarea id="commentText" placeholder="Write your comment here..."
|
| oninput="updatePreview()">This is an amazing video! 🔥❤️</textarea>
|
| </div>
|
|
|
|
|
|
|
| <div class="form-group">
|
| <label for="likeCount">Like Count</label>
|
| <input type="text" id="likeCount" placeholder="e.g., 1.2K" value="2.5K" oninput="updatePreview()">
|
| </div>
|
|
|
|
|
|
|
| <div class="toggle-group">
|
| <span class="toggle-label">
|
| <span>❤️</span>
|
| Show Like Icon
|
| </span>
|
| <label class="toggle-switch">
|
| <input type="checkbox" id="likeIconToggle" checked onchange="updatePreview()">
|
| <span class="toggle-slider"></span>
|
| </label>
|
| </div>
|
|
|
|
|
|
|
| <div class="form-group">
|
| <label for="timeAgo">Time</label>
|
| <input type="text" id="timeAgo" placeholder="e.g., 2h, 1d, 3w" value="2h" oninput="updatePreview()">
|
| </div>
|
|
|
|
|
|
|
| <div class="toggle-group">
|
| <span class="toggle-label">
|
| <span>✓</span>
|
| Verified Badge (Blue Tick)
|
| </span>
|
| <label class="toggle-switch">
|
| <input type="checkbox" id="verifiedToggle" onchange="updatePreview()">
|
| <span class="toggle-slider"></span>
|
| </label>
|
| </div>
|
|
|
|
|
|
|
| <div class="message-style-section">
|
| <h3>💬 Advanced Message Styles</h3>
|
| <div class="style-buttons">
|
| <button class="style-btn active" onclick="changeMessageStyle('default')" id="styleDefault">
|
| <span class="icon">📝</span>
|
| Default
|
| </button>
|
| <button class="style-btn" onclick="changeMessageStyle('bubble')" id="styleBubble">
|
| <span class="icon">💭</span>
|
| Bubble
|
| </button>
|
| <button class="style-btn" onclick="changeMessageStyle('card')" id="styleCard">
|
| <span class="icon">🎴</span>
|
| Card
|
| </button>
|
| </div>
|
| </div>
|
|
|
|
|
|
|
| <div class="advanced-section">
|
| <div class="advanced-toggle" onclick="toggleAdvanced()">
|
| <span class="toggle-label">
|
| <span>⚙️</span>
|
| Advanced Edit
|
| </span>
|
| <span id="advancedArrow">▼</span>
|
| </div>
|
|
|
| <div class="advanced-content" id="advancedContent">
|
|
|
| <div class="form-group">
|
| <label for="blurSlider">Blur Text Effect</label>
|
| <input type="range" id="blurSlider" class="blur-slider" min="0" max="10" value="0"
|
| oninput="updateBlur()">
|
| <p class="blur-value" id="blurValue">0px</p>
|
| </div>
|
|
|
|
|
|
|
| <div class="toggle-group">
|
| <span class="toggle-label">
|
| <span>💬</span>
|
| Show Reply Count
|
| </span>
|
| <label class="toggle-switch">
|
| <input type="checkbox" id="replyToggle" checked onchange="updatePreview()">
|
| <span class="toggle-slider"></span>
|
| </label>
|
| </div>
|
|
|
|
|
|
|
| <div class="form-group" id="replyCountGroup">
|
| <label for="replyCount">Reply Count</label>
|
| <input type="text" id="replyCount" placeholder="e.g., 50" value="12" oninput="updatePreview()">
|
| </div>
|
|
|
| </div>
|
| </div>
|
|
|
|
|
| </div>
|
| |
| |
|
|
|
|
| |
| |
|
|
| <div class="card preview-section">
|
| <h2 class="card-title">
|
| <span class="icon">👁️</span>
|
| Live Preview
|
| </h2>
|
|
|
|
|
| <div class="style-switcher">
|
| <button class="style-switch-btn active" onclick="switchPreviewStyle('default')"
|
| id="previewStyleDefault">
|
| Style 1
|
| </button>
|
| <button class="style-switch-btn" onclick="switchPreviewStyle('bubble')" id="previewStyleBubble">
|
| Style 2
|
| </button>
|
| <button class="style-switch-btn" onclick="switchPreviewStyle('card')" id="previewStyleCard">
|
| Style 3
|
| </button>
|
| </div>
|
|
|
|
|
|
|
| <div class="comment-preview" id="commentPreview">
|
| <div class="comment-container" id="commentContainer">
|
| <img src="https://api.dicebear.com/7.x/avataaars/svg?seed=default" alt="Avatar"
|
| class="comment-avatar" id="commentAvatar">
|
| <div class="comment-content">
|
| <div class="comment-header">
|
| <span class="comment-username" id="previewUsername">user_name</span>
|
|
|
|
|
| <svg class="verified-badge" id="verifiedBadge" viewBox="0 0 20 20" fill="#20d5ec">
|
| <path fill-rule="evenodd"
|
| d="M6.267 3.455a3.066 3.066 0 001.745-.723 3.066 3.066 0 013.976 0 3.066 3.066 0 001.745.723 3.066 3.066 0 012.812 2.812c.051.643.304 1.254.723 1.745a3.066 3.066 0 010 3.976 3.066 3.066 0 00-.723 1.745 3.066 3.066 0 01-2.812 2.812 3.066 3.066 0 00-1.745.723 3.066 3.066 0 01-3.976 0 3.066 3.066 0 00-1.745-.723 3.066 3.066 0 01-2.812-2.812 3.066 3.066 0 00-.723-1.745 3.066 3.066 0 010-3.976 3.066 3.066 0 00.723-1.745 3.066 3.066 0 012.812-2.812zm7.44 5.252a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
|
| clip-rule="evenodd" />
|
| </svg>
|
|
|
|
|
| <span class="comment-time" id="previewTime">2h</span>
|
| </div>
|
| <p class="comment-text" id="previewText">This is an amazing video! 🔥❤️</p>
|
| <div class="comment-actions">
|
|
|
| <span class="comment-action like-action" id="likeAction">
|
| <span class="heart">❤️</span>
|
| <span id="previewLikes">2.5K</span>
|
| </span>
|
|
|
| <span class="comment-action" id="replyAction">
|
| <span>💬</span>
|
| <span id="previewReplies">12</span> replies
|
| </span>
|
| </div>
|
| </div>
|
| </div>
|
| </div>
|
|
|
|
|
|
|
| <div class="export-section">
|
| <button class="export-btn download" onclick="downloadImage()">
|
| <span>📥</span>
|
| Download Image
|
| </button>
|
| <button class="export-btn copy" onclick="copyToClipboard()">
|
| <span>📋</span>
|
| Copy to Clipboard
|
| </button>
|
| </div>
|
|
|
|
|
| </div>
|
| |
| |
|
|
|
|
| </main>
|
| |
| |
|
|
|
|
| |
| |
|
|
| <div class="toast" id="toast">
|
| <span id="toastIcon">✓</span>
|
| <span id="toastMessage">Success!</span>
|
| </div>
|
| |
| |
|
|
|
|
| |
| |
|
|
| <footer class="footer">
|
| <p>Made with ❤️ by N Priva | Generate unlimited TikTok-style comments</p>
|
| </footer>
|
| |
| |
|
|
|
|
| |
| |
|
|
| <script>
|
|
|
|
|
|
|
|
|
|
|
| const maleNames = [
|
| 'james_smith', 'michael_johnson', 'david_williams', 'chris_brown',
|
| 'daniel_jones', 'matthew_davis', 'andrew_miller', 'joshua_wilson',
|
| 'ryan_taylor', 'brandon_anderson', 'kevin_thomas', 'jason_jackson',
|
| 'justin_white', 'tyler_harris', 'austin_martin', 'zachary_thompson',
|
| 'alex_garcia', 'nathan_martinez', 'adam_robinson', 'ethan_clark'
|
| ];
|
|
|
|
|
|
|
| const femaleNames = [
|
| 'emma_watson', 'olivia_jones', 'sophia_williams', 'isabella_brown',
|
| 'mia_johnson', 'charlotte_davis', 'amelia_miller', 'harper_wilson',
|
| 'evelyn_moore', 'abigail_taylor', 'emily_anderson', 'elizabeth_thomas',
|
| 'avery_jackson', 'ella_white', 'scarlett_harris', 'grace_martin',
|
| 'lily_thompson', 'chloe_garcia', 'victoria_martinez', 'riley_robinson'
|
| ];
|
|
|
|
|
|
|
| const celebrityNames = [
|
| 'therock', 'kyliejenner', 'kimkardashian', 'selenagomez',
|
| 'arianagrande', 'beyonce', 'taylorswift', 'justinbieber',
|
| 'cristiano', 'leomessi', 'neymarjr', 'kingjames',
|
| 'travisscott', 'nickiminaj', 'badgalriri', 'theweeknd',
|
| 'billieeilish', 'charlidamelio', 'addisonraee', 'khloekardashian'
|
| ];
|
|
|
|
|
|
|
| const realisticNames = [
|
| 'john_doe_99', 'sarah_miller', 'mike_wilson', 'emily_davis',
|
| 'alex_johnson', 'jessica_brown', 'david_smith', 'amanda_jones',
|
| 'chris_taylor', 'ashley_anderson', 'ryan_thomas', 'stephanie_white',
|
| 'kevin_martin', 'nicole_garcia', 'brian_martinez', 'michelle_robinson',
|
| 'jason_lee', 'jennifer_clark', 'mark_lewis', 'lisa_walker'
|
| ];
|
|
|
|
|
|
|
| let currentStyle = 'default';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function toggleTheme() {
|
| const body = document.body;
|
| const themeIcon = document.getElementById('themeIcon');
|
| const themeText = document.getElementById('themeText');
|
|
|
| if (body.getAttribute('data-theme') === 'light') {
|
| body.setAttribute('data-theme', 'dark');
|
| themeIcon.textContent = '☀️';
|
| themeText.textContent = 'Light Mode';
|
| } else {
|
| body.setAttribute('data-theme', 'light');
|
| themeIcon.textContent = '🌙';
|
| themeText.textContent = 'Dark Mode';
|
| }
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function updatePreview() {
|
|
|
| const username = document.getElementById('username').value || 'username';
|
| const commentText = document.getElementById('commentText').value || 'Your comment here...';
|
| const likeCount = document.getElementById('likeCount').value || '0';
|
| const timeAgo = document.getElementById('timeAgo').value || '1h';
|
| const replyCount = document.getElementById('replyCount').value || '0';
|
| const isVerified = document.getElementById('verifiedToggle').checked;
|
| const showReplies = document.getElementById('replyToggle').checked;
|
| const showLikeIcon = document.getElementById('likeIconToggle').checked;
|
|
|
|
|
|
|
| document.getElementById('previewUsername').textContent = username;
|
| document.getElementById('previewText').textContent = commentText;
|
| document.getElementById('previewLikes').textContent = likeCount;
|
| document.getElementById('previewTime').textContent = timeAgo;
|
| document.getElementById('previewReplies').textContent = replyCount;
|
|
|
|
|
|
|
| const verifiedBadge = document.getElementById('verifiedBadge');
|
| if (isVerified) {
|
| verifiedBadge.classList.add('show');
|
| } else {
|
| verifiedBadge.classList.remove('show');
|
| }
|
|
|
|
|
|
|
| const likeAction = document.getElementById('likeAction');
|
| if (showLikeIcon) {
|
| likeAction.classList.remove('hidden');
|
| } else {
|
| likeAction.classList.add('hidden');
|
| }
|
|
|
|
|
|
|
| const replyAction = document.getElementById('replyAction');
|
| const replyCountGroup = document.getElementById('replyCountGroup');
|
| if (showReplies) {
|
| replyAction.style.display = 'flex';
|
| replyCountGroup.style.display = 'block';
|
| } else {
|
| replyAction.style.display = 'none';
|
| replyCountGroup.style.display = 'none';
|
| }
|
|
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| async function fetchImageAsBase64(url) {
|
|
|
| const blobToBase64 = (blob) => {
|
| return new Promise((resolve, reject) => {
|
| const reader = new FileReader();
|
| reader.onloadend = () => resolve(reader.result);
|
| reader.onerror = reject;
|
| reader.readAsDataURL(blob);
|
| });
|
| };
|
|
|
| try {
|
|
|
| const response = await fetch(url);
|
| if (!response.ok) throw new Error('Direct fetch failed');
|
| const blob = await response.blob();
|
| return await blobToBase64(blob);
|
| } catch (directError) {
|
| console.warn('Direct fetch failed, trying proxy...', directError);
|
| try {
|
|
|
|
|
| const proxyUrl = 'https://corsproxy.io/?' + encodeURIComponent(url);
|
| const response = await fetch(proxyUrl);
|
| if (!response.ok) throw new Error('Proxy fetch failed');
|
| const blob = await response.blob();
|
| return await blobToBase64(blob);
|
| } catch (proxyError) {
|
| console.error('Error fetching image via proxy:', proxyError);
|
| return null;
|
| }
|
| }
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| async function generateIdentity(type) {
|
| let name;
|
| let avatarUrl;
|
|
|
|
|
| if (type === 'male') {
|
| name = maleNames[Math.floor(Math.random() * maleNames.length)];
|
|
|
| avatarUrl = `https://api.dicebear.com/7.x/avataaars/png?seed=male${Math.random()}`;
|
| } else if (type === 'female') {
|
| name = femaleNames[Math.floor(Math.random() * femaleNames.length)];
|
|
|
| avatarUrl = `https://api.dicebear.com/7.x/avataaars/png?seed=female${Math.random()}`;
|
| } else if (type === 'celebrity') {
|
| name = celebrityNames[Math.floor(Math.random() * celebrityNames.length)];
|
|
|
| avatarUrl = `https://api.dicebear.com/7.x/initials/png?seed=${name}`;
|
|
|
| document.getElementById('verifiedToggle').checked = true;
|
| } else if (type === 'realistic') {
|
|
|
| try {
|
| const response = await fetch('https://randomuser.me/api/');
|
| const data = await response.json();
|
| const user = data.results[0];
|
| name = user.login.username;
|
| avatarUrl = user.picture.large;
|
| } catch (e) {
|
|
|
| name = realisticNames[Math.floor(Math.random() * realisticNames.length)];
|
| const gender = Math.random() > 0.5 ? 'men' : 'women';
|
| const randomNum = Math.floor(Math.random() * 99) + 1;
|
| avatarUrl = `https://randomuser.me/api/portraits/${gender}/${randomNum}.jpg`;
|
| }
|
|
|
| }
|
|
|
|
|
|
|
| showToast('Generating identity...', 'info');
|
|
|
|
|
| const base64Image = await fetchImageAsBase64(avatarUrl);
|
|
|
| if (base64Image) {
|
|
|
| document.getElementById('profilePreview').src = base64Image;
|
| document.getElementById('commentAvatar').src = base64Image;
|
|
|
|
|
| showToast(`Generated ${type} identity: ${name}`, 'success');
|
| } else {
|
|
|
| document.getElementById('profilePreview').src = avatarUrl;
|
| document.getElementById('commentAvatar').src = avatarUrl;
|
| showToast(`Generated identity (standard load): ${name}`, 'warning');
|
| }
|
|
|
|
|
| document.getElementById('username').value = name;
|
|
|
|
|
|
|
| updatePreview();
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function changeMessageStyle(style) {
|
| currentStyle = style;
|
|
|
|
|
| document.querySelectorAll('.style-btn').forEach(btn => {
|
| btn.classList.remove('active');
|
| });
|
|
|
|
|
|
|
| if (style === 'default') {
|
| document.getElementById('styleDefault').classList.add('active');
|
| } else if (style === 'bubble') {
|
| document.getElementById('styleBubble').classList.add('active');
|
| } else if (style === 'card') {
|
| document.getElementById('styleCard').classList.add('active');
|
| }
|
|
|
|
|
|
|
| applyMessageStyle(style);
|
|
|
|
|
| showToast(`Style changed to ${style}`, 'success');
|
| }
|
|
|
| function switchPreviewStyle(style) {
|
| currentStyle = style;
|
|
|
|
|
| document.querySelectorAll('.style-switch-btn').forEach(btn => {
|
| btn.classList.remove('active');
|
| });
|
|
|
|
|
|
|
| if (style === 'default') {
|
| document.getElementById('previewStyleDefault').classList.add('active');
|
| } else if (style === 'bubble') {
|
| document.getElementById('previewStyleBubble').classList.add('active');
|
| } else if (style === 'card') {
|
| document.getElementById('previewStyleCard').classList.add('active');
|
| }
|
|
|
|
|
|
|
| applyMessageStyle(style);
|
|
|
| }
|
|
|
| function applyMessageStyle(style) {
|
| const container = document.getElementById('commentContainer');
|
|
|
|
|
| container.classList.remove('style-bubble', 'style-card');
|
|
|
|
|
|
|
| if (style === 'bubble') {
|
| container.classList.add('style-bubble');
|
| } else if (style === 'card') {
|
| container.classList.add('style-card');
|
| }
|
|
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function handleImageUpload(event) {
|
| const file = event.target.files[0];
|
| if (file) {
|
| const reader = new FileReader();
|
| reader.onload = function (e) {
|
| document.getElementById('profilePreview').src = e.target.result;
|
| document.getElementById('commentAvatar').src = e.target.result;
|
| showToast('Profile picture uploaded!', 'success');
|
| };
|
| reader.readAsDataURL(file);
|
| }
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function toggleAdvanced() {
|
| const content = document.getElementById('advancedContent');
|
| const arrow = document.getElementById('advancedArrow');
|
|
|
| content.classList.toggle('show');
|
| arrow.textContent = content.classList.contains('show') ? '▲' : '▼';
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function updateBlur() {
|
| const blurValue = document.getElementById('blurSlider').value;
|
| const commentText = document.getElementById('previewText');
|
|
|
| commentText.style.filter = `blur(${blurValue}px)`;
|
| document.getElementById('blurValue').textContent = `${blurValue}px`;
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| async function downloadImage() {
|
| const element = document.getElementById('commentContainer');
|
|
|
| try {
|
|
|
| const canvas = await html2canvas(element, {
|
| backgroundColor: null,
|
| scale: 3,
|
| useCORS: true,
|
| allowTaint: false,
|
| onclone: (clonedDoc) => {
|
|
|
| const clonedEl = clonedDoc.getElementById('commentContainer');
|
| if (clonedEl.classList.contains('style-bubble')) {
|
| clonedEl.style.marginLeft = "15px";
|
| clonedEl.style.marginRight = "15px";
|
| }
|
| }
|
| });
|
|
|
|
|
|
|
| const link = document.createElement('a');
|
| link.download = 'npriva-comment-' + Date.now() + '.png';
|
| link.href = canvas.toDataURL('image/png');
|
| link.click();
|
|
|
|
|
| showToast('Image downloaded successfully!', 'success');
|
| } catch (error) {
|
| showToast('Error generating image', 'error');
|
| console.error(error);
|
| }
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| async function copyToClipboard() {
|
| const element = document.getElementById('commentContainer');
|
|
|
| try {
|
|
|
| const canvas = await html2canvas(element, {
|
| backgroundColor: null,
|
| scale: 2,
|
| useCORS: true,
|
| allowTaint: true
|
| });
|
|
|
|
|
|
|
| canvas.toBlob(async (blob) => {
|
| try {
|
| await navigator.clipboard.write([
|
| new ClipboardItem({ 'image/png': blob })
|
| ]);
|
| showToast('Copied to clipboard!', 'success');
|
| } catch (err) {
|
|
|
| showToast('Clipboard access denied. Try downloading instead.', 'error');
|
| }
|
| });
|
|
|
|
|
| } catch (error) {
|
| showToast('Error copying image', 'error');
|
| console.error(error);
|
| }
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| function showToast(message, type = 'success') {
|
| const toast = document.getElementById('toast');
|
| const toastIcon = document.getElementById('toastIcon');
|
| const toastMessage = document.getElementById('toastMessage');
|
|
|
|
|
| toastMessage.textContent = message;
|
| toastIcon.textContent = type === 'success' ? '✓' : '✕';
|
| toast.className = 'toast ' + type;
|
|
|
|
|
|
|
| toast.classList.add('show');
|
|
|
|
|
|
|
| setTimeout(() => {
|
| toast.classList.remove('show');
|
| }, 3000);
|
|
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| document.addEventListener('DOMContentLoaded', function () {
|
| updatePreview();
|
|
|
|
|
| const previewContainer = document.getElementById('commentContainer');
|
|
|
|
|
| previewContainer.addEventListener('contextmenu', function (e) {
|
| e.preventDefault();
|
| if (confirm('Do you want to download this image?')) {
|
| downloadImage();
|
| }
|
| });
|
|
|
|
|
| let pressTimer;
|
| previewContainer.addEventListener('touchstart', function (e) {
|
| pressTimer = setTimeout(function () {
|
| if (confirm('Do you want to download this image?')) {
|
| downloadImage();
|
| }
|
| }, 800);
|
| });
|
|
|
| previewContainer.addEventListener('touchend', function (e) {
|
| clearTimeout(pressTimer);
|
| });
|
| previewContainer.addEventListener('touchmove', function (e) {
|
| clearTimeout(pressTimer);
|
| });
|
|
|
| });
|
|
|
|
|
|
|
|
|
| </script>
|
| |
| |
|
|
|
|
| </body>
|
|
|
| </html> |