printmap.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <script setup>
  2. /**
  3. * element-plus组件
  4. */
  5. import {
  6. ElMessage
  7. } from 'element-plus';
  8. import {
  9. ref
  10. } from "vue";
  11. import {
  12. inject
  13. } from "vue";
  14. import html2canvas from "html2canvas";
  15. const getMapInstance = inject("getMapInstance");
  16. jt3d = getMapInstance();
  17. </script>
  18. <template>
  19. <div class="jt-MapPrinting">
  20. <div class="middleviewer">
  21. <el-input v-model="inputValue.mapname" placeholder="请输入地图名称" @focus="getfous" @blur="onblur" />
  22. <div class="viewer">
  23. <div id="printbox" ref="print"></div>
  24. <div class="viewertop" display='block' ref="thumbnailmap"></div>
  25. <div style="display:none" ref="originalmap"></div>
  26. </div>
  27. </div>
  28. <div class="viewerbottom">
  29. <!-- <el-button color="rgb(20 136 255)" v-print="printObj"><span style="color: #fff;font-size: 16rem;">打 印</span></el-button> -->
  30. <el-button color="rgb(255 100 100)" @click="download"><span style="color: #fff;font-size: 16rem;">下 载</span></el-button>
  31. </div>
  32. </div>
  33. </template>
  34. <script>
  35. let jt3d = undefined;
  36. export default {
  37. data() {
  38. return {
  39. inputValue: {
  40. mapname: "默认地图",
  41. },
  42. printObj: {
  43. id: "printbox",
  44. popTitle: "", // 打印配置页上方的标题
  45. extraCss: "background-color:red",
  46. preview: false, // 是否启动预览模式,默认是false
  47. previewTitle: " 关闭预览", // 打印预览的标题
  48. previewPrintBtnLabel: "点击打印", // 打印预览的标题下方的按钮文本,点击可进入打印
  49. zIndex: 20002, // 预览窗口的z-index,默认是20002,最好比默认值更高
  50. previewBeforeOpenCallback() {
  51. console.log("正在加载预览窗口!")
  52. }, // 预览窗口打开之前的callback
  53. previewOpenCallback() {
  54. console.log("已经加载完预览窗口,预览打开了!");
  55. }, // 预览窗口打开时的callback
  56. beforeOpenCallback() {
  57. console.log("开始打印之前!");
  58. }, // 开始打印之前的callback
  59. openCallback() {
  60. console.log("执行打印了!");
  61. }, // 调用打印时的callback
  62. closeCallback() {
  63. console.log("关闭了打印工具!");
  64. },
  65. clickMounted() {
  66. console.log("点击v-print绑定的按钮了!");
  67. },
  68. standard: "",
  69. extarCss: "",
  70. },
  71. };
  72. },
  73. methods: {
  74. //当选择器的输入框获得焦点时触发,标题获取焦点清空输入框
  75. getfous() {
  76. this.inputValue.mapname = ""
  77. },
  78. //当选择器的输入框失去焦点时触发
  79. onblur() {
  80. //删除print组件的内容
  81. this.$refs.print.innerHTML = "";
  82. // 获取标题
  83. let value = this.inputValue.mapname;
  84. //获取输入框的缺省内容
  85. let text = value.length > 0 ? value : '默认地图标题';
  86. let canvas = this.changcanvastitile(this.$refs.originalmap.lastChild, text);
  87. let url = canvas.toDataURL('image/png', 5.0)
  88. let img = document.createElement('img');
  89. img.style.display = "block"
  90. img.style.width = canvas.style.width;
  91. img.style.height = canvas.style.height;
  92. img.src = url
  93. this.$refs.print.appendChild(img);
  94. },
  95. //下载按钮
  96. download() {
  97. if (this.$refs.originalmap.children.length <= 0) {
  98. ElMessage.error("截图未成功");
  99. return
  100. }
  101. let value = this.inputValue.mapname;
  102. //获取输入框的缺省内容
  103. let text = value.length > 0 ? value : '默认地图标题';
  104. let img = this.$refs.print.lastChild;
  105. let a = document.createElement('a');
  106. a.style.display = 'none';
  107. a.download = text + '.png';
  108. a.href = img.src;
  109. document.body.appendChild(a);
  110. a.click();
  111. document.body.removeChild(a);
  112. },
  113. //更新打印标题
  114. changcanvastitile(canvas, text) {
  115. //清理标题位置区域
  116. let width = parseInt(canvas.style.width.slice(0, -2));
  117. let height = parseInt(canvas.style.height.slice(0, -2));
  118. //获取上下文
  119. const ctx = canvas.getContext('2d');
  120. //清理标题问题
  121. ctx.clearRect(0, 0, width, 160)
  122. //设置字体
  123. ctx.font = "bold 50rem arial";
  124. document.fonts.load(ctx.font);
  125. //设置填充颜色
  126. ctx.fillStyle = "black";
  127. //循环输入标题,字间距50rem
  128. for (let i = 0; i < text.length; i++) {
  129. //第I个字的水平位置=((canvs.leght)/2-(text.legth)*letterspace/2+i*letterspace)
  130. let x = Math.ceil(width / 2) - (text.length - 1) * 50 + i * 100
  131. //水平绘制填充文本
  132. ctx.fillText(text[i], x, 100);
  133. }
  134. return canvas;
  135. },
  136. //打印地图截屏
  137. screenshot() {
  138. this.$refs.print.innerHTML = "";
  139. this.$refs.thumbnailmap.innerHTML = ""
  140. this.$refs.originalmap.innerHTML = '';
  141. this.inputValue.mapname = "默认地图"
  142. html2canvas(this.$parent.$parent.$refs.refMap3d.$refs.cesiumContainer, {
  143. // backgroundColor: null, //画出来的图片有白色的边框,不要可设置背景为透明色(null)
  144. useCORS: true, //支持图片跨域
  145. scale: 1, //设置放大的倍数
  146. // tainTest:false,
  147. // foreignObjectRendering: true,//// 是否在浏览器支持的情况下使用ForeignObject渲染
  148. dpi: 300,
  149. // width:1920,
  150. // height:1080
  151. }).then(
  152. (canvas) => {
  153. let url = canvas.toDataURL('image/png', 5.0)
  154. let img = document.createElement('img');
  155. img.style.display = "block"
  156. img.style.width = "calc(100% - 0rem)"
  157. img.style.height = "calc(100% - 0rem)";
  158. img.src = url
  159. //缩略图
  160. this.$refs.thumbnailmap.appendChild(img);
  161. //创建新的canvas
  162. let canvasnew = this.createmap(canvas)
  163. let urla = canvasnew.toDataURL('image/png', 5.0)
  164. let imga = document.createElement('img');
  165. imga.style.display = "block"
  166. imga.style.width = canvas.style.width / 2;
  167. imga.style.height = canvas.style.height / 2;
  168. imga.src = urla
  169. //原图
  170. this.$refs.originalmap.appendChild(canvasnew);
  171. //打印图
  172. this.$refs.print.appendChild(imga)
  173. }
  174. )
  175. },
  176. createmap(img) {
  177. //渲染之前先清理掉所有所有指定canvas
  178. if (document.getElementById('canvasid')) {
  179. document.getElementById('canvasid').remove();
  180. }
  181. let width = parseInt(img.style.width.slice(0, -2));
  182. let height = parseInt(img.style.height.slice(0, -2));
  183. let canvas = this.createHDCanvas(width + 60, height + 160, 'block')
  184. //获取上下文
  185. const ctx = canvas.getContext('2d');
  186. //获取图片对象
  187. ctx.drawImage(img, 30, 120, width, height)
  188. // let value = this.$refs.refinput.value;
  189. let value = this.inputValue.mapname;
  190. let text = value.length > 0 ? value : '默认地图标题';
  191. console.log("text")
  192. console.log(text)
  193. ctx.clearRect(0, 0, width, 120)
  194. //设置字体
  195. ctx.font = "bold 50rem arial";
  196. //设置填充颜色
  197. ctx.fillStyle = "black";
  198. //循环输入标题,字间距50rem
  199. for (let i = 0; i < text.length; i++) {
  200. //第I个字的水平位置=((canvs.leght)/2-(text.legth)*letterspace/2+i*letterspace)
  201. let x = Math.ceil(width / 2) - (text.length - 1) * 50 + i * 100
  202. //水平绘制填充文本
  203. ctx.fillText(text[i], x, 100);
  204. }
  205. return canvas;
  206. },
  207. createHDCanvas(w = 300, h = 150, display = 'block') {
  208. let ratio = window.devicePixelRatio * 1 || 1;
  209. let canvas = document.createElement('canvas');
  210. canvas.id = "canvasid";
  211. canvas.width = w * ratio; // 实际渲染像素
  212. canvas.height = h * ratio; // 实际渲染像素
  213. canvas.style.display = display;
  214. canvas.style.width = `${w}rem`; // 控制显示大小
  215. canvas.style.height = `${h}rem`; // 控制显示大小
  216. canvas.style.backgroundColor = "red";
  217. // setTransform() 允许您缩放、旋转、移动并倾斜当前的环境
  218. canvas.getContext('2d').setTransform(ratio, 0, 0, ratio, 0, 0);
  219. return canvas;
  220. },
  221. },
  222. mounted() {
  223. // //获取角色
  224. // this.info = JSON.parse(localStorage.getItem("person"));
  225. // //获取角色id
  226. // this.id = this.info.id;
  227. // this.$bus.on("screenshot", (e) => {
  228. // console.log("aaaaa")
  229. // this.screenshot()
  230. // })
  231. },
  232. };
  233. </script>
  234. <style lang="scss" scoped>
  235. .jt-MapPrinting {
  236. width: 100%;
  237. height: 100%;
  238. overflow: hidden;
  239. --el-fill-color-blank: rgb(0 44 126 / 68%);
  240. --el-text-color-regular: rgb(216 240 255);
  241. --el-border-color: rgb(35 135 255);
  242. .middleviewer {
  243. height: 92%;
  244. .viewer {
  245. position: relative;
  246. width: 100% !important;
  247. height: calc(100% - 29rem) !important;
  248. overflow: hidden;
  249. .viewertop {
  250. width: calc(100% - 2rem);
  251. height: calc(100% - 2rem);
  252. border: 1rem solid rgb(35 135 255);
  253. position: absolute;
  254. top: 0;
  255. left: 0;
  256. }
  257. }
  258. }
  259. .viewerbottom {
  260. margin: 10rem;
  261. }
  262. }
  263. ::v-deep .el-input {
  264. flex-grow: 0 !important;
  265. width: calc(100%);
  266. height: 30rem !important;
  267. letter-spacing: 100rem;
  268. }
  269. //输入框文字颜色
  270. ::v-deep .el-input__inner {
  271. color: rgb(255, 255, 255);
  272. text-align: center;
  273. }
  274. //输入框背景色
  275. ::v-deep .el-input__wrapper {
  276. background-color: rgba(255, 255, 255, 0) !important;
  277. }
  278. ::v-deep .el-button {
  279. border-radius: 3rem !important;
  280. height: 32rem;
  281. }
  282. ::v-deep .el-button--primary {
  283. background-color: rgba(64, 158, 255, 0.6) !important;
  284. }
  285. ::-webkit-scrollbar {
  286. width: 0rem;
  287. }
  288. </style>