mirror of
https://github.com/litruv/lit.ruv.wtf.git
synced 2026-07-24 02:36:02 +10:00
added tape
This commit is contained in:
@@ -32,8 +32,9 @@
|
||||
<!-- ::PAGE_SPECIFIC_STYLES:: -->
|
||||
|
||||
<script src="main.js" defer></script> <!-- Common main script -->
|
||||
<script src="viewport-scroll-fix.js"></script>
|
||||
<script src="dynamic-rotation.js" defer></script>
|
||||
<script src="dynamic-rotation.js" defer></script> <!-- Common main script -->
|
||||
<script src="tape.js" defer></script>
|
||||
<script src="tape-debug.js" defer></script>
|
||||
<!-- ::PAGE_SPECIFIC_SCRIPTS_DEFER:: -->
|
||||
|
||||
<title><!-- ::PAGE_TITLE:: --></title>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
const minRotation = 0.5;
|
||||
const maxRotation = 2.5;
|
||||
const minHeight = 200;
|
||||
const maxHeight = 700;
|
||||
const maxHeight = 600;
|
||||
|
||||
// Linear interpolation between min and max rotation based on height
|
||||
let rotation = maxRotation - ((height - minHeight) / (maxHeight - minHeight)) * (maxRotation - minRotation);
|
||||
|
||||
@@ -32,8 +32,9 @@
|
||||
|
||||
|
||||
<script src="main.js" defer></script> <!-- Common main script -->
|
||||
<script src="viewport-scroll-fix.js"></script>
|
||||
<script src="dynamic-rotation.js" defer></script>
|
||||
<script src="dynamic-rotation.js" defer></script> <!-- Common main script -->
|
||||
<script src="tape.js" defer></script>
|
||||
<script src="tape-debug.js" defer></script>
|
||||
|
||||
|
||||
<title>Litruv - Dev/Tech Artist</title>
|
||||
|
||||
@@ -55,9 +55,40 @@ function createPost(t) {
|
||||
|
||||
link.href = t.url;
|
||||
link.appendChild(post);
|
||||
|
||||
console.log(`[Main] Created post with ${t.embed.length} images`);
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
// Helper function to add tape to a single image
|
||||
function addTapeToSingleImage(image, index) {
|
||||
if (!window.createTapeElement || !window.positionTape) {
|
||||
console.warn('[Main] Tape functions not available');
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine tape pattern (alternating)
|
||||
const usePattern1 = index % 2 === 0;
|
||||
|
||||
// Create two tape pieces
|
||||
const tape1 = window.createTapeElement(index, 1);
|
||||
const tape2 = window.createTapeElement(index, 2);
|
||||
|
||||
if (usePattern1) {
|
||||
// Pattern 1: top-left and bottom-right
|
||||
window.positionTape(tape1, 'top-left', index, 1);
|
||||
window.positionTape(tape2, 'bottom-right', index, 2);
|
||||
} else {
|
||||
// Pattern 2: top-right and bottom-left
|
||||
window.positionTape(tape1, 'top-right', index, 1);
|
||||
window.positionTape(tape2, 'bottom-left', index, 2);
|
||||
}
|
||||
|
||||
image.appendChild(tape1);
|
||||
image.appendChild(tape2);
|
||||
}
|
||||
|
||||
function filterOriginalPosts(feed) {
|
||||
return feed.filter(item => {
|
||||
const isRepost = item?.reason?.$type === "app.bsky.feed.defs#reasonRepost";
|
||||
@@ -102,10 +133,22 @@ function getShortestColumn(columns) {
|
||||
function layoutPosts(postElements) {
|
||||
const numCols = getNumColumns();
|
||||
const columns = createColumns(numCols);
|
||||
postElements.forEach(postEl => {
|
||||
postElements.forEach((postEl, index) => {
|
||||
const col = getShortestColumn(columns);
|
||||
// Set descending z-index - first post has highest z-index
|
||||
postEl.firstElementChild.style.zIndex = postElements.length - index;
|
||||
col.appendChild(postEl);
|
||||
});
|
||||
|
||||
// Use refreshTape to avoid duplicate tape on resize/layout
|
||||
console.log('[Main] Posts laid out, refreshing tape for all images');
|
||||
setTimeout(() => {
|
||||
if (window.refreshTape) {
|
||||
window.refreshTape();
|
||||
} else {
|
||||
console.error('[Main] refreshTape function not available');
|
||||
}
|
||||
}, 200);
|
||||
}
|
||||
|
||||
async function fetchPosts() {
|
||||
@@ -131,6 +174,8 @@ async function fetchPosts() {
|
||||
})) || []
|
||||
}));
|
||||
|
||||
console.log(`[Main] Fetched ${posts.length} posts, ${posts.filter(p => p.embed.length > 0).length} have images`);
|
||||
|
||||
// Only create post elements once
|
||||
postElementsCache = posts.map(post => createPost(post));
|
||||
// Preload images
|
||||
@@ -156,6 +201,12 @@ async function fetchPosts() {
|
||||
window.addEventListener("resize", () => {
|
||||
if (postElementsCache) {
|
||||
layoutPosts(postElementsCache);
|
||||
// Re-add tape after layout changes
|
||||
if (window.refreshTape) {
|
||||
setTimeout(() => {
|
||||
window.refreshTape();
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
|
||||
if (posts.length === 0 || columns.length === 0) return;
|
||||
|
||||
// Assign z-index based on post order (newer posts first)
|
||||
posts.forEach((post, index) => {
|
||||
post.style.zIndex = 100 - index;
|
||||
});
|
||||
|
||||
// Store original positions of posts
|
||||
posts.forEach((post, index) => {
|
||||
const rect = post.getBoundingClientRect();
|
||||
|
||||
@@ -66,8 +66,9 @@
|
||||
</style>
|
||||
|
||||
<script src="main.js" defer></script> <!-- Common main script -->
|
||||
<script src="viewport-scroll-fix.js"></script>
|
||||
<script src="dynamic-rotation.js" defer></script>
|
||||
<script src="dynamic-rotation.js" defer></script> <!-- Common main script -->
|
||||
<script src="tape.js" defer></script>
|
||||
<script src="tape-debug.js" defer></script>
|
||||
|
||||
|
||||
<title>Privacy Policy - Litruv</title>
|
||||
|
||||
@@ -150,7 +150,6 @@ social-links a:hover .fab.fa-youtube {
|
||||
transition: none; /* Prevent transitions during layout changes */
|
||||
will-change: auto; /* Prevent unnecessary layer promotion */
|
||||
/* Prevent reflow during resize */
|
||||
contain: layout;
|
||||
}
|
||||
|
||||
@media (max-width: 799px) {
|
||||
@@ -160,19 +159,25 @@ social-links a:hover .fab.fa-youtube {
|
||||
transition: none; /* Prevent transitions during layout changes */
|
||||
/* Remove the min-height that was causing issues */
|
||||
min-height: auto;
|
||||
/* Use layout containment to minimize reflow */
|
||||
contain: layout style size;
|
||||
margin-top: 2rem; /* Add top margin to push posts below header */
|
||||
margin-right: 0px;
|
||||
margin-left:0px;
|
||||
padding-right: 0; /* Remove right padding on mobile */
|
||||
}
|
||||
.masonry-col {
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
/* Prevent content reflow during breakpoint change */
|
||||
contain: layout style;
|
||||
/* Hide overflow columns on mobile */
|
||||
}
|
||||
.masonry-col:not(:first-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Ensure posts don't have excessive negative margins on mobile */
|
||||
.post {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.post {
|
||||
@@ -183,7 +188,7 @@ social-links a:hover .fab.fa-youtube {
|
||||
margin-left: -40px;
|
||||
margin-right: -40px;
|
||||
border: 2px solid var(--post-border);
|
||||
position: relative;
|
||||
position: relative; /* Add back for z-index to work */
|
||||
box-shadow: 3px 3px 0 var(--shadow-light), 6px 6px 0 var(--shadow-mid);
|
||||
transition: transform 0.35s cubic-bezier(0.68, -0.55, 0.27, 1.55),
|
||||
box-shadow 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55),
|
||||
@@ -241,8 +246,44 @@ social-links a:hover .fab.fa-youtube {
|
||||
border: 4px solid var(--post-border);
|
||||
background: var(--avatar-bg);
|
||||
text-align: center;
|
||||
transform: rotate(1deg);
|
||||
transform: rotate(0deg); /* Remove rotation from images */
|
||||
box-shadow: 4px 4px 0 var(--post-border);
|
||||
display: block; /* Ensure it's a block element */
|
||||
}
|
||||
|
||||
/* Ensure image containers can hold positioned tape */
|
||||
.image-placeholder,
|
||||
.image-placeholder img {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Force relative positioning on image links (containers) */
|
||||
a:has(.image-placeholder) {
|
||||
position: relative !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/* JavaScript-generated tape styling */
|
||||
.tape {
|
||||
position: absolute;
|
||||
background: rgba(255, 248, 220, 0.9);
|
||||
border: 0.5px solid rgba(0, 0, 0, 0.18);
|
||||
z-index: 100;
|
||||
pointer-events: none;
|
||||
box-shadow: 1px 1px 3px rgba(0,0,0,0.3);
|
||||
background-image: linear-gradient(45deg,
|
||||
rgba(255, 255, 255, 0.3) 25%,
|
||||
transparent 25%,
|
||||
transparent 75%,
|
||||
rgba(255, 255, 255, 0.3) 75%);
|
||||
background-size: 3px 3px;
|
||||
/* Zig-zag mask on top/bottom (long) sides, subtle and thin */
|
||||
-webkit-mask-image: url("data:image/svg+xml;utf8,<svg width='100' height='20' viewBox='0 0 100 20' xmlns='http://www.w3.org/2000/svg'><polygon points='0,0 100,0 100,20 0,20' fill='white'/><polyline points='0,0 5,8 10,0 15,8 20,0 25,8 30,0 35,8 40,0 45,8 50,0 55,8 60,0 65,8 70,0 75,8 80,0 85,8 90,0 95,8 100,0' fill='none' stroke='white' stroke-width='1'/><polyline points='0,20 5,12 10,20 15,12 20,20 25,12 30,20 35,12 40,20 45,12 50,20 55,12 60,20 65,12 70,20 75,12 80,20 85,12 90,20 95,12 100,20' fill='none' stroke='white' stroke-width='1'/></svg>");
|
||||
mask-image: url("data:image/svg+xml;utf8,<svg width='100' height='20' viewBox='0 0 100 20' xmlns='http://www.w3.org/2000/svg'><polygon points='0,0 100,0 100,20 0,20' fill='white'/><polyline points='0,0 5,8 10,0 15,8 20,0 25,8 30,0 35,8 40,0 45,8 50,0 55,8 60,0 65,8 70,0 75,8 80,0 85,8 90,0 95,8 100,0' fill='none' stroke='white' stroke-width='1'/><polyline points='0,20 5,12 10,20 15,12 20,20 25,12 30,20 35,12 40,20 45,12 50,20 55,12 60,20 65,12 70,20 75,12 80,20 85,12 90,20 95,12 100,20' fill='none' stroke='white' stroke-width='1'/></svg>");
|
||||
-webkit-mask-size: 100% 100%;
|
||||
mask-size: 100% 100%;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
mask-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.post-actions {
|
||||
|
||||
11
website/styles.css
Normal file
11
website/styles.css
Normal file
@@ -0,0 +1,11 @@
|
||||
.post {
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||
transition: box-shadow 0.3s ease, transform 0.3s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.post:hover {
|
||||
box-shadow: 0 12px 35px rgba(0, 0, 0, 0.3);
|
||||
z-index: 999 !important;
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
283
website/tape-debug.js
Normal file
283
website/tape-debug.js
Normal file
@@ -0,0 +1,283 @@
|
||||
class TapeDebugger {
|
||||
constructor() {
|
||||
this.enabled = false;
|
||||
this.debugOverlay = null;
|
||||
this.debugInfo = null;
|
||||
this.setupDebugUI();
|
||||
}
|
||||
|
||||
setupDebugUI() {
|
||||
// Create debug toggle button
|
||||
const debugButton = document.createElement('button');
|
||||
debugButton.textContent = 'Debug Tape';
|
||||
debugButton.style.cssText = `
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
z-index: 10000; /* Increased to ensure button is always visible */
|
||||
padding: 10px;
|
||||
background: #ff4444;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-family: monospace;
|
||||
font-weight: bold;
|
||||
`;
|
||||
debugButton.onclick = () => this.toggleDebug();
|
||||
document.body.appendChild(debugButton);
|
||||
|
||||
// Create debug overlay
|
||||
this.debugOverlay = document.createElement('div');
|
||||
this.debugOverlay.style.cssText = `
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 9999; /* Increased to appear above tape */
|
||||
display: none;
|
||||
`;
|
||||
document.body.appendChild(this.debugOverlay);
|
||||
|
||||
// Create debug info panel
|
||||
this.debugInfo = document.createElement('div');
|
||||
this.debugInfo.style.cssText = `
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
right: 10px;
|
||||
width: 300px;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
color: white;
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
z-index: 10000; /* Increased to ensure panel is always visible */
|
||||
display: none;
|
||||
`;
|
||||
document.body.appendChild(this.debugInfo);
|
||||
}
|
||||
|
||||
toggleDebug() {
|
||||
this.enabled = !this.enabled;
|
||||
if (this.enabled) {
|
||||
this.showDebug();
|
||||
} else {
|
||||
this.hideDebug();
|
||||
}
|
||||
}
|
||||
|
||||
showDebug() {
|
||||
console.log('[Tape Debug] Enabling visual debugging');
|
||||
this.debugOverlay.style.display = 'block';
|
||||
this.debugInfo.style.display = 'block';
|
||||
this.visualizeAllTape();
|
||||
this.updateDebugInfo();
|
||||
}
|
||||
|
||||
hideDebug() {
|
||||
console.log('[Tape Debug] Disabling visual debugging');
|
||||
this.debugOverlay.style.display = 'none';
|
||||
this.debugInfo.style.display = 'none';
|
||||
this.debugOverlay.innerHTML = '';
|
||||
}
|
||||
|
||||
visualizeAllTape() {
|
||||
this.debugOverlay.innerHTML = '';
|
||||
const images = document.querySelectorAll('.image-placeholder');
|
||||
|
||||
images.forEach((image, imageIndex) => {
|
||||
this.visualizeImageDebug(image, imageIndex);
|
||||
});
|
||||
}
|
||||
|
||||
visualizeImageDebug(image, imageIndex) {
|
||||
const rect = image.getBoundingClientRect();
|
||||
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
|
||||
|
||||
// Create image outline
|
||||
const imageOutline = document.createElement('div');
|
||||
imageOutline.style.cssText = `
|
||||
position: absolute;
|
||||
left: ${rect.left + scrollLeft}px;
|
||||
top: ${rect.top + scrollTop}px;
|
||||
width: ${rect.width}px;
|
||||
height: ${rect.height}px;
|
||||
border: 3px solid #00ff00;
|
||||
background: rgba(0, 255, 0, 0.1);
|
||||
pointer-events: none;
|
||||
`;
|
||||
|
||||
// Add image label
|
||||
const imageLabel = document.createElement('div');
|
||||
imageLabel.textContent = `IMG ${imageIndex + 1}`;
|
||||
imageLabel.style.cssText = `
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
left: 0;
|
||||
background: #00ff00;
|
||||
color: black;
|
||||
padding: 2px 6px;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
`;
|
||||
imageOutline.appendChild(imageLabel);
|
||||
|
||||
// Visualize tape pieces
|
||||
const tapeElements = image.querySelectorAll('.tape');
|
||||
tapeElements.forEach((tape, tapeIndex) => {
|
||||
this.visualizeTapeDebug(tape, tapeIndex, rect, scrollTop, scrollLeft, imageIndex);
|
||||
});
|
||||
|
||||
this.debugOverlay.appendChild(imageOutline);
|
||||
}
|
||||
|
||||
visualizeTapeDebug(tape, tapeIndex, imageRect, scrollTop, scrollLeft, imageIndex) {
|
||||
const tapeRect = tape.getBoundingClientRect();
|
||||
|
||||
// Create tape outline
|
||||
const tapeOutline = document.createElement('div');
|
||||
tapeOutline.style.cssText = `
|
||||
position: absolute;
|
||||
left: ${tapeRect.left + scrollLeft}px;
|
||||
top: ${tapeRect.top + scrollTop}px;
|
||||
width: ${tapeRect.width}px;
|
||||
height: ${tapeRect.height}px;
|
||||
border: 2px solid #ff0000;
|
||||
background: rgba(255, 0, 0, 0.3);
|
||||
pointer-events: none;
|
||||
transform: ${tape.style.transform};
|
||||
`;
|
||||
|
||||
// Add tape label
|
||||
const tapeLabel = document.createElement('div');
|
||||
tapeLabel.textContent = `T${tapeIndex + 1}`;
|
||||
tapeLabel.style.cssText = `
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: #ff0000;
|
||||
color: white;
|
||||
padding: 1px 3px;
|
||||
font-size: 8px;
|
||||
font-weight: bold;
|
||||
`;
|
||||
tapeOutline.appendChild(tapeLabel);
|
||||
|
||||
// Add positioning info
|
||||
const positionInfo = document.createElement('div');
|
||||
const corner = this.determineTapeCorner(tape);
|
||||
positionInfo.textContent = corner;
|
||||
positionInfo.style.cssText = `
|
||||
position: absolute;
|
||||
top: -15px;
|
||||
left: 0;
|
||||
background: #ff0000;
|
||||
color: white;
|
||||
padding: 1px 3px;
|
||||
font-size: 8px;
|
||||
white-space: nowrap;
|
||||
`;
|
||||
tapeOutline.appendChild(positionInfo);
|
||||
|
||||
this.debugOverlay.appendChild(tapeOutline);
|
||||
}
|
||||
|
||||
determineTapeCorner(tape) {
|
||||
const style = tape.style;
|
||||
if (style.top && style.left) return 'TOP-LEFT';
|
||||
if (style.top && style.right) return 'TOP-RIGHT';
|
||||
if (style.bottom && style.left) return 'BOTTOM-LEFT';
|
||||
if (style.bottom && style.right) return 'BOTTOM-RIGHT';
|
||||
return 'UNKNOWN';
|
||||
}
|
||||
|
||||
updateDebugInfo() {
|
||||
const images = document.querySelectorAll('.image-placeholder');
|
||||
const tapeElements = document.querySelectorAll('.tape');
|
||||
|
||||
let infoHtml = `
|
||||
<h3 style="margin-top: 0; color: #ff4444;">🎬 Tape Debug Info</h3>
|
||||
<div><strong>Images:</strong> ${images.length}</div>
|
||||
<div><strong>Tape Elements:</strong> ${tapeElements.length}</div>
|
||||
<div><strong>Expected Tape:</strong> ${images.length * 2}</div>
|
||||
<hr style="border-color: #333;">
|
||||
`;
|
||||
|
||||
images.forEach((image, index) => {
|
||||
const tapes = image.querySelectorAll('.tape');
|
||||
const pattern = index % 2 === 0 ? 'Pattern 1 (TL+BR)' : 'Pattern 2 (TR+BL)';
|
||||
|
||||
infoHtml += `
|
||||
<div style="margin: 10px 0; padding: 8px; background: rgba(255,255,255,0.1); border-radius: 3px;">
|
||||
<strong>Image ${index + 1}:</strong><br>
|
||||
Pattern: ${pattern}<br>
|
||||
Tape Count: ${tapes.length}/2<br>
|
||||
${tapes.length !== 2 ? '<span style="color: #ff4444;">⚠️ Missing tape!</span>' : '<span style="color: #44ff44;">✓ Complete</span>'}
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
// Add tape details
|
||||
tapeElements.forEach((tape, index) => {
|
||||
const corner = this.determineTapeCorner(tape);
|
||||
const transform = tape.style.transform || 'none';
|
||||
const size = `${tape.style.width} x ${tape.style.height}`;
|
||||
|
||||
infoHtml += `
|
||||
<div style="margin: 5px 0; padding: 5px; background: rgba(255,0,0,0.1); border-radius: 3px; font-size: 10px;">
|
||||
<strong>Tape ${index + 1}:</strong> ${corner}<br>
|
||||
Size: ${size}<br>
|
||||
Transform: ${transform}
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
this.debugInfo.innerHTML = infoHtml;
|
||||
}
|
||||
|
||||
// Method to refresh debug visualization when layout changes
|
||||
refresh() {
|
||||
if (this.enabled) {
|
||||
this.visualizeAllTape();
|
||||
this.updateDebugInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize debugger
|
||||
const tapeDebugger = new TapeDebugger();
|
||||
|
||||
// Add to global scope for easy access
|
||||
window.tapeDebugger = tapeDebugger;
|
||||
|
||||
// Hook into existing functions to update debug visualization
|
||||
const originalAddTapeToImages = window.addTapeToImages;
|
||||
const originalRefreshTape = window.refreshTape;
|
||||
|
||||
if (originalAddTapeToImages) {
|
||||
window.addTapeToImages = function() {
|
||||
originalAddTapeToImages.apply(this, arguments);
|
||||
setTimeout(() => tapeDebugger.refresh(), 100);
|
||||
};
|
||||
}
|
||||
|
||||
if (originalRefreshTape) {
|
||||
window.refreshTape = function() {
|
||||
originalRefreshTape.apply(this, arguments);
|
||||
setTimeout(() => tapeDebugger.refresh(), 100);
|
||||
};
|
||||
}
|
||||
|
||||
// Refresh debug on window resize
|
||||
window.addEventListener('resize', () => {
|
||||
setTimeout(() => tapeDebugger.refresh(), 200);
|
||||
});
|
||||
|
||||
console.log('[Tape Debug] Visual debugging system loaded. Click "Debug Tape" button to toggle.');
|
||||
174
website/tape.js
Normal file
174
website/tape.js
Normal file
@@ -0,0 +1,174 @@
|
||||
function addTapeToImages() {
|
||||
const images = document.querySelectorAll('.image-placeholder');
|
||||
console.log(`[Tape] Found ${images.length} images to add tape to`);
|
||||
|
||||
if (images.length === 0) {
|
||||
console.warn('[Tape] No .image-placeholder elements found');
|
||||
return;
|
||||
}
|
||||
|
||||
images.forEach((image, index) => {
|
||||
console.log(`[Tape] Processing image ${index + 1}/${images.length}`);
|
||||
|
||||
// Check if image already has tape
|
||||
const existingTape = image.querySelectorAll('.tape');
|
||||
if (existingTape.length > 0) {
|
||||
console.log(`[Tape] Image ${index + 1} already has tape, skipping`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure the image parent has relative positioning
|
||||
const imageParent = image.parentElement;
|
||||
if (imageParent && window.getComputedStyle(imageParent).position === 'static') {
|
||||
imageParent.style.position = 'relative';
|
||||
console.log(`[Tape] Set image parent to relative positioning`);
|
||||
}
|
||||
|
||||
// Create two tape pieces
|
||||
const tape1 = createTapeElement(index, 1);
|
||||
const tape2 = createTapeElement(index, 2);
|
||||
|
||||
// Position based on pattern
|
||||
const usePattern1 = index % 2 === 0;
|
||||
if (usePattern1) {
|
||||
positionTape(tape1, 'top-left');
|
||||
positionTape(tape2, 'bottom-right');
|
||||
} else {
|
||||
positionTape(tape1, 'top-right');
|
||||
positionTape(tape2, 'bottom-left');
|
||||
}
|
||||
|
||||
// Add to the image's parent container
|
||||
imageParent.appendChild(tape1);
|
||||
imageParent.appendChild(tape2);
|
||||
|
||||
console.log(`[Tape] Added tape to image ${index + 1} parent`);
|
||||
});
|
||||
}
|
||||
|
||||
function createTapeElement(imageIndex, tapeNumber) {
|
||||
const tape = document.createElement('div');
|
||||
tape.className = 'tape';
|
||||
|
||||
// Even chunkier tape: wider and much taller
|
||||
const width = 60 + Math.random() * 20; // 60-80px
|
||||
const height = 40 + Math.random() * 16; // 40-56px
|
||||
|
||||
tape.style.cssText = `
|
||||
position: absolute;
|
||||
width: ${width}px;
|
||||
height: ${height}px;
|
||||
background: rgba(255, 248, 220, 0.93);
|
||||
z-index: 100;
|
||||
pointer-events: none;
|
||||
box-shadow: 2px 2px 6px rgba(0,0,0,0.18);
|
||||
background-image: linear-gradient(45deg,
|
||||
rgba(255, 255, 255, 0.25) 25%,
|
||||
transparent 25%,
|
||||
transparent 75%,
|
||||
rgba(255, 255, 255, 0.25) 75%);
|
||||
background-size: 4px 4px;
|
||||
`;
|
||||
|
||||
console.log(`[Tape] Created tape element ${tapeNumber} for image ${imageIndex + 1}`);
|
||||
return tape;
|
||||
}
|
||||
|
||||
function positionTape(tape, corner) {
|
||||
const randomOffset = () => Math.random() * 8 - 4; // -4 to 4px
|
||||
const randomRotation = (Math.random() * 20 - 10); // -10 to 10 degrees
|
||||
const OUT_X = 25; // px, how far out from the left/right
|
||||
const OUT_Y = 18; // px, how far out from the top/bottom
|
||||
|
||||
switch (corner) {
|
||||
case 'top-left':
|
||||
tape.style.top = `${-OUT_Y + randomOffset()}px`;
|
||||
tape.style.left = `${-OUT_X + randomOffset()}px`;
|
||||
tape.style.transform = `rotate(${-45 + randomRotation}deg)`;
|
||||
break;
|
||||
case 'top-right':
|
||||
tape.style.top = `${-OUT_Y + randomOffset()}px`;
|
||||
tape.style.right = `${-OUT_X + randomOffset()}px`;
|
||||
tape.style.transform = `rotate(${45 + randomRotation}deg)`;
|
||||
break;
|
||||
case 'bottom-left':
|
||||
tape.style.bottom = `${-OUT_Y + randomOffset()}px`;
|
||||
tape.style.left = `${-OUT_X + randomOffset()}px`;
|
||||
tape.style.transform = `rotate(${45 + randomRotation}deg)`;
|
||||
break;
|
||||
case 'bottom-right':
|
||||
tape.style.bottom = `${-OUT_Y + randomOffset()}px`;
|
||||
tape.style.right = `${-OUT_X + randomOffset()}px`;
|
||||
tape.style.transform = `rotate(${-45 + randomRotation}deg)`;
|
||||
break;
|
||||
}
|
||||
|
||||
console.log(`[Tape] Positioned tape at ${corner}:`, {
|
||||
top: tape.style.top,
|
||||
bottom: tape.style.bottom,
|
||||
left: tape.style.left,
|
||||
right: tape.style.right,
|
||||
transform: tape.style.transform
|
||||
});
|
||||
}
|
||||
|
||||
function refreshTape() {
|
||||
console.log('[Tape] Refreshing tape - removing existing tape');
|
||||
|
||||
// Remove existing tape
|
||||
const existingTape = document.querySelectorAll('.tape');
|
||||
console.log(`[Tape] Found ${existingTape.length} existing tape elements to remove`);
|
||||
|
||||
existingTape.forEach(tape => tape.remove());
|
||||
|
||||
console.log('[Tape] Re-adding tape to images');
|
||||
addTapeToImages();
|
||||
}
|
||||
|
||||
// Simple test function
|
||||
function testSimpleTape() {
|
||||
console.log('[Tape Test] Creating simple test...');
|
||||
|
||||
const firstImage = document.querySelector('.image-placeholder');
|
||||
if (!firstImage) {
|
||||
console.error('[Tape Test] No images found');
|
||||
return;
|
||||
}
|
||||
|
||||
const parent = firstImage.parentElement;
|
||||
parent.style.position = 'relative';
|
||||
|
||||
const testTape = document.createElement('div');
|
||||
testTape.className = 'tape';
|
||||
testTape.style.cssText = `
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
background: red;
|
||||
border: 2px solid black;
|
||||
z-index: 999;
|
||||
color: white;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
`;
|
||||
testTape.textContent = 'TEST';
|
||||
|
||||
parent.appendChild(testTape);
|
||||
console.log('[Tape Test] Added test tape to first image parent');
|
||||
|
||||
setTimeout(() => {
|
||||
testTape.remove();
|
||||
console.log('[Tape Test] Removed test tape');
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
// Export functions
|
||||
window.addTapeToImages = addTapeToImages;
|
||||
window.refreshTape = refreshTape;
|
||||
window.testSimpleTape = testSimpleTape;
|
||||
|
||||
console.log('[Tape] Simple tape system loaded. Use window.testSimpleTape() to test.');
|
||||
Reference in New Issue
Block a user