国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務(wù)器之家 - 編程語言 - JavaScript - js教程 - fabric.js實(shí)現(xiàn)diy明信片功能

fabric.js實(shí)現(xiàn)diy明信片功能

2022-02-19 17:38C491114088 js教程

這篇文章主要為大家詳細(xì)介紹了fabric.js實(shí)現(xiàn)diy明信片功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了fabricjs實(shí)現(xiàn)diy明信片功能的具體代碼,供大家參考,具體內(nèi)容如下

前言

要求需要添加,拷貝,刪除,雙指放大縮小。

提示:以下是本篇文章正文內(nèi)容,下面案例可供參考

一、fabric.js是一個(gè)很好用的 canvas 操作插件

示例:pandas 是基于NumPy 的一種工具,該工具是為了解決數(shù)據(jù)分析任務(wù)而創(chuàng)建的。

二、代碼示例

代碼如下(示例):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
<!DOCTYPE html>
<html lang="en">
<head>
<title>diy</title>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
<meta http-equiv="Access-Control-Allow-Origin" content="*" />
<meta http-equiv="Expires" content="-1">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Pragma" content="no-cache">
<script src="./js/jquery-3.4.1.min.js"></script>
<script src="./js/fabric.js"></script>
<script src="./js/customiseControls.min.js"></script>
</head>
<style>
  body{
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font-weight: normal;
    vertical-align: baseline;   
  
  .end{
    position: fixed;
    top: 0;
    right: 0;
    width: 50px;
    height: 20px;
    background-color: #000000;
    color: #ffffff;
    font-size: 12px;
    line-height: 20px;
    z-index: 9999;
  }
  .canvasimg{
    position: fixed;
    top: 0;
    left: 0;
    width: 50px;
    height: 20px;
    background-color: #000000;
    color: #ffffff;
    font-size: 12px;
    line-height: 20px;
    z-index: 9999;
  }
  .canvasimg input{
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
  }
  #inline-btn{
    position: fixed;
    opacity: 0;
    z-index: 999;
  }
  #addinline-btn{
    opacity: 0;
    position: fixed;
    z-index: 999;
  
  .canvassrc{
    position: fixed;
    top: 0;
    right: 0;
    width: 100%;
    height: 100%;
    z-index: 9999;
  }
</style>
<body>
  <div class="canvasimg"><input type="file" name="" id="canvasimg" class="canvasimgadd" type="file" accept="image/*" onchange="selectFileImage(this);" >添加圖片</div>
  <div class="end" onclick="linkcanvas()">生成圖片</div>
  <button id="inline-btn" onclick="canvasonclick()">刪除圖片按鈕</button>
  <button id="addinline-btn" onclick="copy()">復(fù)制圖片按鈕</button>
  <canvas id="c"></canvas>
</body>
</html>
<script>
  //參考鏈接
  //文末查看比較詳細(xì)的API中文解釋
  //http://fabricjs.com/ fabric.js官網(wǎng)
 
  //diy功能需要有復(fù)制功能 刪除功能 放大縮小移動(dòng)旋轉(zhuǎn)
 
  //添加新圖片
  function selectFileImage(fileObj){
    var file = fileObj.files['0'];
    var reader = new FileReader();
    reader.readAsDataURL(file)
    reader.onload = function (e){
      fabric.Image.fromURL(e.target.result, function (img) {
        img.scale(1).set({
          left: webwidth - (webwidth / 2),//圖片左右居中
          top: webheight - (webheight / 2), //圖片上下居中 ,屏幕高度-(圖片高度/2)的總值/2
          angle: 0, //角度為0
          originX: 'center',
          originY: 'center',
        });
        //圖片默認(rèn)寬度充滿屏幕一邊留白20 高度自適應(yīng)
        img.scaleToWidth(webwidth - 40)
        canvas.add(img).setActiveObject(img);
        //清除線條
        img.hasBorders = false;
        //自定義圖片功能按鈕 , 隱藏多余功能按鈕,只保留4個(gè)角的按鈕
        canvas.forEachObject(function (em) {
          em['setControlVisible']('mtr', false);
          em['setControlVisible']('mt', false);
          em['setControlVisible']('ml', false);
          em['setControlVisible']('mb', false);
          em['setControlVisible']('mr', false);
          em['setControlVisible']('mt', false);
        })
      });
    }
  }
 
 
  // 刪除按鈕
  var btn = document.getElementById('inline-btn')
  // 添加按鈕     
  var addbtn = document.getElementById('addinline-btn')
 
  // 獲取屏幕高寬度
  var webwidth = $(window).width()
  var webheight = $(window).height()
  //創(chuàng)建畫板
  var canvas = new fabric.Canvas('c');
  //canvas默認(rèn)充滿屏幕
    canvas.setWidth(webwidth)
    canvas.setHeight(webheight)
    //導(dǎo)入圖片
    fabric.Image.fromURL('./imgs/2.jpg', function (img) {
      img.scale(1).set({
        left: webwidth - (webwidth/2),//圖片左右居中
        top: webheight-(webheight/2), //圖片上下居中 ,屏幕高度-(圖片高度/2)的總值/2
        angle: 0, //角度為0
        originX: 'center',
        originY: 'center',
      });
      //圖片默認(rèn)寬度充滿屏幕一邊留白20 高度自適應(yīng)
      img.scaleToWidth(webwidth-40)
      canvas.add(img).setActiveObject(img);
      //清除線條
      img.hasBorders = false;
      //自定義圖片功能按鈕 , 隱藏多余功能按鈕,只保留4個(gè)角的按鈕
      canvas.forEachObject(function(em){
        em['setControlVisible']('mtr', false);
        em['setControlVisible']('mt', false);
        em['setControlVisible']('ml', false);
        em['setControlVisible']('mb', false);
        em['setControlVisible']('mr', false);
        em['setControlVisible']('mt', false);
      })
    });
 
    //取消多選
    canvas.selection = false;
    //新建圖層不出現(xiàn)在頂層  
    canvas.preserveObjectStacking = true;   
    //注:要自定義修改按鈕功能需要引入fabric的另一個(gè)叫customiseControls的JS插件 否則無法操作
    //全局修改4個(gè)按鈕的功能
    fabric.Canvas.prototype.customiseControls({
      bl: {
        action: 'rotate' //添加圖片旋轉(zhuǎn)功能
      },
      // only is hasRotatingPoint is not set to false
    }, function () {
      canvas.renderAll();
    }); 
 
    //因?yàn)槟J(rèn)的按鈕樣式不是我們想要的 所以需要自定義一些icon在上面
    fabric.Object.prototype.customiseCornerIcons({
      tl: {
        icon: './img/+1@2x.png', //圖片路徑
        cornerSize: 70,   //按鈕點(diǎn)擊范圍 相當(dāng)于css的padding屬性
        settings: {
          cornerSize: 25 //icon大小
        },   
      },
      tr: {
        icon: './img/X@2x.png',
        cornerSize: 70, 
        settings: {
          cornerSize: 25
        },        
      },
      bl: {
        icon: './img/xuanzhuan@2x.png',
        cornerSize: 70, 
        settings: {
          cornerSize: 25
        },        
      },
      br: {
        icon: './img/fangda@2x.png',
        cornerSize: 70,
        settings: {
          cornerSize: 25
        },        
      },
    }, function () {
      canvas.renderAll();
    });
 
    //按鈕跟隨圖片定位
    function positionBtn(obj) {
      //獲取當(dāng)前選中圖片單位參數(shù)
      var absCoords = canvas.getAbsoluteCoords(obj);
      btn.style.width = '30px';
      btn.style.height = '30px';
      btn.style.opacity = '0';
      btn.style.left = (absCoords.right - 30 / 2) + 'px';
      btn.style.top = (absCoords.top - 30 / 2) + 'px';
 
      addbtn.style.width = '30px';
      addbtn.style.height = '30px';
      addbtn.style.opacity = '0';
      addbtn.style.left = (absCoords.left - 30 / 2) + 'px';
      addbtn.style.top = (absCoords.leftTop - 30 / 2) + 'px';
    }
 
    fabric.Canvas.prototype.getAbsoluteCoords = function (object) {
      return {
        right: object.aCoords.tr.x + this._offset.left,
        top:object.aCoords.tr.y + this._offset.top,
        left: object.aCoords.tl.x + this._offset.left,
        leftTop: object.aCoords.tl.y + this._offset.top,
      };
    }
 
 
    //刪除當(dāng)前選中圖片
    function canvasonclick(){
      var t = canvas.getActiveObject()
      canvas.remove(t);
    }
 
    //拷貝當(dāng)前選中圖片
    function copy(){
      var _self = this;
      canvas.getActiveObject().clone(function (cloned) {
        _self.paste(cloned);
        canvas.discardActiveObject().renderAll()
      })
    }   
    function paste(_clipboard){
      console.log(_clipboard)
      var t = canvas.getActiveObject();
      // 再次克隆,這樣你就可以復(fù)制多個(gè)副本。
      t.clone(function (clonedObj) {
        canvas.discardActiveObject();
        clonedObj.set({
          left: clonedObj.left + 20,
          top: clonedObj.top + 20,
          evented: true,
          hasBorders:false
        });
        if (clonedObj.type === 'activeSelection') {
          // 活動(dòng)選擇需要對畫布的引用。
          clonedObj.canvas = canvas;
          clonedObj.forEachObject(function (obj) {
            canvas.add(obj); 
            canvas.forEachObject(function (em) {
              em['setControlVisible']('mtr', false);
              em['setControlVisible']('mt', false);
              em['setControlVisible']('ml', false);
              em['setControlVisible']('mb', false);
              em['setControlVisible']('mr', false);
              em['setControlVisible']('mt', false);
            })                     
          });
          // 解決不可選擇的問題
          clonedObj.setCoords();
        } else {
          canvas.add(clonedObj);
          canvas.forEachObject(function (em) {
            em['setControlVisible']('mtr', false);
            em['setControlVisible']('mt', false);
            em['setControlVisible']('ml', false);
            em['setControlVisible']('mb', false);
            em['setControlVisible']('mr', false);
            em['setControlVisible']('mt', false);
          })         
        }
      });    
    }
 
    var store = {}
    //計(jì)算平均值
    var getDistance = function (start, stop) {
      return Math.hypot(stop.x - start.x, stop.y - start.y);
    };   
 
    //監(jiān)聽positionBtn事件 鼠標(biāo)以上點(diǎn)擊圖片時(shí)移動(dòng)時(shí)觸發(fā)我們自定義的復(fù)制按鈕和刪除按鈕跟隨圖片定位以及雙指放大縮小功能
    canvas.on('mouse:down',function(options){
      //判斷是否點(diǎn)擊到了圖片單位
      if(options.target){
        //運(yùn)行事件
        positionBtn(options.target);
 
        //雙指放大縮小
        store.pageX = options.e.changedTouches[0].clientX
        store.pageY = options.e.changedTouches[0].clientY
        if (options.e.changedTouches.length == 2) {
          store.pageY2 = options.e.changedTouches[1].clientY
          store.pageX2 = options.e.changedTouches[1].clientX
        }
        store.originScale = options.target.scaleX || 0.5;
        store.originleft = options.target.left;
        store.origintop = options.target.top;
      }
    });               
    canvas.on('mouse:move',function(options){
      if(options.target){
        positionBtn(options.target);
        if (options.e.changedTouches.length == 2) {
          if (!store.pageX2) {
            store.pageX2 = options.e.changedTouches[1].clientX
          }
          if (!store.pageY2) {
            store.pageY2 = options.e.changedTouches[1].clientY
          }
          var zoom = getDistance({
            x: options.e.changedTouches[0].clientX,
            y: options.e.changedTouches[0].clientY
          }, {
            x: options.e.changedTouches[1].clientX,
            y: options.e.changedTouches[1].clientY
          }) /
            getDistance({
              x: store.pageX,
              y: store.pageY
            }, {
              x: store.pageX2,
              y: store.pageY2
            });
          var newScale = store.originScale * zoom;
          if (newScale > 3) {
            newScale = 3;
          }
          options.target.scaleX = newScale;
          options.target.scaleY = newScale;
          canvas.renderAll();
        }         
      }
    }); 
    canvas.on('mouse:up',function(options){
      if(options.target){
        positionBtn(options.target);  
        store.pageY = 0
        store.pageX = 0
        store.pageY2 = 0
        store.pageX2 = 0   
        store.originScale = options.target.scaleX
        store.originleft = options.target.left 
        store.origintop = options.target.top     
      }
    });
 
    //生成明信片
    function linkcanvas(){
      let xheight = $('#c').height()
      let xwidth = $('#c').width()
      canvas.setBackgroundColor('rgba(255, 255, 255, 1)', canvas.renderAll.bind(canvas));
      var exportedArt = this.canvas.toDataURL({
        format: "jpeg",
        quality: 1.0,
        multiplier: 2.4,
        left: 0,
        top: 0,
        width: xwidth,
        height: xheight,
      });
      $('body').append(`<img class="canvassrc" src="${exportedArt}"/>`)
    }
 
</script>

實(shí)現(xiàn)效果

fabric.js實(shí)現(xiàn)diy明信片功能

總結(jié)

具體一些方法知識點(diǎn)建議大家可以去參考一下這篇文章

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/C491114088/article/details/114871216

延伸 · 閱讀

精彩推薦
  • js教程javascript實(shí)現(xiàn)隨機(jī)抽獎(jiǎng)功能

    javascript實(shí)現(xiàn)隨機(jī)抽獎(jiǎng)功能

    這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)隨機(jī)抽獎(jiǎng)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下...

    彴兗7152021-12-23
  • js教程ES6字符串的擴(kuò)展實(shí)例

    ES6字符串的擴(kuò)展實(shí)例

    這篇文章主要介紹了ES6字符串的擴(kuò)展實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小...

    知否5582021-12-16
  • js教程如何在JavaScript中使用localStorage詳情

    如何在JavaScript中使用localStorage詳情

    這篇文章主要介紹了如何在JavaScript中使用localStorage,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下...

    碼農(nóng)翻譯站6242022-01-17
  • js教程微信小程序?qū)崿F(xiàn)走馬燈效果實(shí)例

    微信小程序?qū)崿F(xiàn)走馬燈效果實(shí)例

    這篇文章主要給大家介紹了關(guān)于微信小程序?qū)崿F(xiàn)走馬燈效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)...

    程序猿tx10492022-02-19
  • js教程js面向?qū)ο蠓庋b級聯(lián)下拉菜單列表的實(shí)現(xiàn)步驟

    js面向?qū)ο蠓庋b級聯(lián)下拉菜單列表的實(shí)現(xiàn)步驟

    這篇文章主要介紹了js面向?qū)ο蠓庋b級聯(lián)下拉菜單列表的實(shí)現(xiàn)步驟,幫助大家更好的理解和使用JavaScript,感興趣的朋友可以了解下...

    蔣偉平8682022-01-19
  • js教程JS異步的執(zhí)行原理和回調(diào)詳解

    JS異步的執(zhí)行原理和回調(diào)詳解

    這篇文章主要給大家介紹了關(guān)于JS異步的執(zhí)行原理和回調(diào)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值...

    Zxinxxxx5802022-02-13
  • js教程js實(shí)現(xiàn)驗(yàn)證碼干擾(靜態(tài))

    js實(shí)現(xiàn)驗(yàn)證碼干擾(靜態(tài))

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)驗(yàn)證碼干擾,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下...

    lzh~5242022-01-22
  • js教程mapboxgl實(shí)現(xiàn)帶箭頭軌跡線的代碼

    mapboxgl實(shí)現(xiàn)帶箭頭軌跡線的代碼

    這篇文章主要介紹了mapboxgl實(shí)現(xiàn)帶箭頭軌跡線的代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下...

    GIS兵器庫9342021-12-27
主站蜘蛛池模板: 高清久久| 日韩视频在线观看 | 国产午夜在线 | 色一色视频 | 久久精品国产欧美亚洲人人爽 | 欧美日韩精品一区二区三区四区 | 成人国产电影 | 日韩欧美一区二区三区免费观看 | 日韩免费在线观看视频 | 在线国产精品一区 | 一级片免费视频 | 亚洲一区在线观看视频 | 精品久久久久久久久福利 | 一区二区三区高清 | 久久精品片| 在线观看免费毛片视频 | 毛片免费在线视频 | 精品国产91久久 | 免费av电影网站 | 成人片在线播放 | 伊人网在线视频观看 | 日韩av高清 | 国产高清无密码一区二区三区 | 日韩精品影院 | 日本综合色| 色婷婷精品国产一区二区三区 | 中文字幕不卡在线观看 | 国产精品久久久99 | 亚洲特黄一级 | 欧美一区二区三区在线观看视频 | 日韩一区精品视频 | 一区二区免费看 | 午夜在线电影 | 久久精品亚洲精品 | 亚洲天堂av网 | 国产白浆在线观看 | 中文字幕亚洲一区二区三区 | 国产成人免费视频 | 久色成人| 干片网| 久久涩 |