|
|
import { useCallback } from "react"; |
|
|
import { useScreenshot } from "use-react-screenshot"; |
|
|
|
|
|
export function useStoryCapture() { |
|
|
const [image, takeScreenshot] = useScreenshot({ |
|
|
type: "image/png", |
|
|
quality: 1.0, |
|
|
}); |
|
|
|
|
|
const calculateOptimalWidth = (element) => { |
|
|
|
|
|
const comicPages = element.querySelectorAll("[data-comic-page]"); |
|
|
if (!comicPages.length) return element.scrollWidth; |
|
|
|
|
|
|
|
|
const firstPage = comicPages[0]; |
|
|
const pageWidth = firstPage.offsetWidth; |
|
|
const gap = 32; |
|
|
const padding = 32; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const totalWidth = |
|
|
pageWidth * comicPages.length + |
|
|
(comicPages.length > 1 ? gap * (comicPages.length - 1) : 0) + |
|
|
padding * 2; |
|
|
|
|
|
console.log("Width calculation:", { |
|
|
numberOfPages: comicPages.length, |
|
|
pageWidth, |
|
|
gapBetweenPages: gap, |
|
|
totalGaps: comicPages.length > 1 ? gap * (comicPages.length - 1) : 0, |
|
|
padding, |
|
|
totalWidth, |
|
|
}); |
|
|
|
|
|
return totalWidth; |
|
|
}; |
|
|
|
|
|
const captureStory = useCallback( |
|
|
async (containerRef) => { |
|
|
if (!containerRef.current) return null; |
|
|
|
|
|
const element = containerRef.current.querySelector("[data-comic-layout]"); |
|
|
if (!element) { |
|
|
console.error("Comic layout container not found"); |
|
|
return null; |
|
|
} |
|
|
|
|
|
try { |
|
|
|
|
|
const originalStyle = element.style.cssText; |
|
|
const originalScroll = element.scrollLeft; |
|
|
const originalWidth = element.style.width; |
|
|
const originalPadding = element.style.padding; |
|
|
const originalGap = element.style.gap; |
|
|
|
|
|
|
|
|
const optimalWidth = calculateOptimalWidth(element); |
|
|
|
|
|
|
|
|
Object.assign(element.style, { |
|
|
width: `${optimalWidth}px`, |
|
|
display: "flex", |
|
|
flexDirection: "row", |
|
|
gap: "32px", |
|
|
padding: "32px", |
|
|
paddingLeft: "32px !important", |
|
|
paddingRight: "32px !important", |
|
|
overflow: "hidden", |
|
|
transition: "none", |
|
|
}); |
|
|
element.scrollLeft = 0; |
|
|
|
|
|
|
|
|
element.offsetHeight; |
|
|
|
|
|
|
|
|
const result = await takeScreenshot(element, { |
|
|
backgroundColor: "#242424", |
|
|
width: optimalWidth, |
|
|
height: element.scrollHeight, |
|
|
style: { |
|
|
transform: "none", |
|
|
transition: "none", |
|
|
}, |
|
|
}); |
|
|
|
|
|
|
|
|
element.style.cssText = originalStyle; |
|
|
element.style.width = originalWidth; |
|
|
element.style.padding = originalPadding; |
|
|
element.style.gap = originalGap; |
|
|
element.scrollLeft = originalScroll; |
|
|
|
|
|
return result; |
|
|
} catch (error) { |
|
|
console.error("Error capturing story:", error); |
|
|
return null; |
|
|
} |
|
|
}, |
|
|
[takeScreenshot] |
|
|
); |
|
|
|
|
|
const downloadStoryImage = useCallback( |
|
|
async (containerRef, filename = "my-story.png") => { |
|
|
const image = await captureStory(containerRef); |
|
|
if (!image) return; |
|
|
|
|
|
const link = document.createElement("a"); |
|
|
link.href = image; |
|
|
link.download = filename; |
|
|
document.body.appendChild(link); |
|
|
link.click(); |
|
|
document.body.removeChild(link); |
|
|
}, |
|
|
[captureStory] |
|
|
); |
|
|
|
|
|
return { |
|
|
captureStory, |
|
|
downloadStoryImage, |
|
|
}; |
|
|
} |
|
|
|