index.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. //第一版是用来计算 上传图片的宽高和父容器宽高,计算后的一个canvas宽高
  2. //后面改成了 正方形,估计算方式失效,本文件保留,
  3. const viewMixins = {
  4. data() {
  5. return {
  6. view: {
  7. width: 500,
  8. height: 500,
  9. aspect: 1 // 宽高比 >1 横屏 ===1 正方形 小于1 竖屏
  10. },
  11. canvas: {
  12. width: 500,
  13. height: 500
  14. },
  15. viewStatus: false,
  16. minimap: null,
  17. }
  18. },
  19. props:{
  20. canvasStyle:{
  21. type:Object,
  22. default:()=>{
  23. return {
  24. width:0,
  25. height:0,
  26. }
  27. }
  28. },
  29. maxZoom:{
  30. type:Number,
  31. default:5,
  32. },
  33. minZoom:{
  34. type:Number,
  35. default:0.1,
  36. },
  37. showZoom:{
  38. type:Boolean,
  39. default:true,
  40. },
  41. isEmpty:{
  42. type:Boolean,
  43. default:false,
  44. },
  45. resize:{
  46. type:Boolean,
  47. default:true,
  48. },
  49. //x y
  50. proportion:{
  51. type:[Object,Number],
  52. default:()=>{
  53. return {}
  54. }
  55. },
  56. //xy
  57. padding:{
  58. type:Object,
  59. default:()=>{
  60. return {
  61. x:160,
  62. y:0
  63. }
  64. }
  65. }
  66. },
  67. computed: {
  68. },
  69. watch: {
  70. proportion(){
  71. this.proportionResize();
  72. }
  73. },
  74. created() {
  75. },
  76. activated(){
  77. if(this.resize) window.addEventListener('resize', this.handleResize);
  78. },
  79. deactivated() {
  80. if(this.resize) window.removeEventListener('resize', this.handleResize)
  81. },
  82. mounted() {
  83. },
  84. methods: {
  85. //自适应
  86. handleResize(){
  87. let width = this.$refs.wrap?.clientWidth - this.padding.x;
  88. let height = this.$refs.wrap?.clientHeight - this.padding.y
  89. let min = Math.max(Math.min(width,height),100)
  90. let width_old = this.canvas.width
  91. this.canvas.width = min
  92. this.canvas.height = min
  93. let scaleRatio = (min/width_old).toFixed(4)
  94. let objects = this.fcanvas.getObjects();
  95. objects.forEach(function(object) {
  96. // 调整对象的位置
  97. object.left *= scaleRatio;
  98. object.top *= scaleRatio;
  99. // 调整对象的大小
  100. object.scaleX *= scaleRatio;
  101. object.scaleY *= scaleRatio;
  102. });
  103. // 调整画布的大小
  104. var newWidth = this.fcanvas.getWidth() * scaleRatio;
  105. var newHeight = this.fcanvas.getHeight() * scaleRatio;
  106. this.fcanvas.setDimensions({ width: newWidth, height: newHeight });
  107. this.fcanvas.requestRenderAll();
  108. },
  109. async proportionResize(){
  110. await this.setMax()
  111. this.fcanvas.setDimensions({ width: this.canvas.width , height: this.canvas.height });
  112. this.fcanvas.requestRenderAll();
  113. },
  114. async viewInit() {
  115. // 没有传值进来 默认基准宽度为基准算最大高度
  116. await this.setMax()
  117. if(this.resize) window.addEventListener('resize', this.handleResize);
  118. },
  119. // 获取容器的宽高最大值
  120. async setMax() {
  121. if(this.canvasStyle.width && this.canvasStyle.height){
  122. this.view.width = this.canvasStyle.width
  123. this.view.height = this.canvasStyle.height
  124. this.canvas.width = this.canvasStyle.width
  125. this.canvas.height = this.canvasStyle.height
  126. this.viewStatus = true;
  127. return;
  128. }
  129. this.view.width = this.$refs.wrap?.clientWidth
  130. this.view.height = this.$refs.wrap?.clientHeight
  131. let width = this.$refs.wrap?.clientWidth - this.padding.x;
  132. let height = this.$refs.wrap?.clientHeight - this.padding.y;
  133. let min = Math.min(width,height)
  134. let widthn = min
  135. let heightn = min
  136. if(this.proportion?.x > 1 && this.proportion?.y > 1){
  137. let size = this.proportion.x/this.proportion.y
  138. if(size>1){
  139. widthn = min
  140. heightn = min/this.proportion.x*this.proportion.y
  141. }else{
  142. widthn = min/this.proportion.y*this.proportion.x
  143. heightn = min
  144. }
  145. }
  146. if(this.proportion === 1 && this.image){
  147. const image = await this.$appfun.loadingImg(this.image)
  148. const imgObj = this.$appfun.getImageSize({width:image.width,height:image.height, MAXWIDTH:width,MAXHEIGHT:height})
  149. widthn = imgObj.width
  150. heightn = imgObj.height
  151. }
  152. this.canvas.width = widthn
  153. this.canvas.height = heightn
  154. this.viewStatus = true;
  155. },
  156. updateMiniMap() {
  157. var canvas = this.createCanvasEl();
  158. this.minimap.backgroundImage._element = canvas;
  159. this.minimap.requestRenderAll();
  160. },
  161. setZoom(type){
  162. //吸管模式下,不让放大缩小
  163. if(this.showStraw) return;
  164. let zoom = this.fcanvas.getZoom();
  165. switch (type){
  166. case 'in':
  167. zoom+=0.1
  168. break;
  169. case 'out':
  170. zoom-=0.1
  171. break;
  172. case 1:
  173. zoom=1
  174. break;
  175. }
  176. if (zoom > this.maxZoom) zoom = this.maxZoom;
  177. if (zoom < this.minZoom) zoom = this.minZoom;
  178. var myCenterCoordinates = fabric.util.transformPoint({
  179. x: parseInt(this.fcanvas.width / 2),
  180. y: parseInt(this.fcanvas.height / 2),
  181. }, fabric.util.invertTransform(this.fcanvas.viewportTransform));
  182. this.fcanvas.zoomToPoint(myCenterCoordinates, zoom);
  183. if(zoom = 1){
  184. this.fcanvas.viewportTransform[4] = 0
  185. this.fcanvas.viewportTransform[5] = 0
  186. }
  187. this.setCursor()
  188. },
  189. minimapInit(){
  190. var self = this
  191. this.fcanvas.on('mouse:wheel', function (e){
  192. this.zoom = (event.deltaY > 0 ? -0.1 : 0.1) + self.fcanvas.getZoom();
  193. this.zoom = Math.max(self.minZoom, this.zoom); //最小为原来的1/10
  194. this.zoom = Math.min(self.maxZoom, this.zoom); //最大是原来的10倍
  195. this.zoomPoint = new fabric.Point(e.pointer.x,e.pointer.y);
  196. self.fcanvas.zoomToPoint(this.zoomPoint, this.zoom);
  197. self.setCursor()
  198. });
  199. this.fcanvas.on('mouse:down', function(opt) {
  200. //吸管模式下,不让放大缩小
  201. if(self.showStraw) return;
  202. var evt = opt.e;
  203. if (evt.altKey === true || self.action === 'drag') {
  204. this.isDragging = true;
  205. this.selection = false;
  206. this.lastPosX = evt.clientX;
  207. this.lastPosY = evt.clientY;
  208. }
  209. });
  210. this.fcanvas.on('mouse:move', function(opt) {
  211. if (this.isDragging) {
  212. var e = opt.e;
  213. var vpt = this.viewportTransform;
  214. vpt[4] += e.clientX - this.lastPosX;
  215. vpt[5] += e.clientY - this.lastPosY;
  216. this.requestRenderAll();
  217. this.lastPosX = e.clientX;
  218. this.lastPosY = e.clientY;
  219. }
  220. });
  221. this.fcanvas.on('mouse:up', function(opt) {
  222. this.isDragging = false;
  223. this.selection = true;
  224. });
  225. },
  226. updateMiniMapVP() {
  227. var designSize = { width: this.canvas.width, height: this.canvas.height };
  228. var rect = this.minimap.getObjects()[0];
  229. var designRatio = fabric.util.findScaleToFit(designSize, this.fcanvas);
  230. var totalRatio = fabric.util.findScaleToFit(designSize, this.minimap);
  231. var finalRatio = designRatio / this.fcanvas.getZoom();
  232. rect.scaleX = finalRatio;
  233. rect.scaleY = finalRatio;
  234. rect.top = this.minimap.backgroundImage.top - this.fcanvas.viewportTransform[5] * totalRatio / this.fcanvas.getZoom();
  235. rect.left = this.minimap.backgroundImage.left - this.fcanvas.viewportTransform[4] * totalRatio / this.fcanvas.getZoom();
  236. this.minimap.requestRenderAll();
  237. },
  238. createCanvasEl() {
  239. var designSize = { width: this.canvas.width, height: this.canvas.height };
  240. var originalVPT = this.fcanvas.viewportTransform;
  241. // zoom to fit the design in the display canvas
  242. var designRatio = fabric.util.findScaleToFit(designSize, this.fcanvas);
  243. // zoom to fit the display the design in the minimap.
  244. var minimapRatio = fabric.util.findScaleToFit(this.fcanvas, this.minimap);
  245. var scaling = this.minimap.getRetinaScaling();
  246. var finalWidth = designSize.width * designRatio;
  247. var finalHeight = designSize.height * designRatio;
  248. this.fcanvas.viewportTransform = [
  249. designRatio, 0, 0, designRatio,
  250. (this.fcanvas.getWidth() - finalWidth) / 2,
  251. (this.fcanvas.getHeight() - finalHeight) / 2
  252. ];
  253. var canvas = this.fcanvas.toCanvasElement(minimapRatio * scaling);
  254. this.fcanvas.viewportTransform = originalVPT;
  255. return canvas;
  256. },
  257. initMinimap() {
  258. var canvas = this.createCanvasEl();
  259. var backgroundImage = new fabric.Image(canvas);
  260. backgroundImage.scaleX = 1 / this.fcanvas.getRetinaScaling();
  261. backgroundImage.scaleY = 1 / this.fcanvas.getRetinaScaling();
  262. this.minimap.centerObject(backgroundImage);
  263. this.minimap.backgroundColor = 'white';
  264. this.minimap.backgroundImage = backgroundImage;
  265. this.minimap.requestRenderAll();
  266. var minimapView = new fabric.Rect({
  267. top: backgroundImage.top,
  268. left: backgroundImage.left,
  269. width: backgroundImage.width / this.fcanvas.getRetinaScaling(),
  270. height: backgroundImage.height/ this.fcanvas.getRetinaScaling(),
  271. fill: 'rgba(0, 0, 255, 0.3)',
  272. cornerSize: 6,
  273. transparentCorners: false,
  274. cornerColor: 'blue',
  275. strokeWidth: 0,
  276. });
  277. minimapView.controls = {
  278. br: fabric.Object.prototype.controls.br,
  279. };
  280. this.minimap.add(minimapView);
  281. }
  282. }
  283. }
  284. export default viewMixins