简体   繁体   中英

Export DIV to JPG/PNG - html2canvas doesnt work

I have created kind of logo generator which creates div with custom css styling. I would like to add button "Download" in order to let users get it as png/jpg file.

I went through all other post on stackoverflow but they didn't work for me. I tried html2canvas but that doesn't gives expected results.

My div:

<i id="icon" class="fa fa-android" style="text-shadow: rgb(48, 117, 165) 0px 0px, rgb(48, 118, 167) 1px 1px, rgb(49, 120, 169) 2px 2px, rgb(49, 121, 171) 3px 3px, rgb(50, 123, 173) 4px 4px, rgb(51, 124, 175) 5px 5px, rgb(51, 125, 177) 6px 6px, rgb(52, 127, 179) 7px 7px, rgb(52, 128, 181) 8px 8px, rgb(53, 130, 183) 9px 9px, rgb(53, 131, 185) 10px 10px, rgb(54, 133, 187) 11px 11px, rgb(55, 134, 189) 12px 12px, rgb(55, 136, 191) 13px 13px, rgb(56, 137, 193) 14px 14px, rgb(56, 138, 195) 15px 15px, rgb(57, 140, 197) 16px 16px, rgb(58, 141, 199) 17px 17px, rgb(58, 143, 201) 18px 18px, rgb(59, 144, 203) 19px 19px, rgb(59, 146, 205) 20px 20px, rgb(60, 147, 207) 21px 21px, rgb(60, 148, 209) 22px 22px, rgb(61, 150, 211) 23px 23px, rgb(62, 151, 213) 24px 24px, rgb(62, 153, 215) 25px 25px, rgb(63, 154, 217) 26px 26px, rgb(63, 156, 219) 27px 27px, rgb(64, 157, 221) 28px 28px, rgb(65, 158, 223) 29px 29px, rgb(65, 160, 225) 30px 30px, rgb(66, 161, 227) 31px 31px, rgb(66, 163, 229) 32px 32px, rgb(67, 164, 231) 33px 33px, rgb(67, 166, 233) 34px 34px; font-size: 80px; color: white; height: 150px; width: 150px; line-height: 150px; border-radius: 0%; text-align: center; background-color: rgb(68, 167, 235);"></i>

It looks like:

在此处输入图片说明

While canvas creates that:

在此处输入图片说明

According to documentation some of the CSS might not be supported and I am afraid that this what is happening in my case. Is there other way to save this DIV as a picture?

It appears that html2canvas will not allow multiple text-shadowing but you can get a similar effect using native canvas commands.

You can draw a directional shadow (like a motion blur) on the canvas.

在此处输入图片说明

  1. On a second (in-memory canvas), get the outline of the image just in the shadow direction.

    • Draw the image with an offset of a few pixels in the shadow direction.

    • Use destination-out compositing to erase the original image. This leaves just the shadow outline which will be only a few pixels wide.

  2. On a third canvas, repeatedly draw the shadow with an increasing offset. This creates the full shadow (but it's currently fully opaque -- not gradient).

  3. Fill a gradient on the main canvas going from the image [x,y] and extending past the image by a bit less than the shadow length.

  4. Draw the shadow from the third canvas onto the main canvas with source-in compositing. Compositing will cause the shadow to be drawn with a gradient.

  5. Draw the original image over the shadow.

  6. Draw the background "under" the shadowed image using destination-over compositing.

  7. Done -- you have an image with a trailing shadow

Here's example code and a Demo:

 var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var cw=canvas.width; var ch=canvas.height; var c=document.createElement('canvas'); cctx=c.getContext('2d'); var cc=document.createElement('canvas'); ccctx=cc.getContext('2d'); c.width=cc.width=cw; c.height=cc.height=ch; // x,y of the image var x=50; var y=50; // shadowing definition variables var offsetX=2; var offsetY=2; var extent=50; var img=new Image(); img.onload=start; img.src="https://dl.dropboxusercontent.com/u/139992952/multple/android.png"; function start(){ // get the offset outline of the image on a second // by drawing the image offset by a few pixels // and then erasing the un-offset image // which leaves just the "shadow" outline cctx.drawImage(img,x+offsetX,y+offsetY); cctx.globalCompositeOperation='destination-out'; cctx.drawImage(img,x,y); cctx.drawImage(img,x,y); cctx.drawImage(img,x,y); cctx.globalCompositeOperation='source-atop'; cctx.fillStyle='black'; cctx.fillRect(0,0,cw,ch); // draw the "shadow" canvas repeatedly // with an increasing offset onto another canvas for(var i=0;i<extent;i++){ ccctx.drawImage(c,i,i) } // create a gradient on the main canvas // going from the image x,y and extending past the image // by a bit less than the shadow length var g=ctx.createLinearGradient(x,y,x+img.width+extent*.75,y+img.height+extent*.75); g.addColorStop(0.00,'rgba(0,0,0,0.50)'); g.addColorStop(0.75,'rgba(0,0,0,.10)'); g.addColorStop(1.00,'rgba(0,0,0,0)'); ctx.fillStyle=g; ctx.fillRect(0,0,cw,ch); // draw the extended shadow from the 3rd canvas onto // the main canvas with 'source-in' compositing so // the shadow is made gradient ctx.globalCompositeOperation='source-in'; ctx.drawImage(cc,0,0); // draw the original image over the shadow // the original image is now shadowed ctx.globalCompositeOperation='source-over'; ctx.drawImage(img,x,y); // draw the background "under" the shadowed image // using 'destination-over' compositing ctx.globalCompositeOperation='destination-over'; ctx.fillStyle='#44A7EB'; ctx.fillRect(0,0,cw,ch); } 
 body{ background-color: ivory; } canvas{border:1px solid red; margin:0 auto; } 
 <canvas id="canvas" width=400 height=400></canvas> 

Alternatively , you can create a motion-blur effect by repeatedly drawing an image with different opacities.

在此处输入图片说明

Example code and a Demo

Warning: example code has hard-coded values -- tweaking required!

 var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var cw=canvas.width; var ch=canvas.height; var image=new Image(); image.onload=start; image.src="https://dl.dropboxusercontent.com/u/139992952/multple/android.png"; function start(){ var c=document.createElement('canvas'); var cctx=c.getContext('2d'); c.width=image.width; c.height=image.height; cctx.translate(c.width/2,c.height/2); cctx.rotate(Math.PI/4); cctx.drawImage(image,-image.width/2,-image.height/2); cctx.setTransform(1,0,0,1,0,0); cctx.globalCompositeOperation='source-atop'; cctx.fillRect(0,0,c.width,c.height); ctx.translate(-50,0); ctx.translate(100,200); ctx.rotate(-Math.PI/4); ctx.clearRect(0,0,canvas.width,canvas.height) var y=0; while (++y <= 100) { ctx.globalAlpha=1/y; ctx.drawImage(c, 0,0, image.width, image.height+y); } ctx.globalAlpha=1; ctx.setTransform(1,0,0,1,0,0); ctx.drawImage(image,96.5,87.5); ctx.globalCompositeOperation='destination-over'; ctx.fillStyle='#44A7EB'; ctx.fillRect(0,0,cw,ch); } 
 body{ background-color: ivory; } canvas{border:1px solid red; margin:0 auto; } 
 <canvas id="canvas" width=500 height=400></canvas> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM