credTpl.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1">
  6. <!-- 强制让文档与设备的宽度保持1:1 -->
  7. <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  8. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  9. <script type="text/javascript" src="http://cdn.webfont.youziku.com/wwwroot/js/wf/youziku.api.min.js"></script>
  10. <script type="text/javascript">
  11. $youziku.load(".txtStyle", "2bbc4dcf2e874e37875bd362aad4e32e", "Source-Han-Sans-Medium");
  12. $youziku.draw();
  13. </script>
  14. <style type="text/css">
  15. * {
  16. margin: 0;
  17. padding: 0;
  18. border: 0;
  19. }
  20. .ui-absolute {
  21. position: absolute;
  22. top: 0;
  23. bottom: 0;
  24. left: 0;
  25. right: 0;
  26. margin: auto;
  27. }
  28. .ui-relative {
  29. position: relative;
  30. }
  31. .cred {
  32. background: url(bg.png) no-repeat center center;
  33. background-size: 100% 100%;
  34. width: calc(908px/1.5);
  35. height: calc(1304px/1.5);
  36. font-size: calc(908px/1.5*0.11);
  37. margin: 0 auto;
  38. }
  39. .cred .logo,
  40. .cred .QR-code {
  41. bottom: auto;
  42. overflow: hidden;
  43. left: 50%;
  44. right: auto;
  45. transform: translateX(-50%);
  46. }
  47. .cred .QR-code {
  48. top:86%;
  49. right:45%;
  50. padding-top: 10%;
  51. width: 10%;
  52. background: url(code.png) no-repeat center center;
  53. background-size: 100% 100%;
  54. border-radius: 0;
  55. }
  56. .cred .title {
  57. font-size: .45em;
  58. top: 19%;
  59. bottom: auto;
  60. text-align: center;
  61. line-height: 1.5em;
  62. /*color: #00984C;*/
  63. }
  64. .cred .title .coreTitle{
  65. font-size:0.8em;
  66. color:#329800;
  67. }
  68. .cred .title .subTitle{
  69. margin-top:-0.1em
  70. font-weight:bold;
  71. color:#35A129;
  72. }
  73. .cred .number {
  74. top: 29.8%;
  75. bottom: auto;
  76. font-size: .19em;
  77. text-align: center;
  78. line-height: 1em;
  79. color: #339A00;
  80. }
  81. .cred .content {
  82. top: 33%;
  83. bottom: auto;
  84. font-size: .32em;
  85. color: #323334;
  86. margin: auto 12% auto 13%;
  87. font-weight: 300;
  88. }
  89. .cred .content p {
  90. text-indent: 2em;
  91. line-height: 2em;
  92. letter-spacing: .05em;
  93. word-wrap: break-word;
  94. word-break: break-all;
  95. }
  96. .cred .content .name {
  97. text-indent: 0;
  98. }
  99. .cred .content p span {
  100. border-bottom: 2px solid #010101;
  101. overflow: hidden;
  102. }
  103. .cred .seal-1,
  104. .cred .seal-2 {
  105. top: 72%;
  106. bottom: auto;
  107. width: 26.22%;
  108. padding-top: 26.22%;
  109. border-radius: 50%;
  110. }
  111. .cred .seal-1 {
  112. background: url(z1.png) no-repeat center center;
  113. background-size: 100% 100%;
  114. left: 20%;
  115. right: auto;
  116. }
  117. .cred .seal-2 {
  118. background: url(z2.png) no-repeat center center;
  119. background-size: 100% 100%;
  120. right: 20%;
  121. left: auto;
  122. }
  123. .cred .seal-1-text {
  124. top: 84%;
  125. padding-top: 0;
  126. background: none;
  127. font-size: .25em;
  128. bottom: auto;
  129. line-height: 1em;
  130. color: #000;
  131. display: flex;
  132. text-align: center;
  133. width: 60%;
  134. left: 10%;
  135. right: 10%;
  136. }
  137. .cred .seal-1-text span {
  138. flex: 1;
  139. }
  140. .cred .seal-1-text.time {
  141. top: 90%;
  142. right: 0;
  143. left: 0;
  144. margin: auto;
  145. text-align: center;
  146. }
  147. .cred .foot-text {
  148. top: auto;
  149. bottom: 6.82%;
  150. font-size: .23em;
  151. line-height: 1.5em;
  152. left: 13.43%;
  153. right: 13.43%;
  154. color: #595656;
  155. text-indent: 2em;
  156. letter-spacing: .1em;
  157. }
  158. .cred .stamp{
  159. width:2.4em;
  160. height:1.8em;
  161. top:58%;
  162. text-align:center;
  163. }
  164. .cred .stamp p{
  165. position:absolute;
  166. font-size:0.2em;
  167. z-index:1;
  168. color:#333;
  169. }
  170. .cred .stamp .stampImg{
  171. position:absolute;
  172. width:1.6em;
  173. height:1.6em;
  174. z-index:2;
  175. left: 50%;
  176. margin-left:-0.9em;
  177. }
  178. .cred .stampLeft{
  179. left:-39%;
  180. }
  181. .cred .stampLeft .stampImg{
  182. background:url("./hjt.png") no-repeat;
  183. background-size:cover;
  184. }
  185. .cred .stampLeft p.orgName{
  186. top:2.6em;
  187. left:1.5em;
  188. }
  189. .cred .stampLeft p.buyDate{
  190. top:4.1em;
  191. left:1.9em;
  192. }
  193. .cred .stampRight{
  194. right:-45%;
  195. }
  196. .cred .stampRight .stampImg{
  197. background:url("./gysy.png") no-repeat;
  198. background-size:cover;
  199. }
  200. .cred .stampRight p.orgName{
  201. top:2.6em;
  202. left:-0.4em;
  203. }
  204. .cred .stampRight p.buyDate{
  205. top:4.4em;
  206. left:1.9em;
  207. }
  208. </style>
  209. </head>
  210. <body>
  211. <div class="ui-relative cred" id="cred">
  212. <div class="ui-absolute QR-code"></div>
  213. <div class='ui-absolute title txtStyle'>
  214. <p class="coreTitle"><span>碳汇+</span><span>生态产品价值实现</span></p>
  215. <p class="subTitle"><span>碳中和证书</span></p>
  216. </div>
  217. <div class="ui-absolute number txtStyle">
  218. </div>
  219. <div class="ui-absolute content txtStyle">
  220. </div>
  221. <div class="ui-absolute stamp stampLeft">
  222. <div class="stampImg"></div>
  223. <p class="orgName">重庆市生态环境局</p>
  224. <p class="buyDate time"></p>
  225. </div>
  226. <div class="ui-absolute stamp stampRight">
  227. <div class="stampImg"></div>
  228. <p class="orgName">重庆市阳光公益事业基金会</p>
  229. <p class="buyDate time"></p>
  230. </div>
  231. </div>
  232. </body>
  233. <script src="html2canvas.js" type="text/javascript" charset="utf-8"></script>
  234. <script type="text/javascript">
  235. //下载图片
  236. let downloadImg = function(obj) {
  237. obj = obj || {};
  238. this.imgData = obj.data.toDataURL((obj.format || 'image/jpg')) || null;
  239. this.src = '';
  240. this.init();
  241. };
  242. downloadImg.prototype.init = function() {
  243. this.downloadImgFile(this.imgData);
  244. };
  245. //下载
  246. downloadImg.prototype.downloadImgFile = function(content) {
  247. var _this = this;
  248. var blob = this.base64ToBlob(content);
  249. this.src = URL.createObjectURL(blob);
  250. };
  251. downloadImg.prototype.base64ToBlob = function(code) {
  252. let parts = code.split(';base64,');
  253. let contentType = parts[0].split(':')[1];
  254. let raw = window.atob(parts[1]);
  255. let rawLength = raw.length;
  256. let uInt8Array = new Uint8Array(rawLength);
  257. for (let i = 0; i < rawLength; ++i) {
  258. uInt8Array[i] = raw.charCodeAt(i);
  259. }
  260. return new Blob([uInt8Array], {
  261. type: contentType
  262. });
  263. };
  264. window.certificate = function(obj) {
  265. // console.log(obj)
  266. var _this = this;
  267. _this.obj = obj || {
  268. elem: 'cred'
  269. };
  270. _this.contentData = obj.data || {};
  271. _this.content();
  272. _this.elem = _this.obj.elem || 'cred'; //要绘制的页面
  273. _this.elemObj = document.getElementById(_this.elem);
  274. _this.format = _this.obj.format || "jpg"; //下载格式
  275. _this.success = obj.success || function(url, data) {
  276. console.log("没有配置success接收函数");
  277. };
  278. _this.type = null;
  279. _this.A0 = {
  280. width: '1080px',
  281. height: '1551px',
  282. 'font-size': '118.8px'
  283. };
  284. _this.A3 = {
  285. width: '3058px',
  286. 'height': '4961px',
  287. 'font-size': '336.38px'
  288. };
  289. _this.A4 = {
  290. 'width': '2048px',
  291. 'height': '3508px',
  292. 'font-size': '225.28px'
  293. };
  294. // _this.down('A0');
  295. };
  296. certificate.prototype.content = function(obj) {
  297. var _this = this;
  298. this.contentData = obj || this.contentData;
  299. // console.log(this.contentData)
  300. let span = function(name, bool) {
  301. let html = '';
  302. let arr = (typeof(_this.contentData[name]) == 'undefined' ? [] : _this.contentData[name]) + '';
  303. for (let i in arr) {
  304. html += bool ? '<span>' + arr[i] + '</span>' : arr[i];
  305. }
  306. return html;
  307. };
  308. document.getElementsByClassName('number')[0].innerHTML = this.contentData.code == '0' ? '' : '证书编号:' + this.contentData
  309. .code;
  310. document.getElementsByClassName('content')[0].innerHTML = '<p class="name">尊敬的' + span('name', true) +
  311. ':</p>\
  312. <p>感谢您对“碳汇+”生态产品价值实现的支持,您购买了'+ span('year') + '年度碳汇量' + span('co2') + 'kg,\
  313. 您购碳资金' + span('money') +'元,已全额转入'+ span('farmerName') +'的银行账户。</p>\
  314. <p>该笔碳汇可用于抵消您的碳排放</p>\
  315. <p>感谢您为生态文明建设和全球应对气候变化所做出的贡献。</p>';
  316. document.getElementsByClassName('time')[0].innerHTML = "<span>" + this.contentData.date + "</span>";
  317. document.getElementsByClassName('time')[1].innerHTML = "<span>" + this.contentData.date + "</span>";
  318. };
  319. certificate.prototype.generate = function() {
  320. var _this = this;
  321. _this.style(_this.elemObj, _this[_this.type]);
  322. return _this;
  323. };
  324. certificate.prototype.style = function(elem, styleObj) {
  325. for (let i in styleObj) {
  326. elem.style[i] = styleObj[i];
  327. }
  328. return elem;
  329. };
  330. certificate.prototype.down = function(type) {
  331. if (this.type == type) {
  332. this.aLink.dispatchEvent(this.evt);
  333. return -1;
  334. } else {
  335. this.type = type;
  336. return this.generate().html2canvas();
  337. }
  338. };
  339. certificate.prototype.html2canvas = function() {
  340. var _this = this;
  341. html2canvas(_this.elemObj).then(function(canvas) {
  342. let img = new downloadImg({
  343. data: canvas,
  344. format: 'image/' + (_this.format || 'jpg'),
  345. });
  346. if (img.src) {
  347. _this.src = img.src;
  348. if (_this.success) {
  349. _this.data = canvas.toDataURL('image/' + (_this.format || 'jpg'));
  350. _this.aLink = document.createElement('a');
  351. _this.evt = document.createEvent("MouseEvents");
  352. _this.evt.initEvent("click", true, true);
  353. _this.aLink.download = new Date().getTime() + '.' + (_this.format || 'jpg');
  354. _this.aLink.href = _this.src;
  355. _this.success(function(type) {
  356. switch (type) {
  357. case 'down':
  358. _this.aLink.dispatchEvent(_this.evt);
  359. return _this.src;
  360. break;
  361. case 'url':
  362. return _this.src;
  363. break;
  364. case 'data':
  365. return _this.data;
  366. break;
  367. default:
  368. return _this.src;
  369. }
  370. }, _this.data);
  371. }
  372. }
  373. });
  374. return _this;
  375. };
  376. </script>
  377. </html>