javascript - 将 DIV 导出为 JPG/PNG - html2canvas 不起作用

标签 javascript css canvas html5-canvas html2canvas

我创建了一种 Logo 生成器,它使用自定义 CSS 样式创建 div。我想添加按钮“下载”,以便让用户将其作为 png/jpg 文件获取。

我浏览了 stackoverflow 上的所有其他帖子,但它们对我不起作用。我试过 html2canvas 但没有给出预期的结果。

我的分区:

<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>

看起来像:

enter image description here

当 canvas 创建时:

enter image description here

根据文档,某些 CSS 可能不受支持,恐怕这就是我的情况。有没有其他方法可以将这个 DIV 保存为图片?

最佳答案

html2canvas 似乎不允许多重文本阴影,但您可以使用 native Canvas 命令获得类似的效果。

您可以在 Canvas 上绘制定向阴影(如运动模糊)。

enter image description here

  1. 在第二个(内存中的 Canvas )上,在阴影方向获取图像的轮廓。

    • 绘制图像时在阴影方向偏移几个像素。

    • 使用destination-out 合成删除原始图像。这只留下只有几个像素宽的阴影轮廓。

  2. 在第三个 Canvas 上,重复绘制阴影并增加偏移量。这会创建完整的阴影(但它目前是完全不透明的——不是渐变)。

  3. 在主 Canvas 上填充一个渐变,从图像 [x,y] 开始,延伸到图像的长度略小于阴影长度。

  4. 使用 source-in 合成将第三个 Canvas 的阴影绘制到主 Canvas 上。合成将使阴影绘制成渐变色。

  5. 在阴影上绘制原始图像。

  6. 使用 destination-over 合成在阴影图像“下方”绘制背景。

  7. 完成——你有一张带有尾随阴影的图像

这是示例代码和演示:

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>

或者,您可以通过重复绘制具有不同不透明度的图像来创建运动模糊效果。

enter image description here

示例代码和演示

警告:示例代码具有硬编码值——需要进行调整!

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>

关于javascript - 将 DIV 导出为 JPG/PNG - html2canvas 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33904971/

相关文章:

java - 如何在android中使用Canvas在线尖上画一个圆

javascript - 如何使用 JavaScript 将 base64 图像保存到用户的磁盘?

javascript - 移动设备上的Java单击事件

c# - 有没有办法以编程方式导出/保存生成的 javascript 和 css 包?

css - React Slick 渲染中的幻灯片溢出

html - 为什么图像在 CSS Grid 中重叠?

JavaScript 类 - 对象初始化时调用方法

javascript - 在窗口大小调整时重新加载 bxSlider

javascript - window.GetAnimationFrame() 没有调用回调函数

Android AdMob 横幅添加到 Canvas 之上?