drawSign.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. <template>
  2. <multi-color-background>
  3. <h1 class="title">手绘签名</h1>
  4. <div class="inner draw" >
  5. <div class="canvas-container" @mousemove="beginPath($event)">
  6. <canvas
  7. id="canvas"
  8. class="fl"
  9. :width="canvasWidth"
  10. :height="canvasHeight"
  11. @mousedown="canvasDown($event)"
  12. @mouseup="canvasUp($event)"
  13. @mousemove="canvasMove($event)"
  14. @touchstart="canvasDown($event)"
  15. @touchend="canvasUp($event)"
  16. @touchmove="canvasMove($event)"
  17. >
  18. </canvas>
  19. </div>
  20. <div class="control">
  21. <!--画笔颜色-->
  22. <div class="canvas-color clearfix">
  23. <ul>
  24. <li
  25. v-for="item in colors"
  26. class="color-shower"
  27. :class="{'active':config.lineColor === item}"
  28. :style="{ background: item }"
  29. @click="setColor(item)"
  30. ></li>
  31. </ul>
  32. </div>
  33. <!--操作-->
  34. <div class="canvas-control clearfix">
  35. <button class="go-prev action-button" @click="controlCanvas('prev')"><-</button>
  36. <button class="go-next action-button" @click="controlCanvas('next')">-></button>
  37. </div>
  38. <!-- 生成图像-->
  39. </div>
  40. <button class="draw-image" @click="getImage()">预览</button>
  41. <!--存放图片-->
  42. </div>
  43. </multi-color-background>
  44. </template>
  45. <script>
  46. import MultiColorBackground from "../components/multiColorBackground";
  47. export default {
  48. components: {MultiColorBackground},
  49. data () {
  50. return {
  51. colors: ['#333333','#1491e2','#df4848'],
  52. context: {},
  53. imgUrl: [],
  54. canvasMoveUse: true,
  55. // 存储当前表面状态数组-上一步
  56. preDrawAry: [],
  57. // 存储当前表面状态数组-下一步
  58. nextDrawAry: [],
  59. // 中间数组
  60. middleAry: [],
  61. // 配置参数
  62. config: {
  63. lineWidth: 1,
  64. lineColor: '#333333',
  65. shadowBlur: 2
  66. },
  67. canvasHeight:0,
  68. canvasWidth:0
  69. }
  70. },
  71. created () {
  72. },
  73. mounted () {
  74. const canvas = document.querySelector('#canvas')
  75. this.canvasHeight=parseFloat(window.getComputedStyle(canvas).getPropertyValue('height'));
  76. this.canvasWidth=parseFloat(window.getComputedStyle(canvas).getPropertyValue('width'));
  77. this.context = canvas.getContext('2d')
  78. this.initDraw()
  79. this.setCanvasStyle()
  80. // document.querySelector('#footer').classList.add('hide-footer')
  81. // document.querySelector('body').classList.add('fix-body')
  82. },
  83. destroyed () {
  84. // document.querySelector('#footer').classList.remove('hide-footer')
  85. // document.querySelector('body').classList.remove('fix-body')
  86. },
  87. computed: {
  88. controls () {
  89. return [{
  90. title: '上一步',
  91. action: 'prev',
  92. className: this.preDrawAry.length ? 'active fa fa-reply' : 'fa fa-reply'
  93. }, {
  94. title: '下一步',
  95. action: 'next',
  96. className: this.nextDrawAry.length ? 'active fa fa-share' : 'fa fa-share'
  97. }, {
  98. title: '清除',
  99. action: 'clear',
  100. className: (this.preDrawAry.length || this.nextDrawAry.length) ? 'active fa fa-trash' : 'fa fa-trash'
  101. }]
  102. }
  103. },
  104. methods: {
  105. isPc () {
  106. const userAgentInfo = navigator.userAgent
  107. const Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
  108. let flag = true
  109. for (let v = 0; v < Agents.length; v++) {
  110. if (userAgentInfo.indexOf(Agents[v]) > 0) {
  111. flag = false
  112. break
  113. }
  114. }
  115. return flag
  116. },
  117. removeImg (src) {
  118. this.imgUrl = this.imgUrl.filter(item => item !== src)
  119. },
  120. initDraw () {
  121. const preData = this.context.getImageData(0, 0, this.canvasWidth, this.canvasHeight)
  122. // 空绘图表面进栈
  123. this.middleAry.push(preData)
  124. },
  125. canvasMove (e) {
  126. if (this.canvasMoveUse) {
  127. console.log('canvasMove')
  128. const t = e.target
  129. let canvasX
  130. let canvasY
  131. if (this.isPc()) {
  132. canvasX = e.clientX - t.parentNode.offsetLeft
  133. canvasY = e.clientY - t.parentNode.offsetTop
  134. } else {
  135. canvasX = e.changedTouches[0].clientX - t.parentNode.offsetLeft
  136. canvasY = e.changedTouches[0].clientY - t.parentNode.offsetTop
  137. }
  138. this.context.lineTo(canvasX, canvasY)
  139. this.context.stroke()
  140. }
  141. },
  142. beginPath (e) {
  143. const canvas = document.querySelector('#canvas')
  144. if (e.target !== canvas) {
  145. console.log('beginPath')
  146. this.context.beginPath()
  147. }
  148. },
  149. // mouseup
  150. canvasUp (e) {
  151. console.log('canvasUp')
  152. const preData = this.context.getImageData(0, 0, 600, 400)
  153. if (!this.nextDrawAry.length) {
  154. // 当前绘图表面进栈
  155. this.middleAry.push(preData)
  156. } else {
  157. this.middleAry = []
  158. this.middleAry = this.middleAry.concat(this.preDrawAry)
  159. this.middleAry.push(preData)
  160. this.nextDrawAry = []
  161. }
  162. this.canvasMoveUse = false
  163. },
  164. // mousedown
  165. canvasDown (e) {
  166. console.log('canvasDown')
  167. this.canvasMoveUse = true
  168. // client是基于整个页面的坐标
  169. // offset是cavas距离顶部以及左边的距离
  170. const canvasX = e.clientX - e.target.parentNode.offsetLeft
  171. const canvasY = e.clientY - e.target.parentNode.offsetTop
  172. this.setCanvasStyle()
  173. // 清除子路径
  174. this.context.beginPath()
  175. this.context.moveTo(canvasX, canvasY)
  176. console.log('moveTo', canvasX, canvasY)
  177. // 当前绘图表面状态
  178. const preData = this.context.getImageData(0, 0, 600, 400)
  179. // 当前绘图表面进栈
  180. this.preDrawAry.push(preData)
  181. },
  182. // 设置颜色
  183. setColor (color) {
  184. // console.log(111)
  185. this.config.lineColor = color
  186. },
  187. // 操作
  188. controlCanvas (action) {
  189. switch (action) {
  190. case 'prev':
  191. if (this.preDrawAry.length) {
  192. const popData = this.preDrawAry.pop()
  193. const midData = this.middleAry[this.preDrawAry.length + 1]
  194. this.nextDrawAry.push(midData)
  195. this.context.putImageData(popData, 0, 0)
  196. }
  197. break
  198. case 'next':
  199. if (this.nextDrawAry.length) {
  200. const popData = this.nextDrawAry.pop()
  201. const midData = this.middleAry[this.middleAry.length - this.nextDrawAry.length - 2]
  202. this.preDrawAry.push(midData)
  203. this.context.putImageData(popData, 0, 0)
  204. }
  205. break
  206. case 'clear':
  207. this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height)
  208. this.preDrawAry = []
  209. this.nextDrawAry = []
  210. this.middleAry = [this.middleAry[0]]
  211. break
  212. }
  213. },
  214. // 生成图片
  215. getImage () {
  216. const canvas = document.querySelector('#canvas')
  217. const src = canvas.toDataURL('image/png')
  218. this.imgUrl.push(src)
  219. console.log(src);
  220. },
  221. // 设置绘画配置
  222. setCanvasStyle () {
  223. this.context.lineWidth = this.config.lineWidth
  224. this.context.shadowBlur = this.config.shadowBlur
  225. this.context.shadowColor = this.config.lineColor
  226. this.context.strokeStyle = this.config.lineColor
  227. }
  228. }
  229. }
  230. </script>
  231. <style >
  232. .title{
  233. color:white;
  234. font-size: 0.5rem;
  235. margin-top: 0.6rem;
  236. }
  237. .control{
  238. width: 100%;
  239. margin-top: 0.6rem;
  240. }
  241. .draw-image{
  242. width: 100%;
  243. height: 1.1rem;
  244. border-radius: 0.6rem;
  245. border: none;
  246. background-color: #60c0ff;
  247. color: #fff;
  248. font-size: 0.4rem;
  249. margin-top: 0.6rem;
  250. }
  251. .canvas-container{
  252. padding: 1px;
  253. width: 100%;
  254. height: 11.1rem;
  255. }
  256. .inner{
  257. margin: 0.4rem 0.4rem 0;
  258. width: 9.2rem;
  259. }
  260. .color-shower{
  261. width: 0.4rem;
  262. height: 0.4rem;
  263. border-radius: 0.2rem;
  264. float: left;
  265. margin-right: 0.6rem;
  266. margin-top: 0.1rem;
  267. }
  268. .color-shower.active{
  269. width: 0.6rem;
  270. height: 0.6rem;
  271. border-radius: 0.3rem;
  272. margin-top: 0;
  273. }
  274. .canvas-color{
  275. margin-top: 0.25rem;
  276. float: left;
  277. width: 50%;
  278. }
  279. .canvas-control{
  280. float: right;
  281. width: 50%;
  282. text-align: right;
  283. }
  284. #canvas{
  285. width: 100%;
  286. /*width: 100%;*/
  287. height: 11.1rem;
  288. background-color: white;
  289. border-radius: 0.1rem;
  290. }
  291. .action-button{
  292. width: 1.1rem;
  293. height: 1.1rem;
  294. border: none;
  295. border-radius: 100%;
  296. background-color: #60c0ff;
  297. color: white;
  298. font-size: 0.4rem;
  299. }
  300. .go-prev{
  301. margin-right: 0.7rem;
  302. }
  303. </style>
  304. <!--<template>-->
  305. <!--<multi-color-background top-height="2.7">-->
  306. <!--<h1 class="title">手绘签名</h1>-->
  307. <!--<div class="main" >-->
  308. <!--<canvas class="draw-area" id="draw-area">-->
  309. <!--</canvas>-->
  310. <!--</div>-->
  311. <!--</multi-color-background>-->
  312. <!--</template>-->
  313. <!--<script>-->
  314. <!--import Draw from '../components/drawing.js';-->
  315. <!--import MultiColorBackground from "../components/multiColorBackground";-->
  316. <!--export default {-->
  317. <!--name: "drawSign",-->
  318. <!--components: {MultiColorBackground},-->
  319. <!--mounted(){-->
  320. <!--let draw = new Draw('draw-area')-->
  321. <!--}-->
  322. <!--}-->
  323. <!--</script>-->
  324. <!--<style scoped>-->
  325. <!--.title{-->
  326. <!--color:white;-->
  327. <!--font-size: 0.5rem;-->
  328. <!--margin-top: 0.6rem;-->
  329. <!--}-->
  330. <!--.main .input-container{-->
  331. <!--background-color: white;-->
  332. <!--border: 1px white solid;-->
  333. <!--border-radius: 10px;-->
  334. <!--}-->
  335. <!--.main{-->
  336. <!--margin: 0.4rem 0.4rem 0;-->
  337. <!--}-->
  338. <!--.draw-area{-->
  339. <!--width: 100%;-->
  340. <!--height: 11.1rem;-->
  341. <!--background-color: white;-->
  342. <!--border-radius: 0.1rem;-->
  343. <!--}-->
  344. <!--</style>-->