@@ -87,4 +87,48 @@ document.addEventListener("DOMContentLoaded", () => {
8787 } ;
8888 img . src = url ;
8989 } ) ;
90+
91+ const copyPng = document . getElementById ( "copy-png" ) ;
92+ copyPng . addEventListener ( "click" , function ( event ) {
93+ // get svg element
94+ const svgElement = document . getElementById ( "svg-container" ) . querySelector ( "svg" ) ;
95+ if ( ! svgElement ) {
96+ alert ( "No SVG found to convert to PNG." ) ;
97+ return ;
98+ }
99+ // serialise svg to string
100+ const svgData = new XMLSerializer ( ) . serializeToString ( svgElement ) ;
101+ const svgBlob = new Blob ( [ svgData ] , { type : "image/svg+xml;charset=utf-8" } ) ;
102+ const url = URL . createObjectURL ( svgBlob ) ;
103+ // create image element to load svg
104+ const img = new Image ( ) ;
105+ img . onload = function ( ) {
106+ // create canvas to draw image
107+ const canvas = document . createElement ( "canvas" ) ;
108+ canvas . width = 2028 ;
109+ canvas . height = 2028 ;
110+ // draw image to canvas
111+ const ctx = canvas . getContext ( "2d" ) ;
112+ ctx . drawImage ( img , 0 , 0 , canvas . width , canvas . height ) ;
113+ // convert canvas to blob
114+ canvas . toBlob ( function ( blob ) {
115+ // copy to clipboard
116+ const item = new ClipboardItem ( { "image/png" : blob } ) ;
117+ navigator . clipboard . write ( [ item ] ) . then ( ( ) => {
118+ // show success state
119+ copyPng . classList . remove ( "btn-outline-secondary" ) ;
120+ copyPng . classList . add ( "btn-success" ) ;
121+ copyPng . innerHTML = "<i class='ph-bold ph-check'></i> Copied" ;
122+ // revert after 2 seconds
123+ setTimeout ( ( ) => {
124+ copyPng . classList . remove ( "btn-success" ) ;
125+ copyPng . classList . add ( "btn-outline-secondary" ) ;
126+ copyPng . innerHTML = "Copy PNG" ;
127+ } , 2000 ) ;
128+ } ) ;
129+ URL . revokeObjectURL ( url ) ;
130+ } , "image/png" ) ;
131+ } ;
132+ img . src = url ;
133+ } ) ;
90134} ) ;
0 commit comments