create a fully functional ppt editing canvas where i put my html code and think it of like so i have created a presentation agent that will generate ppt using html css js example generated ppt
Browse filesso i want that you create me a full functional and generalised web ui where i input the code of ppt and so i can edit the components in the ppt like edit the text move the image charts etc. to anywhere seemlessly i want that the ui should be very good and should adjust to the size of the ppt it should be generalised and effective as it will be given to the end user so it should be working accurately i hope you understand what i want. think of a canvas where i can do anything ove anything
the slides are 16:9 so they should be properly visble they can contain images, charts etc.
eg ppt fcode
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Introduction to Thermodynamics</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #f5f5f5;
padding: 20px;
}
.slide-container {
width: 1280px;
min-height: 720px;
display: flex;
flex-direction: column;
font-family: 'Montserrat', sans-serif;
position: relative;
background-color: #ffffff;
color: #333333;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
padding: 40px;
}
.slide-header {
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 2px solid #003366;
}
.slide-header h1 {
font-size: 36px;
font-weight: 600;
color: #003366;
}
.content-wrapper {
display: flex;
flex: 1;
gap: 30px;
margin-top: 10px;
}
.text-content {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.text-section {
margin-bottom: 25px;
}
.text-section h3 {
font-size: 20px;
font-weight: 600;
color: #003366;
margin-bottom: 10px;
}
.text-section p, .text-section li {
font-size: 16px;
line-height: 1.5;
margin-bottom: 8px;
}
.text-section ul {
list-style-type: none;
padding-left: 0;
}
.text-section li {
position: relative;
padding-left: 20px;
}
.text-section li:before {
content: "•";
color: #003366;
font-weight: bold;
position: absolute;
left: 0;
}
.image-content {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.image-content img {
max-width: 100%;
height: auto;
border: 1px solid #ddd;
border-radius: 4px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.fig-caption {
font-size: 14px;
color: #666;
margin-top: 10px;
text-align: center;
font-style: italic;
}
.slide-footer {
position: absolute;
bottom: 20px;
right: 20px;
font-size: 14px;
color: #666;
}
@media
(max-width: 1300px) {
.slide-container {
width: 100%;
min-height: 600px;
}
}
</style>
</head>
<body>
<div class="slide-container">
<div class="slide-header">
<h1>Introduction to Thermodynamics</h1>
</div>
<div class="content-wrapper">
<div class="text-content">
<div class="text-section">
<h3>Definition</h3>
<p>Thermodynamics is the branch of physics that deals with the relationships between heat, work, temperature, energy, and the laws governing energy conversion.</p>
</div>
<div class="text-section">
<h3>Key Concepts</h3>
<ul>
<li><strong>Energy:</strong> Capacity to do work or produce heat</li>
<li><strong>Temperature:</strong> Measure of average kinetic energy</li>
<li><strong>Entropy:</strong> Measure of disorder or randomness</li>
<li><strong>Thermal Equilibrium:</strong> State where no heat transfer occurs</li>
</ul>
</div>
<div class="text-section">
<h3>Importance</h3>
<p>Thermodynamics forms the foundation for engineering disciplines, chemical processes, physical theories, and explains everyday phenomena from engine operation to climate systems.</p>
</div>
</div>
<div class="image-content">
<img src="https://www.chemistrylearner.com/wp-content/uploads/2022/08/Laws-of-Thermodynamics.jpg" alt="Thermodynamic System and Surroundings">
<p class="fig-caption">Fig 2.1 Thermodynamic System and Surroundings</p>
</div>
</div>
<div class="slide-footer">
Slide 2
</div>
</div>
</body>
</html>
give attention to detail
- README.md +8 -5
- components/navbar.js +74 -0
- components/sidebar.js +189 -0
- index.html +272 -19
- script.js +359 -0
- style.css +186 -18
|
@@ -1,10 +1,13 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: SlideCraft Studio 🎨
|
| 3 |
+
colorFrom: blue
|
| 4 |
+
colorTo: pink
|
| 5 |
+
emoji: 🐳
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
+
tags:
|
| 9 |
+
- deepsite-v3
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Welcome to your new DeepSite project!
|
| 13 |
+
This project was created with [DeepSite](https://huggingface.co/deepsite).
|
|
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class CustomNavbar extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
this.attachShadow({ mode: 'open' });
|
| 4 |
+
this.shadowRoot.innerHTML = `
|
| 5 |
+
<style>
|
| 6 |
+
nav {
|
| 7 |
+
background: linear-gradient(135deg, #3B82F6 0%, #1E40AF 100%);
|
| 8 |
+
color: white;
|
| 9 |
+
padding: 1rem 0;
|
| 10 |
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
.nav-container {
|
| 14 |
+
max-width: 1200px;
|
| 15 |
+
margin: 0 auto;
|
| 16 |
+
padding: 0 1rem;
|
| 17 |
+
display: flex;
|
| 18 |
+
justify-content: space-between;
|
| 19 |
+
align-items: center;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
.logo {
|
| 23 |
+
display: flex;
|
| 24 |
+
align-items: center;
|
| 25 |
+
font-size: 1.5rem;
|
| 26 |
+
font-weight: bold;
|
| 27 |
+
}
|
| 28 |
+
|
| 29 |
+
.nav-links {
|
| 30 |
+
display: flex;
|
| 31 |
+
align-items: center;
|
| 32 |
+
gap: 2rem;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
.nav-link {
|
| 36 |
+
color: white;
|
| 37 |
+
text-decoration: none;
|
| 38 |
+
padding: 0.5rem 1rem;
|
| 39 |
+
border-radius: 6px;
|
| 40 |
+
transition: background-color 0.2s ease;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
.nav-link:hover {
|
| 44 |
+
background-color: rgba(255, 255, 255, 0.1);
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
@media (max-width: 768px) {
|
| 48 |
+
.nav-links {
|
| 49 |
+
gap: 1rem;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
.logo {
|
| 53 |
+
font-size: 1.25rem;
|
| 54 |
+
}
|
| 55 |
+
}
|
| 56 |
+
</style>
|
| 57 |
+
<nav>
|
| 58 |
+
<div class="nav-container">
|
| 59 |
+
<div class="logo">
|
| 60 |
+
<i data-feather="layout"></i>
|
| 61 |
+
<span class="ml-2">SlideCraft Studio</span>
|
| 62 |
+
</div>
|
| 63 |
+
<div class="nav-links">
|
| 64 |
+
<a href="#" class="nav-link">Home</a>
|
| 65 |
+
<a href="#" class="nav-link">Templates</a>
|
| 66 |
+
<a href="#" class="nav-link">Help</a>
|
| 67 |
+
</div>
|
| 68 |
+
</div>
|
| 69 |
+
</nav>
|
| 70 |
+
`;
|
| 71 |
+
}
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
customElements.define('custom-navbar', CustomNavbar);
|
|
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class CustomSidebar extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
this.attachShadow({ mode: 'open' });
|
| 4 |
+
this.shadowRoot.innerHTML = `
|
| 5 |
+
<style>
|
| 6 |
+
.sidebar {
|
| 7 |
+
background: white;
|
| 8 |
+
border-radius: 12px;
|
| 9 |
+
padding: 1.5rem;
|
| 10 |
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
.sidebar-section {
|
| 14 |
+
margin-bottom: 2rem;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
.sidebar-title {
|
| 18 |
+
font-size: 1.125rem;
|
| 19 |
+
font-weight: 600;
|
| 20 |
+
color: #1f2937;
|
| 21 |
+
margin-bottom: 1rem;
|
| 22 |
+
display: flex;
|
| 23 |
+
align-items: center;
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
.sidebar-title i {
|
| 27 |
+
margin-right: 0.5rem;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
.element-btn {
|
| 31 |
+
display: flex;
|
| 32 |
+
align-items: center;
|
| 33 |
+
width: 100%;
|
| 34 |
+
padding: 0.75rem 1rem;
|
| 35 |
+
border: 1px solid #e5e7eb;
|
| 36 |
+
border-radius: 8px;
|
| 37 |
+
margin-bottom: 0.5rem;
|
| 38 |
+
cursor: pointer;
|
| 39 |
+
transition: all 0.2s ease;
|
| 40 |
+
background: white;
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
.element-btn:hover {
|
| 44 |
+
background: #f3f4f6;
|
| 45 |
+
border-color: #3B82F6;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
.element-btn i {
|
| 49 |
+
margin-right: 0.5rem;
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
.slide-thumbnail {
|
| 53 |
+
width: 100%;
|
| 54 |
+
aspect-ratio: 16/9;
|
| 55 |
+
background: #f8fafc;
|
| 56 |
+
border: 2px dashed #cbd5e1;
|
| 57 |
+
border-radius: 8px;
|
| 58 |
+
display: flex;
|
| 59 |
+
align-items: center;
|
| 60 |
+
justify-content: center;
|
| 61 |
+
margin-bottom: 0.75rem;
|
| 62 |
+
cursor: pointer;
|
| 63 |
+
transition: all 0.2s ease;
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
.slide-thumbnail:hover {
|
| 67 |
+
border-color: #3B82F6;
|
| 68 |
+
background: #eff6ff;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
.slide-thumbnail.active {
|
| 72 |
+
border-color: #1E40AF;
|
| 73 |
+
background: #dbeafe;
|
| 74 |
+
}
|
| 75 |
+
</style>
|
| 76 |
+
<div class="sidebar">
|
| 77 |
+
<div class="sidebar-section">
|
| 78 |
+
<h3 class="sidebar-title">
|
| 79 |
+
<i data-feather="plus"></i>
|
| 80 |
+
Add Elements
|
| 81 |
+
</h3>
|
| 82 |
+
<button class="element-btn" data-type="text">
|
| 83 |
+
<i data-feather="type"></i>
|
| 84 |
+
Text Box
|
| 85 |
+
</button>
|
| 86 |
+
<button class="element-btn" data-type="image">
|
| 87 |
+
<i data-feather="image"></i>
|
| 88 |
+
Image
|
| 89 |
+
</button>
|
| 90 |
+
<button class="element-btn" data-type="shape">
|
| 91 |
+
<i data-feather="square"></i>
|
| 92 |
+
Shape
|
| 93 |
+
</button>
|
| 94 |
+
<button class="element-btn" data-type="chart">
|
| 95 |
+
<i data-feather="bar-chart-2"></i>
|
| 96 |
+
Chart
|
| 97 |
+
</button>
|
| 98 |
+
</div>
|
| 99 |
+
|
| 100 |
+
<div class="sidebar-section">
|
| 101 |
+
<h3 class="sidebar-title">
|
| 102 |
+
<i data-feather="layers"></i>
|
| 103 |
+
Slides
|
| 104 |
+
</h3>
|
| 105 |
+
<div class="slide-thumbnail active">
|
| 106 |
+
<i data-feather="file-text" class="text-gray-400"></i>
|
| 107 |
+
</div>
|
| 108 |
+
<div class="slide-thumbnail">
|
| 109 |
+
<i data-feather="file-text" class="text-gray-400"></i>
|
| 110 |
+
</div>
|
| 111 |
+
<div class="slide-thumbnail">
|
| 112 |
+
<i data-feather="file-text" class="text-gray-400"></i>
|
| 113 |
+
</div>
|
| 114 |
+
</div>
|
| 115 |
+
|
| 116 |
+
<div class="sidebar-section">
|
| 117 |
+
<h3 class="sidebar-title">
|
| 118 |
+
<i data-feather="settings"></i>
|
| 119 |
+
Properties
|
| 120 |
+
</h3>
|
| 121 |
+
<div class="property-control">
|
| 122 |
+
<label class="block text-sm text-gray-600 mb-1">Font Size</label>
|
| 123 |
+
<input type="range" min="8" max="72" value="16" class="w-full">
|
| 124 |
+
</div>
|
| 125 |
+
</div>
|
| 126 |
+
</div>
|
| 127 |
+
`;
|
| 128 |
+
|
| 129 |
+
// Add event listeners for element buttons
|
| 130 |
+
setTimeout(() => {
|
| 131 |
+
const buttons = this.shadowRoot.querySelectorAll('.element-btn');
|
| 132 |
+
buttons.forEach(button => {
|
| 133 |
+
button.addEventListener('click', () => {
|
| 134 |
+
const type = button.getAttribute('data-type');
|
| 135 |
+
this.addElement(type);
|
| 136 |
+
});
|
| 137 |
+
}, 100);
|
| 138 |
+
});
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
addElement(type) {
|
| 142 |
+
const canvasContainer = document.getElementById('canvasContainer');
|
| 143 |
+
let newElement;
|
| 144 |
+
|
| 145 |
+
switch(type) {
|
| 146 |
+
case 'text':
|
| 147 |
+
newElement = document.createElement('div');
|
| 148 |
+
newElement.className = 'editable-element';
|
| 149 |
+
newElement.setAttribute('contenteditable', 'true');
|
| 150 |
+
newElement.style.position = 'absolute';
|
| 151 |
+
newElement.style.left = '100px';
|
| 152 |
+
newElement.style.top = '100px';
|
| 153 |
+
newElement.style.padding = '10px';
|
| 154 |
+
newElement.style.background = 'white';
|
| 155 |
+
newElement.style.border = '1px solid #e5e7eb';
|
| 156 |
+
newElement.style.borderRadius = '6px';
|
| 157 |
+
newElement.style.minWidth = '200px';
|
| 158 |
+
newElement.style.minHeight = '40px';
|
| 159 |
+
newElement.style.zIndex = '1000';
|
| 160 |
+
newElement.textContent = 'Double click to edit text';
|
| 161 |
+
break;
|
| 162 |
+
|
| 163 |
+
case 'image':
|
| 164 |
+
newElement = document.createElement('div');
|
| 165 |
+
newElement.className = 'editable-element';
|
| 166 |
+
newElement.style.position = 'absolute';
|
| 167 |
+
newElement.style.left = '150px';
|
| 168 |
+
newElement.style.top = '150px';
|
| 169 |
+
newElement.style.width = '200px';
|
| 170 |
+
newElement.style.height = '150px';
|
| 171 |
+
newElement.style.background = '#f3f4f6';
|
| 172 |
+
newElement.style.border = '2px dashed #d1d5db';
|
| 173 |
+
newElement.style.borderRadius = '6px';
|
| 174 |
+
newElement.style.display = 'flex';
|
| 175 |
+
newElement.style.alignItems = 'center';
|
| 176 |
+
newElement.style.justifyContent = 'center';
|
| 177 |
+
newElement.innerHTML = `
|
| 178 |
+
<i data-feather="image" class="text-gray-400"></i>
|
| 179 |
+
<span class="ml-2 text-gray-500">Add Image</span>
|
| 180 |
+
`;
|
| 181 |
+
break;
|
| 182 |
+
|
| 183 |
+
case 'chart':
|
| 184 |
+
newElement = document.createElement('div');
|
| 185 |
+
newElement.className = 'editable-element';
|
| 186 |
+
newElement.style.position = 'absolute';
|
| 187 |
+
newElement.style.left = '200px';
|
| 188 |
+
newElement.style.top = '200px';
|
| 189 |
+
newElement.style.width = '300
|
|
@@ -1,19 +1,272 @@
|
|
| 1 |
-
<!
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>SlideCraft Studio - PPT Editor</title>
|
| 7 |
+
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
| 8 |
+
<link rel="stylesheet" href="style.css">
|
| 9 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 10 |
+
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 11 |
+
<script src="https://unpkg.com/feather-icons"></script>
|
| 12 |
+
<script>
|
| 13 |
+
tailwind.config = {
|
| 14 |
+
theme: {
|
| 15 |
+
extend: {
|
| 16 |
+
colors: {
|
| 17 |
+
primary: '#3B82F6',
|
| 18 |
+
secondary: '#1E40AF'
|
| 19 |
+
}
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
}
|
| 23 |
+
</script>
|
| 24 |
+
</head>
|
| 25 |
+
<body class="bg-gray-100 min-h-screen">
|
| 26 |
+
<custom-navbar></custom-navbar>
|
| 27 |
+
|
| 28 |
+
<div class="container mx-auto px-4 py-6">
|
| 29 |
+
<div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
|
| 30 |
+
<!-- Sidebar -->
|
| 31 |
+
<div class="lg:col-span-1">
|
| 32 |
+
<custom-sidebar></custom-sidebar>
|
| 33 |
+
</div>
|
| 34 |
+
|
| 35 |
+
<!-- Main Content -->
|
| 36 |
+
<div class="lg:col-span-3">
|
| 37 |
+
<div class="bg-white rounded-xl shadow-lg p-6">
|
| 38 |
+
<div class="flex justify-between items-center mb-6">
|
| 39 |
+
<h1 class="text-2xl font-bold text-gray-800">PPT Editor</h1>
|
| 40 |
+
<div class="flex space-x-3">
|
| 41 |
+
<button id="previewMode" class="bg-primary hover:bg-secondary text-white px-4 py-2 rounded-lg transition-colors flex items-center">
|
| 42 |
+
<i data-feather="eye" class="w-4 h-4 mr-2"></i>
|
| 43 |
+
Preview
|
| 44 |
+
</button>
|
| 45 |
+
<button id="editMode" class="bg-gray-200 hover:bg-gray-300 text-gray-700 px-4 py-2 rounded-lg transition-colors flex items-center">
|
| 46 |
+
<i data-feather="edit" class="w-4 h-4 mr-2"></i>
|
| 47 |
+
Edit
|
| 48 |
+
</button>
|
| 49 |
+
<button id="exportBtn" class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-lg transition-colors flex items-center">
|
| 50 |
+
<i data-feather="download" class="w-4 h-4 mr-2"></i>
|
| 51 |
+
Export
|
| 52 |
+
</button>
|
| 53 |
+
</div>
|
| 54 |
+
</div>
|
| 55 |
+
|
| 56 |
+
<!-- Code Input -->
|
| 57 |
+
<div class="mb-6">
|
| 58 |
+
<label class="block text-sm font-medium text-gray-700 mb-2">PPT HTML Code</label>
|
| 59 |
+
<textarea id="codeInput" class="w-full h-40 p-4 border border-gray-300 rounded-lg font-mono text-sm focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="Paste your PPT HTML code here...">
|
| 60 |
+
<!DOCTYPE html>
|
| 61 |
+
<html lang="en">
|
| 62 |
+
<head>
|
| 63 |
+
<meta charset="UTF-8">
|
| 64 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 65 |
+
<title>Introduction to Thermodynamics</title>
|
| 66 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
| 67 |
+
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
| 68 |
+
<style>
|
| 69 |
+
* {
|
| 70 |
+
margin: 0;
|
| 71 |
+
padding: 0;
|
| 72 |
+
box-sizing: border-box;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
body {
|
| 76 |
+
display: flex;
|
| 77 |
+
justify-content: center;
|
| 78 |
+
align-items: center;
|
| 79 |
+
min-height: 100vh;
|
| 80 |
+
background-color: #f5f5f5;
|
| 81 |
+
padding: 20px;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
.slide-container {
|
| 85 |
+
width: 1280px;
|
| 86 |
+
min-height: 720px;
|
| 87 |
+
display: flex;
|
| 88 |
+
flex-direction: column;
|
| 89 |
+
font-family: 'Montserrat', sans-serif;
|
| 90 |
+
position: relative;
|
| 91 |
+
background-color: #ffffff;
|
| 92 |
+
color: #333333;
|
| 93 |
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
|
| 94 |
+
padding: 40px;
|
| 95 |
+
}
|
| 96 |
+
|
| 97 |
+
.slide-header {
|
| 98 |
+
margin-bottom: 20px;
|
| 99 |
+
padding-bottom: 15px;
|
| 100 |
+
border-bottom: 2px solid #003366;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
.slide-header h1 {
|
| 104 |
+
font-size: 36px;
|
| 105 |
+
font-weight: 600;
|
| 106 |
+
color: #003366;
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
.content-wrapper {
|
| 110 |
+
display: flex;
|
| 111 |
+
flex: 1;
|
| 112 |
+
gap: 30px;
|
| 113 |
+
margin-top: 10px;
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
.text-content {
|
| 117 |
+
flex: 1;
|
| 118 |
+
display: flex;
|
| 119 |
+
flex-direction: column;
|
| 120 |
+
justify-content: space-between;
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
.text-section {
|
| 124 |
+
margin-bottom: 25px;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
.text-section h3 {
|
| 128 |
+
font-size: 20px;
|
| 129 |
+
font-weight: 600;
|
| 130 |
+
color: #003366;
|
| 131 |
+
margin-bottom: 10px;
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
.text-section p, .text-section li {
|
| 135 |
+
font-size: 16px;
|
| 136 |
+
line-height: 1.5;
|
| 137 |
+
margin-bottom: 8px;
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
.text-section ul {
|
| 141 |
+
list-style-type: none;
|
| 142 |
+
padding-left: 0;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
.text-section li {
|
| 146 |
+
position: relative;
|
| 147 |
+
padding-left: 20px;
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
.text-section li:before {
|
| 151 |
+
content: "•";
|
| 152 |
+
color: #003366;
|
| 153 |
+
font-weight: bold;
|
| 154 |
+
position: absolute;
|
| 155 |
+
left: 0;
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
.image-content {
|
| 159 |
+
flex: 1;
|
| 160 |
+
display: flex;
|
| 161 |
+
flex-direction: column;
|
| 162 |
+
align-items: center;
|
| 163 |
+
justify-content: center;
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
.image-content img {
|
| 167 |
+
max-width: 100%;
|
| 168 |
+
height: auto;
|
| 169 |
+
border: 1px solid #ddd;
|
| 170 |
+
border-radius: 4px;
|
| 171 |
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
| 172 |
+
}
|
| 173 |
+
|
| 174 |
+
.fig-caption {
|
| 175 |
+
font-size: 14px;
|
| 176 |
+
color: #666;
|
| 177 |
+
margin-top: 10px;
|
| 178 |
+
text-align: center;
|
| 179 |
+
font-style: italic;
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
.slide-footer {
|
| 183 |
+
position: absolute;
|
| 184 |
+
bottom: 20px;
|
| 185 |
+
right: 20px;
|
| 186 |
+
font-size: 14px;
|
| 187 |
+
color: #666;
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
@media (max-width: 1300px) {
|
| 191 |
+
.slide-container {
|
| 192 |
+
width: 100%;
|
| 193 |
+
min-height: 600px;
|
| 194 |
+
}
|
| 195 |
+
}
|
| 196 |
+
</style>
|
| 197 |
+
</head>
|
| 198 |
+
<body>
|
| 199 |
+
<div class="slide-container">
|
| 200 |
+
<div class="slide-header">
|
| 201 |
+
<h1>Introduction to Thermodynamics</h1>
|
| 202 |
+
</div>
|
| 203 |
+
|
| 204 |
+
<div class="content-wrapper">
|
| 205 |
+
<div class="text-content">
|
| 206 |
+
<div class="text-section">
|
| 207 |
+
<h3>Definition</h3>
|
| 208 |
+
<p>Thermodynamics is the branch of physics that deals with the relationships between heat, work, temperature, energy, and the laws governing energy conversion.</p>
|
| 209 |
+
</div>
|
| 210 |
+
|
| 211 |
+
<div class="text-section">
|
| 212 |
+
<h3>Key Concepts</h3>
|
| 213 |
+
<ul>
|
| 214 |
+
<li><strong>Energy:</strong> Capacity to do work or produce heat</li>
|
| 215 |
+
<li><strong>Temperature:</strong> Measure of average kinetic energy</li>
|
| 216 |
+
<li><strong>Entropy:</strong> Measure of disorder or randomness</li>
|
| 217 |
+
<li><strong>Thermal Equilibrium:</strong> State where no heat transfer occurs</li>
|
| 218 |
+
</ul>
|
| 219 |
+
</div>
|
| 220 |
+
|
| 221 |
+
<div class="text-section">
|
| 222 |
+
<h3>Importance</h3>
|
| 223 |
+
<p>Thermodynamics forms the foundation for engineering disciplines, chemical processes, physical theories, and explains everyday phenomena from engine operation to climate systems.</p>
|
| 224 |
+
</div>
|
| 225 |
+
</div>
|
| 226 |
+
|
| 227 |
+
<div class="image-content">
|
| 228 |
+
<img src="https://www.chemistrylearner.com/wp-content/uploads/2022/08/Laws-of-Thermodynamics.jpg" alt="Thermodynamic System and Surroundings">
|
| 229 |
+
<p class="fig-caption">Fig 2.1 Thermodynamic System and Surroundings</p>
|
| 230 |
+
</div>
|
| 231 |
+
</div>
|
| 232 |
+
|
| 233 |
+
<div class="slide-footer">
|
| 234 |
+
Slide 2
|
| 235 |
+
</div>
|
| 236 |
+
</div>
|
| 237 |
+
</body>
|
| 238 |
+
</html>
|
| 239 |
+
</textarea>
|
| 240 |
+
<div class="flex justify-end mt-2">
|
| 241 |
+
<button id="loadCode" class="bg-primary hover:bg-secondary text-white px-4 py-2 rounded-lg transition-colors">
|
| 242 |
+
Load PPT
|
| 243 |
+
</button>
|
| 244 |
+
</div>
|
| 245 |
+
</div>
|
| 246 |
+
|
| 247 |
+
<!-- Canvas Container -->
|
| 248 |
+
<div class="border-2 border-dashed border-gray-300 rounded-xl p-4 bg-gray-50 min-h-[600px]">
|
| 249 |
+
<div id="canvasContainer" class="flex justify-center items-center min-h-[500px]">
|
| 250 |
+
<div id="placeholder" class="text-center text-gray-500">
|
| 251 |
+
<i data-feather="file" class="w-16 h-16 mx-auto mb-4"></i>
|
| 252 |
+
<p class="text-lg">Load your PPT code to start editing</p>
|
| 253 |
+
</div>
|
| 254 |
+
</div>
|
| 255 |
+
</div>
|
| 256 |
+
</div>
|
| 257 |
+
</div>
|
| 258 |
+
</div>
|
| 259 |
+
</div>
|
| 260 |
+
|
| 261 |
+
<custom-footer></custom-footer>
|
| 262 |
+
|
| 263 |
+
<script src="components/navbar.js"></script>
|
| 264 |
+
<script src="components/sidebar.js"></script>
|
| 265 |
+
<script src="components/footer.js"></script>
|
| 266 |
+
<script src="script.js"></script>
|
| 267 |
+
<script>
|
| 268 |
+
feather.replace();
|
| 269 |
+
</script>
|
| 270 |
+
<script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
|
| 271 |
+
</body>
|
| 272 |
+
</html>
|
|
@@ -0,0 +1,359 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// Global state
|
| 2 |
+
let currentMode = 'edit';
|
| 3 |
+
let selectedElement = null;
|
| 4 |
+
let isDragging = false;
|
| 5 |
+
let dragOffset = { x: 0, y: 0 };
|
| 6 |
+
|
| 7 |
+
// Initialize the application
|
| 8 |
+
document.addEventListener('DOMContentLoaded', function() {
|
| 9 |
+
initializeEventListeners();
|
| 10 |
+
setupCanvas();
|
| 11 |
+
});
|
| 12 |
+
|
| 13 |
+
function initializeEventListeners() {
|
| 14 |
+
// Mode buttons
|
| 15 |
+
document.getElementById('previewMode').addEventListener('click', () => switchMode('preview'));
|
| 16 |
+
document.getElementById('editMode').addEventListener('click', () => switchMode('edit'));
|
| 17 |
+
|
| 18 |
+
// Load code button
|
| 19 |
+
document.getElementById('loadCode').addEventListener('click', loadPPT);
|
| 20 |
+
|
| 21 |
+
// Export button
|
| 22 |
+
document.getElementById('exportBtn').addEventListener('click', exportPPT);
|
| 23 |
+
|
| 24 |
+
// Canvas events
|
| 25 |
+
document.getElementById('canvasContainer').addEventListener('click', handleCanvasClick);
|
| 26 |
+
document.addEventListener('keydown', handleKeyDown);
|
| 27 |
+
document.addEventListener('contextmenu', handleContextMenu);
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
function setupCanvas() {
|
| 31 |
+
// Set up initial canvas state
|
| 32 |
+
const canvas = document.getElementById('canvasContainer');
|
| 33 |
+
canvas.addEventListener('mousedown', startDrag);
|
| 34 |
+
canvas.addEventListener('mousemove', handleDrag);
|
| 35 |
+
canvas.addEventListener('mouseup', stopDrag);
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
function switchMode(mode) {
|
| 39 |
+
currentMode = mode;
|
| 40 |
+
const previewBtn = document.getElementById('previewMode');
|
| 41 |
+
const editBtn = document.getElementById('editMode');
|
| 42 |
+
|
| 43 |
+
if (mode === 'preview') {
|
| 44 |
+
previewBtn.classList.remove('bg-gray-200', 'text-gray-700');
|
| 45 |
+
previewBtn.classList.add('bg-primary', 'text-white');
|
| 46 |
+
editBtn.classList.remove('bg-primary', 'text-white');
|
| 47 |
+
editBtn.classList.add('bg-gray-200', 'text-gray-700');
|
| 48 |
+
disableEditing();
|
| 49 |
+
} else {
|
| 50 |
+
editBtn.classList.remove('bg-gray-200', 'text-gray-700');
|
| 51 |
+
editBtn.classList.add('bg-primary', 'text-white');
|
| 52 |
+
previewBtn.classList.remove('bg-primary', 'text-white');
|
| 53 |
+
previewBtn.classList.add('bg-gray-200', 'text-gray-700');
|
| 54 |
+
enableEditing();
|
| 55 |
+
}
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
function loadPPT() {
|
| 59 |
+
const codeInput = document.getElementById('codeInput').value;
|
| 60 |
+
const canvasContainer = document.getElementById('canvasContainer');
|
| 61 |
+
|
| 62 |
+
if (!codeInput.trim()) {
|
| 63 |
+
alert('Please enter PPT HTML code');
|
| 64 |
+
return;
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
try {
|
| 68 |
+
// Clear previous content
|
| 69 |
+
canvasContainer.innerHTML = '';
|
| 70 |
+
|
| 71 |
+
// Create iframe to safely render the HTML
|
| 72 |
+
const iframe = document.createElement('iframe');
|
| 73 |
+
iframe.style.width = '100%';
|
| 74 |
+
iframe.style.height = '500px';
|
| 75 |
+
iframe.style.border = 'none';
|
| 76 |
+
iframe.style.borderRadius = '8px';
|
| 77 |
+
|
| 78 |
+
iframe.onload = function() {
|
| 79 |
+
// Once iframe is loaded, extract the content and make it editable
|
| 80 |
+
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
|
| 81 |
+
iframeDoc.open();
|
| 82 |
+
iframeDoc.write(codeInput);
|
| 83 |
+
iframeDoc.close();
|
| 84 |
+
|
| 85 |
+
// Replace iframe with editable content
|
| 86 |
+
setTimeout(() => {
|
| 87 |
+
const slideContent = iframeDoc.body.firstElementChild.cloneNode(true);
|
| 88 |
+
canvasContainer.innerHTML = '';
|
| 89 |
+
canvasContainer.appendChild(slideContent);
|
| 90 |
+
|
| 91 |
+
// Make elements editable
|
| 92 |
+
makeElementsEditable(slideContent);
|
| 93 |
+
|
| 94 |
+
// Scale the slide to fit container
|
| 95 |
+
scaleSlideToFit(slideContent);
|
| 96 |
+
}, 100);
|
| 97 |
+
};
|
| 98 |
+
|
| 99 |
+
canvasContainer.appendChild(iframe);
|
| 100 |
+
} catch (error) {
|
| 101 |
+
console.error('Error loading PPT:', error);
|
| 102 |
+
alert('Error loading PPT. Please check your HTML code.');
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
function makeElementsEditable(container) {
|
| 107 |
+
// Add editable class to all elements
|
| 108 |
+
const allElements = container.querySelectorAll('*');
|
| 109 |
+
allElements.forEach(element => {
|
| 110 |
+
element.classList.add('editable-element');
|
| 111 |
+
|
| 112 |
+
// Make text elements directly editable
|
| 113 |
+
if (element.tagName === 'P' || element.tagName === 'H1' || element.tagName === 'H2' ||
|
| 114 |
+
element.tagName === 'H3' || element.tagName === 'LI' || element.tagName === 'SPAN') {
|
| 115 |
+
element.setAttribute('contenteditable', 'true');
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
// Add event listeners for interaction
|
| 119 |
+
element.addEventListener('mousedown', handleElementMouseDown);
|
| 120 |
+
element.addEventListener('dblclick', handleElementDoubleClick);
|
| 121 |
+
});
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
function scaleSlideToFit(slide) {
|
| 125 |
+
const container = document.getElementById('canvasContainer');
|
| 126 |
+
const containerWidth = container.clientWidth;
|
| 127 |
+
const slideWidth = 1280; // Standard 16:9 slide width
|
| 128 |
+
|
| 129 |
+
if (slideWidth > containerWidth) {
|
| 130 |
+
const scale = (containerWidth - 40) / slideWidth;
|
| 131 |
+
slide.style.transform = `scale(${scale})`;
|
| 132 |
+
slide.style.transformOrigin = 'center top';
|
| 133 |
+
}
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
function handleElementMouseDown(e) {
|
| 137 |
+
if (currentMode !== 'edit') return;
|
| 138 |
+
|
| 139 |
+
e.stopPropagation();
|
| 140 |
+
selectElement(e.target);
|
| 141 |
+
|
| 142 |
+
if (e.target.tagName === 'IMG' || e.target.classList.contains('image-content')) {
|
| 143 |
+
isDragging = true;
|
| 144 |
+
const rect = e.target.getBoundingClientRect();
|
| 145 |
+
dragOffset.x = e.clientX - rect.left;
|
| 146 |
+
dragOffset.y = e.clientY - rect.top;
|
| 147 |
+
}
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
function handleElementDoubleClick(e) {
|
| 151 |
+
if (currentMode !== 'edit') return;
|
| 152 |
+
|
| 153 |
+
e.stopPropagation();
|
| 154 |
+
const element = e.target;
|
| 155 |
+
|
| 156 |
+
if (element.tagName === 'P' || element.tagName === 'H1' || element.tagName === 'H2' ||
|
| 157 |
+
element.tagName === 'H3' || element.tagName === 'LI') {
|
| 158 |
+
element.focus();
|
| 159 |
+
selectElement(element);
|
| 160 |
+
}
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
function startDrag(e) {
|
| 164 |
+
if (currentMode !== 'edit' || !selectedElement) return;
|
| 165 |
+
|
| 166 |
+
isDragging = true;
|
| 167 |
+
const rect = selectedElement.getBoundingClientRect();
|
| 168 |
+
dragOffset.x = e.clientX - rect.left;
|
| 169 |
+
dragOffset.y = e.clientY - rect.top;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
function handleDrag(e) {
|
| 173 |
+
if (!isDragging || !selectedElement) return;
|
| 174 |
+
|
| 175 |
+
e.preventDefault();
|
| 176 |
+
|
| 177 |
+
const container = document.getElementById('canvasContainer');
|
| 178 |
+
const containerRect = container.getBoundingClientRect();
|
| 179 |
+
|
| 180 |
+
const newX = e.clientX - containerRect.left - dragOffset.x;
|
| 181 |
+
const newY = e.clientY - containerRect.top - dragOffset.y;
|
| 182 |
+
|
| 183 |
+
selectedElement.style.position = 'absolute';
|
| 184 |
+
selectedElement.style.left = `${newX}px`;
|
| 185 |
+
selectedElement.style.top = `${newY}px`;
|
| 186 |
+
selectedElement.style.zIndex = '1000';
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
function stopDrag() {
|
| 190 |
+
isDragging = false;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
function selectElement(element) {
|
| 194 |
+
// Deselect previous element
|
| 195 |
+
if (selectedElement) {
|
| 196 |
+
selectedElement.classList.remove('selected');
|
| 197 |
+
}
|
| 198 |
+
|
| 199 |
+
// Select new element
|
| 200 |
+
selectedElement = element;
|
| 201 |
+
selectedElement.classList.add('selected');
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
function handleCanvasClick(e) {
|
| 205 |
+
if (e.target === document.getElementById('canvasContainer')) {
|
| 206 |
+
if (selectedElement) {
|
| 207 |
+
selectedElement.classList.remove('selected');
|
| 208 |
+
selectedElement = null;
|
| 209 |
+
}
|
| 210 |
+
}
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
function handleKeyDown(e) {
|
| 214 |
+
if (currentMode !== 'edit' || !selectedElement) return;
|
| 215 |
+
|
| 216 |
+
// Delete selected element
|
| 217 |
+
if (e.key === 'Delete' || e.key === 'Backspace') {
|
| 218 |
+
e.preventDefault();
|
| 219 |
+
selectedElement.remove();
|
| 220 |
+
selectedElement = null;
|
| 221 |
+
}
|
| 222 |
+
}
|
| 223 |
+
|
| 224 |
+
function handleContextMenu(e) {
|
| 225 |
+
if (currentMode !== 'edit') return;
|
| 226 |
+
|
| 227 |
+
e.preventDefault();
|
| 228 |
+
|
| 229 |
+
const element = e.target;
|
| 230 |
+
if (element.classList.contains('editable-element')) {
|
| 231 |
+
selectElement(element);
|
| 232 |
+
showContextMenu(e.clientX, e.clientY, element);
|
| 233 |
+
}
|
| 234 |
+
}
|
| 235 |
+
|
| 236 |
+
function showContextMenu(x, y, element) {
|
| 237 |
+
// Remove existing context menu
|
| 238 |
+
const existingMenu = document.querySelector('.context-menu');
|
| 239 |
+
if (existingMenu) {
|
| 240 |
+
existingMenu.remove();
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
const contextMenu = document.createElement('div');
|
| 244 |
+
contextMenu.className = 'context-menu';
|
| 245 |
+
contextMenu.style.left = `${x}px`;
|
| 246 |
+
contextMenu.style.top = `${y}px`;
|
| 247 |
+
|
| 248 |
+
const menuItems = [
|
| 249 |
+
{ icon: 'edit-3', text: 'Edit Text', action: () => editText(element) },
|
| 250 |
+
{ icon: 'trash-2', text: 'Delete', action: () => deleteElement(element) },
|
| 251 |
+
{ icon: 'copy', text: 'Duplicate', action: () => duplicateElement(element) },
|
| 252 |
+
{ icon: 'layers', text: 'Bring to Front', action: () => bringToFront(element) },
|
| 253 |
+
{ icon: 'move', text: 'Move to Back', action: () => moveToBack(element) }
|
| 254 |
+
];
|
| 255 |
+
|
| 256 |
+
menuItems.forEach(item => {
|
| 257 |
+
const menuItem = document.createElement('div');
|
| 258 |
+
menuItem.className = 'context-menu-item';
|
| 259 |
+
menuItem.innerHTML = `
|
| 260 |
+
<i data-feather="${item.icon}"></i>
|
| 261 |
+
<span>${item.text}</span>
|
| 262 |
+
`;
|
| 263 |
+
menuItem.addEventListener('click', item.action);
|
| 264 |
+
contextMenu.appendChild(menuItem);
|
| 265 |
+
});
|
| 266 |
+
|
| 267 |
+
document.body.appendChild(contextMenu);
|
| 268 |
+
feather.replace();
|
| 269 |
+
|
| 270 |
+
// Close context menu when clicking elsewhere
|
| 271 |
+
setTimeout(() => {
|
| 272 |
+
document.addEventListener('click', function closeMenu() {
|
| 273 |
+
contextMenu.remove();
|
| 274 |
+
document.removeEventListener('click', closeMenu);
|
| 275 |
+
});
|
| 276 |
+
}, 10);
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
function editText(element) {
|
| 280 |
+
element.focus();
|
| 281 |
+
const range = document.createRange();
|
| 282 |
+
range.selectNodeContents(element);
|
| 283 |
+
const selection = window.getSelection();
|
| 284 |
+
selection.removeAllRanges();
|
| 285 |
+
selection.addRange(range);
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
function deleteElement(element) {
|
| 289 |
+
element.remove();
|
| 290 |
+
selectedElement = null;
|
| 291 |
+
}
|
| 292 |
+
|
| 293 |
+
function duplicateElement(element) {
|
| 294 |
+
const clone = element.cloneNode(true);
|
| 295 |
+
element.parentNode.insertBefore(clone, element.nextSibling);
|
| 296 |
+
makeElementsEditable(clone);
|
| 297 |
+
selectElement(clone);
|
| 298 |
+
}
|
| 299 |
+
|
| 300 |
+
function bringToFront(element) {
|
| 301 |
+
element.style.zIndex = '1000';
|
| 302 |
+
}
|
| 303 |
+
|
| 304 |
+
function moveToBack(element) {
|
| 305 |
+
element.style.zIndex = '0';
|
| 306 |
+
}
|
| 307 |
+
|
| 308 |
+
function enableEditing() {
|
| 309 |
+
const editableElements = document.querySelectorAll('.editable-element');
|
| 310 |
+
editableElements.forEach(element => {
|
| 311 |
+
element.style.cursor = 'move';
|
| 312 |
+
if (element.tagName === 'P' || element.tagName === 'H1' || element.tagName === 'H2' ||
|
| 313 |
+
element.tagName === 'H3' || element.tagName === 'LI' || element.tagName === 'SPAN') {
|
| 314 |
+
element.setAttribute('contenteditable', 'true');
|
| 315 |
+
}
|
| 316 |
+
});
|
| 317 |
+
}
|
| 318 |
+
|
| 319 |
+
function disableEditing() {
|
| 320 |
+
const editableElements = document.querySelectorAll('.editable-element');
|
| 321 |
+
editableElements.forEach(element => {
|
| 322 |
+
element.style.cursor = 'default';
|
| 323 |
+
element.removeAttribute('contenteditable');
|
| 324 |
+
});
|
| 325 |
+
}
|
| 326 |
+
|
| 327 |
+
function exportPPT() {
|
| 328 |
+
const slideContent = document.querySelector('#canvasContainer > *');
|
| 329 |
+
if (!slideContent) {
|
| 330 |
+
alert('No PPT content to export');
|
| 331 |
+
return;
|
| 332 |
+
}
|
| 333 |
+
|
| 334 |
+
const htmlContent = `
|
| 335 |
+
<!DOCTYPE html>
|
| 336 |
+
<html lang="en">
|
| 337 |
+
<head>
|
| 338 |
+
<meta charset="UTF-8">
|
| 339 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 340 |
+
${document.querySelector('style').outerHTML}
|
| 341 |
+
</head>
|
| 342 |
+
<body>
|
| 343 |
+
${slideContent.outerHTML}
|
| 344 |
+
</body>
|
| 345 |
+
</html>`;
|
| 346 |
+
|
| 347 |
+
// Create download link
|
| 348 |
+
const blob = new Blob([htmlContent], { type: 'text/html' });
|
| 349 |
+
const url = URL.createObjectURL(blob);
|
| 350 |
+
const a = document.createElement('a');
|
| 351 |
+
a.href = url;
|
| 352 |
+
a.download = 'presentation.html';
|
| 353 |
+
document.body.appendChild(a);
|
| 354 |
+
a.click();
|
| 355 |
+
document.body.removeChild(a);
|
| 356 |
+
URL.revokeObjectURL(url);
|
| 357 |
+
|
| 358 |
+
alert('PPT exported successfully!');
|
| 359 |
+
}
|
|
@@ -1,28 +1,196 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
body {
|
| 2 |
-
|
| 3 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
}
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
|
|
|
| 9 |
}
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
| 16 |
}
|
| 17 |
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
}
|
| 25 |
|
| 26 |
-
.
|
| 27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/* Global Styles */
|
| 2 |
+
* {
|
| 3 |
+
margin: 0;
|
| 4 |
+
padding: 0;
|
| 5 |
+
box-sizing: border-box;
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
body {
|
| 9 |
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
| 10 |
+
line-height: 1.6;
|
| 11 |
+
color: #333;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
/* Canvas Styles */
|
| 15 |
+
.editable-element {
|
| 16 |
+
position: relative;
|
| 17 |
+
cursor: move;
|
| 18 |
+
transition: all 0.2s ease;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
.editable-element:hover {
|
| 22 |
+
outline: 2px dashed #3B82F6;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
.editable-element.selected {
|
| 26 |
+
outline: 2px solid #1E40AF;
|
| 27 |
+
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
.edit-handle {
|
| 31 |
+
position: absolute;
|
| 32 |
+
width: 8px;
|
| 33 |
+
height: 8px;
|
| 34 |
+
background: #1E40AF;
|
| 35 |
+
border: 1px solid white;
|
| 36 |
+
border-radius: 50%;
|
| 37 |
+
cursor: pointer;
|
| 38 |
+
z-index: 1000;
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
.edit-handle.top-left { top: -4px; left: -4px; }
|
| 42 |
+
.edit-handle.top-right { top: -4px; right: -4px; }
|
| 43 |
+
.edit-handle.bottom-left { bottom: -4px; left: -4px; }
|
| 44 |
+
.edit-handle.bottom-right { bottom: -4px; right: -4px; }
|
| 45 |
+
|
| 46 |
+
.text-edit-overlay {
|
| 47 |
+
position: absolute;
|
| 48 |
+
top: 0;
|
| 49 |
+
left: 0;
|
| 50 |
+
right: 0;
|
| 51 |
+
bottom: 0;
|
| 52 |
+
background: rgba(59, 130, 246, 0.1);
|
| 53 |
+
display: flex;
|
| 54 |
+
align-items: center;
|
| 55 |
+
justify-content: center;
|
| 56 |
+
opacity: 0;
|
| 57 |
+
transition: opacity 0.2s ease;
|
| 58 |
+
cursor: text;
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
.text-edit-overlay:hover {
|
| 62 |
+
opacity: 1;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
/* Context Menu */
|
| 66 |
+
.context-menu {
|
| 67 |
+
position: fixed;
|
| 68 |
+
background: white;
|
| 69 |
+
border: 1px solid #e5e7eb;
|
| 70 |
+
border-radius: 8px;
|
| 71 |
+
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
|
| 72 |
+
padding: 8px 0;
|
| 73 |
+
z-index: 10000;
|
| 74 |
+
min-width: 160px;
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
.context-menu-item {
|
| 78 |
+
display: flex;
|
| 79 |
+
align-items: center;
|
| 80 |
+
padding: 8px 16px;
|
| 81 |
+
cursor: pointer;
|
| 82 |
+
transition: background-color 0.2s ease;
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
.context-menu-item:hover {
|
| 86 |
+
background-color: #f3f4f6;
|
| 87 |
}
|
| 88 |
|
| 89 |
+
.context-menu-item i {
|
| 90 |
+
width: 16px;
|
| 91 |
+
height: 16px;
|
| 92 |
+
margin-right: 8px;
|
| 93 |
}
|
| 94 |
|
| 95 |
+
/* Slide Container */
|
| 96 |
+
.slide-container {
|
| 97 |
+
position: relative;
|
| 98 |
+
width: 1280px;
|
| 99 |
+
min-height: 720px;
|
| 100 |
+
background: white;
|
| 101 |
+
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
|
| 102 |
+
transform-origin: center top;
|
| 103 |
}
|
| 104 |
|
| 105 |
+
/* Toolbar */
|
| 106 |
+
.toolbar {
|
| 107 |
+
position: fixed;
|
| 108 |
+
top: 50%;
|
| 109 |
+
right: 20px;
|
| 110 |
+
transform: translateY(-50%);
|
| 111 |
+
background: white;
|
| 112 |
+
border-radius: 12px;
|
| 113 |
+
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
|
| 114 |
+
padding: 12px;
|
| 115 |
+
z-index: 1000;
|
| 116 |
}
|
| 117 |
|
| 118 |
+
.toolbar-btn {
|
| 119 |
+
display: flex;
|
| 120 |
+
align-items: center;
|
| 121 |
+
justify-content: center;
|
| 122 |
+
width: 44px;
|
| 123 |
+
height: 44px;
|
| 124 |
+
border-radius: 8px;
|
| 125 |
+
margin-bottom: 8px;
|
| 126 |
+
cursor: pointer;
|
| 127 |
+
transition: all 0.2s ease;
|
| 128 |
}
|
| 129 |
+
|
| 130 |
+
.toolbar-btn:hover {
|
| 131 |
+
background: #f3f4f6;
|
| 132 |
+
transform: scale(1.05);
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
/* Responsive Design */
|
| 136 |
+
@media (max-width: 1024px) {
|
| 137 |
+
.slide-container {
|
| 138 |
+
width: 100%;
|
| 139 |
+
min-height: 600px;
|
| 140 |
+
transform: scale(0.8);
|
| 141 |
+
}
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
@media (max-width: 768px) {
|
| 145 |
+
.slide-container {
|
| 146 |
+
transform: scale(0.7);
|
| 147 |
+
min-height: 500px;
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
.toolbar {
|
| 151 |
+
right: 10px;
|
| 152 |
+
padding: 8px;
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
.toolbar-btn {
|
| 156 |
+
width: 36px;
|
| 157 |
+
height: 36px;
|
| 158 |
+
}
|
| 159 |
+
}
|
| 160 |
+
|
| 161 |
+
/* Animation Classes */
|
| 162 |
+
.fade-in {
|
| 163 |
+
animation: fadeIn 0.3s ease-in-out;
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
@keyframes fadeIn {
|
| 167 |
+
from { opacity: 0; transform: translateY(10px); }
|
| 168 |
+
to { opacity: 1; transform: translateY(0); }
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
.slide-in {
|
| 172 |
+
animation: slideIn 0.3s ease-out;
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
@keyframes slideIn {
|
| 176 |
+
from { transform: translateX(-20px); opacity: 0; }
|
| 177 |
+
to { transform: translateX(0); opacity: 1; }
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
/* Custom Scrollbar */
|
| 181 |
+
::-webkit-scrollbar {
|
| 182 |
+
width: 6px;
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
::-webkit-scrollbar-track {
|
| 186 |
+
background: #f1f1f1;
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
::-webkit-scrollbar-thumb {
|
| 190 |
+
background: #c1c1c1;
|
| 191 |
+
border-radius: 3px;
|
| 192 |
+
}
|
| 193 |
+
|
| 194 |
+
::-webkit-scrollbar-thumb:hover {
|
| 195 |
+
background: #a8a8a8;
|
| 196 |
+
}
|