@@ -25,25 +25,31 @@ import { baseCSSCache } from '../core/cache.js'
2525
2626export async function captureDOM ( element , options = { } ) {
2727 if ( ! element ) throw new Error ( "Element cannot be null or undefined" ) ;
28+ if ( ! ( element instanceof Element ) ) throw new Error ( "captureDOM: Only Element nodes are supported" ) ;
29+
2830 const { compress = true , embedFonts = false , fast = true , scale = 1 } = options ;
2931 let clone , classCSS , styleCache ;
3032 let fontsCSS = "" ;
3133 let baseCSS = "" ;
3234 let dataURL ;
3335 let svgString ;
36+
3437 ( { clone, classCSS, styleCache } = await prepareClone ( element , compress , embedFonts ) ) ;
38+
3539 await new Promise ( ( resolve ) => {
3640 idle ( async ( ) => {
3741 await inlineImages ( clone , options ) ;
3842 resolve ( ) ;
3943 } , { fast } ) ;
4044 } ) ;
45+
4146 await new Promise ( ( resolve ) => {
4247 idle ( async ( ) => {
4348 await inlineBackgroundImages ( element , clone , styleCache , options ) ;
4449 resolve ( ) ;
4550 } , { fast } ) ;
4651 } ) ;
52+
4753 if ( embedFonts ) {
4854 await new Promise ( ( resolve ) => {
4955 idle ( async ( ) => {
@@ -52,6 +58,7 @@ export async function captureDOM(element, options = {}) {
5258 } , { fast } ) ;
5359 } ) ;
5460 }
61+
5562 if ( compress ) {
5663 const usedTags = collectUsedTagNames ( clone ) . sort ( ) ;
5764 const tagKey = usedTags . join ( "," ) ;
@@ -67,17 +74,54 @@ export async function captureDOM(element, options = {}) {
6774 } ) ;
6875 }
6976 }
77+
7078 await new Promise ( ( resolve ) => {
7179 idle ( ( ) => {
7280 const rect = element . getBoundingClientRect ( ) ;
73- // para capurar drop shadow en raster hay que aumentar el tmano aca
74- const w = Math . ceil ( rect . width ) ;
75- const h = Math . ceil ( rect . height ) ;
76- clone . setAttribute ( "xmlns" , "http://www.w3.org/1999/xhtml" ) ;
77- clone . style . transformOrigin = "top left" ;
78- if ( scale !== 1 && isSafari ( ) ) {
81+ let w = rect . width ;
82+ let h = rect . height ;
83+
84+ const hasW = Number . isFinite ( options . width ) ;
85+ const hasH = Number . isFinite ( options . height ) ;
86+ const hasScale = typeof scale === "number" && scale !== 1 ;
87+
88+ if ( ! hasScale ) {
89+ const aspect = rect . width / rect . height ;
90+
91+ if ( hasW && hasH ) {
92+ w = options . width ;
93+ h = options . height ;
94+ } else if ( hasW ) {
95+ w = options . width ;
96+ h = w / aspect ;
97+ } else if ( hasH ) {
98+ h = options . height ;
99+ w = h * aspect ;
100+ }
101+ }
102+
103+ w = Math . ceil ( w ) ;
104+ h = Math . ceil ( h ) ;
105+
106+ clone . setAttribute ( "xmlns" , "http://www.w3.org/1999/xhtml" ) ;
107+ clone . style . transformOrigin = "top left" ;
108+
109+ if ( ! hasScale && ( hasW || hasH ) ) {
110+ // Solo aplicar escala CSS si no estamos usando scale para escalar
111+ const originalW = rect . width ;
112+ const originalH = rect . height ;
113+
114+ const scaleX = w / originalW ;
115+ const scaleY = h / originalH ;
116+
117+ const existingTransform = clone . style . transform || '' ;
118+ const scaleTransform = `scale(${ scaleX } , ${ scaleY } )` ;
119+ clone . style . transform = `${ scaleTransform } ${ existingTransform } ` . trim ( ) ;
120+ } else if ( hasScale && isSafari ( ) ) {
121+ // En Safari se puede usar style.scale para un escalado más directo
79122 clone . style . scale = `${ scale } ` ;
80123 }
124+
81125 const svgNS = "http://www.w3.org/2000/svg" ;
82126 const fo = document . createElementNS ( svgNS , "foreignObject" ) ;
83127 fo . setAttribute ( "width" , "100%" ) ;
@@ -86,16 +130,21 @@ export async function captureDOM(element, options = {}) {
86130 styleTag . textContent = baseCSS + fontsCSS + "svg{overflow:visible;}" + classCSS ;
87131 fo . appendChild ( styleTag ) ;
88132 fo . appendChild ( clone ) ;
133+
89134 const serializer = new XMLSerializer ( ) ;
90135 const foString = serializer . serializeToString ( fo ) ;
136+
91137 const svgHeader = `<svg xmlns="${ svgNS } " width="${ w } " height="${ h } " viewBox="0 0 ${ w } ${ h } ">` ;
92138 const svgFooter = "</svg>" ;
93139 svgString = svgHeader + foString + svgFooter ;
140+
94141 dataURL = `data:image/svg+xml;charset=utf-8,${ encodeURIComponent ( svgString ) } ` ;
95142 resolve ( ) ;
96143 } , { fast } ) ;
97144 } ) ;
145+
98146 const sandbox = document . getElementById ( "snapdom-sandbox" ) ;
99147 if ( sandbox && sandbox . style . position === "absolute" ) sandbox . remove ( ) ;
148+
100149 return dataURL ;
101150}
0 commit comments