canvas 添加 竖版文字_html2canvas.js——HTML转Canvas工具

76e460ca51dff6574015191662833221.gif

72d7cb4dcfcfe18eaf25f82d39bb088b.png

5900d7dc3b75ccbe7544b3d0dabcb2ff.png

25条工作和生活原则

1 做大事和做小事的难易程度是一样的。所以要选择一个值得追求的宏伟目标,让回报与你的努力相匹配。

2 最优秀的高管不是天生的,而是后天磨砺的结果。他们好学不倦,永无止境。要善于研究你生活中取得巨大成功的人和组织,他们能够提供关于如何在现实世界获得成功的免费教程,可以帮助你进行自我提升。

3 给你敬佩的人写信或打电话,请他们提供建议或与其会面的机会。你永远不知道谁愿意跟你见面。最后你会从这些人身上学到很多重要的东西,建立你在余生都可以享用的人际关系。在生命早期结交的人,会与你缔结非同寻常的感情纽带。

4 人们总觉得最有意思的话题就是与自己相关的话题。所以,要善于分析他人的问题所在,并尝试提出办法来帮助他人。几乎所有的人,无论他声名多么显赫、地位多么高贵,都愿意接受新的想法,当然,前提是这些想法必须经过深思熟虑。

5 每个企业都是一个封闭的集成系统,内部各个组成部分性能独特却又相互关联。优秀的管理者既洞悉每个部分如何独立运行,也熟知各部分之间如何相互协作。

6 信息是最重要的商业资产。掌握得越多,拥有的视角就越多,在竞争对手面前就越有可能发现常规模式和异常现象。所以要始终对进入企业的新鲜事物保持开放的态度,无论是新的人、新的经验,还是新的知识。

7 在年轻的时候,请接受能为自己提供陡峭的学习曲线和艰苦的磨炼机会的工作。最初的工作是为人生打基础的,不要为了暂时的声望而轻易地接受一份工作。

8 在展示自己时,请记住,印象非常重要。整体形象必须毫无瑕疵。其他人会通过各种线索和端倪,判断你的真实面貌。所以,要重诺守时,要真实诚信,要准备充分。

9 再聪明的人也不能解决所有问题。聪明人组成的开诚布公的团队却可以无往而不利。

10 处于困境中的人往往只关注自己的问题,而解决问题的途径通常在于你如何解决别人的问题。

11 一个人的信念必须超越自我和个人需求,它可以是自己的公司、祖国或服役义务。任何因信念和核心价值观的激励而选择的挑战都是值得的,无论最终的结果是成功还是失败。

12 永远要黑白分明、百折不回。你的诚信必须要毋庸置疑。当一个人不需要付出代价或承担后果的时候,坚持做正确的事情并非难事。但当必须得放弃一些东西时,你就很难保持信用记录。要始终言而有信,不要为了自己的利益误导任何人。

13 要勇往直前。成功的企业家、经理和个人都是具有志在必得的气魄和一往无前的精神的人。他们会在恰当的时刻当仁不让。当其他人谨小慎微时,他们会接受风险;当其他人瞻前顾后时,他们会采取行动,但他们会选择明智的做法。这种特质是领导者的标志。

14 永远不要骄傲自满。没有什么是一成不变的。无论是个人还是企业,如果不经常寻求自我重塑和自我改进的方法,就会被竞争对手打败。尤其是组织,因为组织比想象中更脆弱。

15 极少有人能在首次推介中完成销售。仅仅因为你对一些事物有信念,并不意味着其他人也愿意接受。你需要能够一次又一次坚定地推销你的愿景。大多数人不喜欢改变,所以你需要说服他们为什么要接受改变。不要因为畏惧而不去争取自己想得到的东西。

16 如果你看到一个巨大的变革性机会,不要疑虑其他人为什么没有采取行动。你可能看到了他人没有看到的东西。问题越严峻,竞争就越有限,对问题解决者的回报就越大。

17 归根到底,成功就是抓住了寥寥可数的机遇。要始终保持开放的思维,冷静观察,高度警觉,随时准备抓住机会。要统筹合适的人力和其他资源,然后全力以赴。如果你没有准备好拼尽全力,要么是因为这个机会没有你想象的那么有吸引力,要么是因为你不是把握这一机遇的合适人选。

18 时间会对所有交易造成负面影响,有时甚至产生致命影响。一般情况下,等待的时间越久,意料之外的事情就越多。特别是在艰难的谈判中,要让所有人都在谈判桌上协商足够长的时间,以此达成协议。

19 不要赔钱!!!客观地评估每个机会的风险。

20 要在准备好时做出决定,而不是在压力之下。或为了达到个人目的,或因为内部政治斗争,或因为一些外部需求,其他人总会催促你做出决策。但几乎每次你都可以这么说:“我需要更多的时间来考虑这个问题。我想清楚了再回复你。”即使是在最艰难、最令人不快的情况下,这种策略也非常有效。

21 忧虑是一种积极的心理活动,可以开阔人的思路。如果能正确引导这一情绪,你就可以洞察任何形势下的负面风险,并采取行动规避这些风险。

22 失败是一个组织最好的老师。开诚布公地客观谈论失败,分析问题所在,你就会从失败中学到关于决策和组织行为的新规则。如果评估得当,失败就有可能改变一个组织的进程,使其在未来更加成功。

23 尽可能雇用10分人才,因为他们会积极主动地感知问题、设计解决方案,并朝着新方向开展业务。他们还会吸引和雇用其他10分人才。10分人才做什么事都会得心应手。

24 如果你认为一个人的本质是好的,就要随时为这个人提供帮助,即使其他人都离他而去。任何人都可能陷入困境。在别人需要的时候,一个偶然的善意行为就会改变他的生命轨迹,造就意想不到的友谊或忠诚。

25 每个人都有梦想。尽你所能帮助别人实现他们的目标。

50f72865d3335cc245dae9cd90379e50.gif 点击关注我哦 50f72865d3335cc245dae9cd90379e50.gif

我们经常会遇上动态生成海报的需求,而在Web前端中,生成图片非Canvas莫属。但是在实际工作当中,为了追求效率,我们会不可避免地去使用一些JS插件,而html2canvas.js就是一款优秀的插件,它可以轻松地帮你将HTML代码转换成Canvas,进而生成可保存分享的图片。

具体如何使用这款插件呢?接下来请让我用一个简单的示例来为大家讲解。

50f72865d3335cc245dae9cd90379e50.gif 点击关注我哦 50f72865d3335cc245dae9cd90379e50.gif业余草:www.xttblog.com e3cafd5bc8de7616a76182556592ef65.gif qianduanwz { e3cafd5bc8de7616a76182556592ef65.gif

width: 900px;

height: 383px;

text-align: center;

background: url("./bg.jpg") no-repeat center;

}

e3cafd5bc8de7616a76182556592ef65.gif qianduanwz img { e3cafd5bc8de7616a76182556592ef65.gif

width: 200px;

margin-top: 60px;

}

e3cafd5bc8de7616a76182556592ef65.gif qianduanwz p { e3cafd5bc8de7616a76182556592ef65.gif

margin: 0;

padding-top: 10px;

font-size: 20px;

color: #fff;

}

学习Web前端
关注前端微站

new html2canvas(document.getElementById('qianduanwz'), {

backgroundColor: "transparent",

allowTaint: true,

useCORS: true

}).then(canvas => {

// canvas为转换后的Canvas对象

let oImg = new Image();

oImg.src = canvas.toDataURL(); // 导出图片

document.body.appendChild(oImg); // 将生成的图片添加到body

});

// 渲染图片

function Render(src, width, height, cb) {

const img = new Image();

img.src = src;

img.width = width;

img.height = height;

img.crossOrigin = ""; // 图像跨域时配置

cb && cb(img);

}

// 下载图片

function Download(url, name) {

const target = document.createElement("a");

target.href = url;

target.download = name;

const event = document.createEvent("MouseEvents");

event.initEvent("click", true, true);

target.dispatchEvent(event);

}

const btn = document.getElementById("save-btn");

btn.addEventListener("click", () => {

const screenshot = document.getElementById("screenshot");

// allowTaint: true, // 不能与useCORS共用

const opts = {

logging: false,

scale: 2,

useCORS: true

};

Html2canvas(screenshot, opts).then(res => {

const { height, width } = res;

const base64 = res.toDataURL("image/png", 1);

Render(base64, width, height, img => {

document.body.appendChild(img);

Download(base64, "screenshot.png");

});

}, err => alert("截图失败,请重新尝试"));

});

f4b7cbf4bac6d8f9d082e6c7979889b6.png 50f72865d3335cc245dae9cd90379e50.gif 50f72865d3335cc245dae9cd90379e50.gif 50f72865d3335cc245dae9cd90379e50.gif 扫码关注我们 更多精彩等待你的发现 664cc777aabbec7c3571fb05aa4b0556.gif

现在假设要生成如下图片,而所有图片和文字都是动态获取的。

50f72865d3335cc245dae9cd90379e50.gif 点击关注我哦 50f72865d3335cc245dae9cd90379e50.gif

如今很多网站都引入截图功能,可用于问题反馈、内容分享等实用需求,而前端截图也不知不觉成为了首选。今天为大家推荐两种前端截图方式,虽然有些局限,但是也能应付大部分项目需求。

Canvas截图:html2canvas

SVG截图:rasterizehtml

原理其实很简单,虽然实现方式不太一致,但是核心思想是相同的。

以html2canvas为代表的Canvas截图,通过遍历DOM克隆一份副本,将此副本在Canvas上重新绘制,并根据DOM的样式应用在对应的绘制元素上,再通过Canvas生成图片。转换过程可理解成:DOM→Canvas→Image。

以rasterizehtml为代表的SVG截图,通过遍历DOM克隆一份副本,利用SVG的foreignObject把DOM作为外部资源嵌套在SVG中,将此SVG在Canvas上重新绘制,并根据DOM的样式应用在对应的绘制元素上,再通过Canvas生成图片。转换过程可理解成:DOM→SVG的ForeignObject→Canvas→Image。

两种前端截图方式最后都是通过把DOM绘制到Canvas,再通过Canvas输出图片。

虽然两种前端截图方式都有这两个封装得比较完善的第三方库html2canvas和rasterizehtml,但是由于在转换过程中存在一些自身的局限性,所以也导致截图可能出现一些不完美的问题。

Canvas截图的限制性:

无法渲染跨域资源(支持同域)

无法渲染iFrame和Flash内容(支持SVG)

SVG截图的限制性:

无法渲染跨域资源(支持同域)

无法渲染如lazyload等通过JS加载的资源

无法渲染内联background-image或JS操作background-image

不多废话,直接上两种前端截图方式的代码,小伙伴们可根据项目需求自行优化代码和增加功能哈。

测试代码如下:

Hello World
保存// 渲染图片 function Render(src, width, height, cb) { const img = new Image(); img.src = src; img.width = width; img.height = height; img.crossOrigin = ""; // 图像跨域时配置 cb && cb(img); } // 下载图片 function Download(url, name) { const target = document.createElement("a"); target.href = url; target.download = name; const event = document.createEvent("MouseEvents"); event.initEvent("click", true, true); target.dispatchEvent(event); }

Canvas截图核心代码如下所示:

import Html2canvas from "html2canvas"; const btn = document.getElementById("save-btn"); btn.addEventListener("click", () => { const screenshot = document.getElementById("screenshot"); // allowTaint: true, // 不能与useCORS共用 const opts = { logging: false, scale: 2, useCORS: true }; Html2canvas(screenshot, opts).then(res => { const { height, width } = res; const base64 = res.toDataURL("image/png", 1); Render(base64, width, height, img => { document.body.appendChild(img); Download(base64, "screenshot.png"); }); }, err => alert("截图失败,请重新尝试")); });

SVG截图核心代码如下所示:

import Rasterizehtml from "rasterizehtml"; const btn = document.getElementById("save-btn"); btn.addEventListener("click", () => { // drawURL()加载的URL必须是同域名URL或支持跨域的URL // 下面的URL是随便写的,记得换成同域名URL或支持跨域的URL const url = "https://www.baidu.com"; const canvas = document.createElement("canvas"); const opts = { executeJs: true, height: screen.height, width: screen.width }; Rasterizehtml.drawURL(url, canvas, opts).then(res => { const base64 = "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(res.svg))); Render(base64, opts.width, opts.height, img => { document.body.appendChild(img); Download(base64, "screenshot.png"); }); }, err => alert("截图失败,请重新尝试")); });

另外还有几点需要注意一下:

使用Canvas截图兼容低版本浏览器时,不能使用CSS3属性和带有前缀的属性

使用SVG截图可获取同域< iframe>内容进行渲染

使用SVG截图可获取同域

感兴趣的网友可结合自身项目尝试一下两种前端截图方式,探究下其相同点和不同点。如果对其截图原理感兴趣,可剖析下html2canvas和rasterizehtml的源码,相信你会有意外的收获喔!

664cc777aabbec7c3571fb05aa4b0556.gif

按照需求,我们无法使用PS去合成元素,只能通过代码动态生成,这时就可以用到html2canvas.js了。

1. 布局

学习Web前端
关注前端微站

2. 转换Canvas并导出图片

html2canvas.js用法其实很简单,通常情况下只需传入需要转换的DOM对象就可以了。如果你对canvas导出图片有疑惑,可以看之前写的一篇文章→

教你使用Canvas处理图片

3. 可能出现的问题及相应解决方案① 图片模糊问题

有时候我们会发现,导出的图片局部有些图片看起来没有原图那么清晰,这其实是因为你使用背景图片的原因。解决方法也很简单,就是直接使用标签就好了(比如上面示例中的背景图最好是用来替代)。

② 图片不显示问题

有时你可能莫名其妙地发现有些图片并没有出现在导出的图片中,这基本上就是因为图片素材出现跨域,也就是说图片所在的域名与你项目所在域名不一致。这个问题的解决方案就是html2canvas使用时多加以下两个配置项就好了。

allowTaint: true, useCORS: true

上面例子添加配置项后的代码如下:

newhtml2canvas(document.getElementById('qianduanwz'),{ allowTaint:true, useCORS:true}).then(canvas=>{ // ……});

③ PNG图片不透明问题

有时你可能用到透明的PNG图片作为背景图,可是结果最后生成的图片却并不透明,这是因为html2canvas生成的canvas背景颜色默认为白色的缘故,所以导出的图片背景颜色当然也是白色。

解决方案也是添加一个配置项就好(事实上经实验发现只要是非颜色类型的字符串都可以)。

backgroundColor: "transparent"

上面例子添加配置项后的代码如下:

newhtml2canvas(document.getElementById('qianduanwz'),{ backgroundColor:"transparent", allowTaint:true, useCORS:true}).then(canvas=>{ // ……});

④ 在iOS系统部分浏览器中,用
标签进行文字换行时,文本只显示第一行的问题

这种现象并不是必现的,但确实存在这样的问题,这时解决问题的方式也很简单,就是不用
标签来换行,而是采用其他块级标签元素对需要进行换行的文字分别包裹即可。

例如:

想学习前端,
可关注微信公众号:前端微站

可写成:

  • 想学习前端,
  • 可关注微信公众号:前端微站

重点总结

① 生成图片的HTML尽量使用而不使用背景图

② { allowTaint: true, useCORS: true }可解决跨域图片不显示问题

③ { backgroundColor: "transparent" }可解决图片不透明问题

知道你会来

所以我一直在这里等

1、赠人玫瑰,手留余香。这句话是出自印度古谚,赠人玫瑰之手,经久犹有余香。用英语说是“The roses in her hand,the flavor in mine.”意思是一件很平凡微小的事情,哪怕如同赠人一支玫瑰般微不足道,但它带来的温馨都会在赠花人和受花人的心底慢慢升腾、弥漫、覆盖。

7ac4bfe2712d1fd45709bf98006316c6.png

2、有福同享,有难同当。意思是幸福共同分享,苦难共同分担,形容患难与共,和衷共济。出自《官场现形记》第五回:“还有一件:从前老爷有过话,是‘有福同享,有难同当’。现在老爷有得升官发财,我们做家人的出了力、赔了钱,只落得一个半途而废。”

8d43dbc014bcbf36389f94f29a566c6f.png

3、乐人之乐,人亦乐其乐;忧人之忧,人亦忧其忧。出自唐代白居易《辩兴亡之由策》。白话文意思是:为别人的快乐而高兴,别人也会为你的快乐而高兴;为别人的忧愁而担忧,别人也会为你的忧愁而担忧。

4、如果你把快乐告诉一个朋友,你将得到两个快乐,而如果你把忧愁向一个朋友倾诉,你将被分掉一半忧愁。出自弗朗西斯·培根(英国)。意思是说朋友可以和你分享快乐和烦恼,快乐时,可以与朋友一起快乐,那样会更快乐。烦恼时,与朋友倾诉,就可以一起解决这个烦恼。

5、好咖啡要和朋友一起品尝,好机会也要和朋友一起分享;我们必须与其它生命共同分享我们的地球。出自美国雷切尔·卡森。意思是分享是我们每个人都应该做的事。无论您有多忙,请在文章右下角给朋友送上一个“在看”,可能您的朋友就需要!

8092c330e2ed4e8116ed39eb4795598f.png

PS:老规矩哟,先点击“在看”或转发,私信截图到后台,再取资料,获取方式见视频。

资料下载

谢谢大家的支持,有了大家的支持我才更有动力去给大家更新干货黑科技!300个在看给我安排上!然后记得回复关键词,自取呦。看到这的,都是真粉丝,感谢你们,给我坚持下去的理由。

老规矩,兄弟们还记得么,右下角的 “在看” 点一下,文章最底部的小广gào 点一下,如果感觉分享的不错,记得分享朋友圈让更多的人知道!

点个在看,支持小编
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值