公交车上荫蒂添的好舒服的电影-公用玩物(np双xing总受)-公用小荡货芊芊-公与妇仑乱hd-攻把受做哭边走边肉楼梯play-古装一级淫片a免费播放口

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

Fabric.js 簡(jiǎn)單介紹和使用

admin
2023年5月23日 16:3 本文熱度 2217

簡(jiǎn)介

Fabric.js是一個(gè)可以簡(jiǎn)化canvas程序編寫的庫(kù)。 Fabric.js為canvas提供所缺少的對(duì)象模型, svg parser, 交互和一整套其他不可或缺的工具。基于MIT協(xié)議開源,在github上有許多人貢獻(xiàn)代碼。

Why fabric?

canvas提供一個(gè)好的畫布能力, 但其api超級(jí)爛。如果你就想畫個(gè)簡(jiǎn)單圖形, 其實(shí)也可以, 不過做一些復(fù)雜的圖形繪制, 編寫一些復(fù)雜的效果,就不是那么好了。
fabric就是為此而開發(fā)。

用對(duì)象的方式去編寫代碼

舉個(gè)例子
傳統(tǒng)的畫正方形代碼

// reference canvas element (with id="c")

var canvasEl = document.getElementById('c');


// get 2d context to draw on (the "bitmap" mentioned earlier)

var ctx = canvasEl.getContext('2d');


// set fill color of context

ctx.fillStyle = 'red';


// create rectangle at a 100,100 point, with 20x20 dimensions

ctx.fillRect(100, 100, 20, 20);


使用fabric

// create a wrapper around native canvas element (with id="c")

var canvas = new fabric.Canvas('c');

 

// create a rectangle object

var rect = new fabric.Rect({

    left: 100,

    top: 100,

    fill: 'red',

    width: 20,

    height: 20

});

 

// "add" rectangle onto canvas

canvas.add(rect);

好的 其實(shí)并沒有什么差別 不過我們?cè)囍D(zhuǎn)一下角度

var canvasEl = document.getElementById('c');

var ctx = canvasEl.getContext('2d');

ctx.fillStyle = 'red';


ctx.translate(100, 100);

ctx.rotate(Math.PI / 180 * 45);

ctx.fillRect(-10, -10, 20, 20);


fabric

var canvas = new fabric.Canvas('c');


// create a rectangle with angle=45

var rect = new fabric.Rect({

  left: 100,

  top: 100,

  fill: 'red',

  width: 20,

  height: 20,

  angle: 45

});


canvas.add(rect);


如果我們想重新調(diào)整位置 怎么辦

var canvasEl = document.getElementById('c');


...

ctx.strokRect(100, 100, 20, 20);

...


// erase entire canvas area

ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);

ctx.fillRect(20, 50, 20, 20);


fabric

var canvas = new fabric.Canvas('c');

...

canvas.add(rect);

...


rect.set({ left: 20, top: 50 });

canvas.renderAll();


objects

  1. fabric.Circle

  2. fabric.Ellipse

  3. fabric.Line

  4. fabric.Polygon

  5. fabric.Polyline

  6. fabric.Rect

  7. fabric.Triangle

畫一個(gè)三角形 和一個(gè) 圓形

// create a wrapper around native canvas element (with id="c")

var canvas = new fabric.Canvas('c');


var circle = new fabric.Circle({

    radius: 20, fill: 'green', left: 100, top: 100

});

var triangle = new fabric.Triangle({

    width: 20, height: 30, fill: 'blue', left: 50, top: 50

});


canvas.add(circle, triangle);

Manipulating objects

可以簡(jiǎn)單的使用set來控制對(duì)象屬性
positioning — left, top;
dimension — width, height;
rendering — fill, opacity, stroke, strokeWidth;
scaling and rotation — scaleX, scaleY, angle;
and even those related to flipping — flipX, flipY.

rect.set('fill', 'red');

rect.set({ strokeWidth: 5, stroke: 'rgba(100,200,200,0.5)' });

rect.set('angle', 15).set('flipY', true);

有了set 其實(shí)也就有了get,對(duì)象可以創(chuàng)建時(shí)設(shè)置屬性,也可以先實(shí)例化再賦值。

var rect = new fabric.Rect({ width: 10, height: 20, fill: '#f55', opacity: 0.7 });


// or functionally identical


var rect = new fabric.Rect();

rect.set({ width: 10, height: 20, fill: '#f55', opacity: 0.7 });


另外這里的fabric.Rect是函數(shù),大家可以使用class繼承。

默認(rèn)值

var rect = new fabric.Rect(); // notice no options passed in


rect.getWidth(); // 0

rect.getHeight(); // 0


rect.getLeft(); // 0

rect.getTop(); // 0


rect.getFill(); // rgb(0,0,0)

rect.getStroke(); // null


rect.getOpacity(); // 1


Hierarchy and Inheritance

fabric.Object 是圖像基類

你可以自己擴(kuò)充方法

fabric.Object.prototype.getAngleInRadians = function() {

  return this.getAngle() / 180 * Math.PI;

};


var rect = new fabric.Rect({ angle: 45 });

rect.getAngleInRadians(); // 0.785...


var circle = new fabric.Circle({ angle: 30, radius: 10 });

circle.getAngleInRadians(); // 0.523...


circle instanceof fabric.Circle; // true

circle instanceof fabric.Object; // true


Canvas

fabric.Canvas 是canvas的wrapper

var canvas = new fabric.Canvas('c');

var rect = new fabric.Rect();


canvas.add(rect); // add object


canvas.item(0); // reference fabric.Rect added earlier (first object)

canvas.getObjects(); // get all objects on canvas (rect will be first and only)


canvas.remove(rect); // remove previously-added fabric.Rect


經(jīng)典的設(shè)計(jì) 有options 有對(duì)象方法

var canvas = new fabric.Canvas('c', {

  backgroundColor: 'rgb(100,100,200)',

  selectionColor: 'blue',

  selectionLineWidth: 2

  // ...

});


// or


var canvas = new fabric.Canvas('c');

canvas.setBackgroundImage(http://...');

canvas.onFpsupdate = function(){ /* ... */ };

// ...


Images

使用fabric.Image你可以輕松的加載一個(gè)圖片
html

<canvas id="c"></canvas>

<img src="my_image.png" id="my-image">


js

var canvas = new fabric.Canvas('c');

var imgElement = document.getElementById('my-image');

var imgInstance = new fabric.Image(imgElement, {

  left: 100,

  top: 100,

  angle: 30,

  opacity: 0.85

});

canvas.add(imgInstance);

當(dāng)然也可以通過url加載一張圖片到canvas

fabric.Image.fromURL('my_image.png', function(oImg) {

  canvas.add(oImg);

});


可以對(duì)加載的圖片進(jìn)行預(yù)處理

fabric.Image.fromURL('my_image.png', function(oImg) {

  // scale image down, and flip it, before adding it onto canvas

  oImg.scale(0.5).setFlipX(true);

  canvas.add(oImg);

});


Path and PathGroup

我們已經(jīng)看了簡(jiǎn)單的形狀,然后圖像。更復(fù)雜、豐富的形狀和內(nèi)容呢?
路徑包括一系列的命令,這基本上模仿一個(gè)筆從一個(gè)點(diǎn)到另一個(gè)。在“移動(dòng)”,“線”,“曲線”,或“弧”等命令的幫助下,路徑可以形成令人難以置信的復(fù)雜形狀。同組的路徑(路徑組的幫助),開放更多的可能性。
類似于svg的path

var canvas = new fabric.Canvas('c');

var path = new fabric.Path('M 0 0 L 200 100 L 170 200 z');

path.set({ left: 120, top: 120 });

canvas.add(path);

“M” 代表 “move” 命令, 告訴筆到 0, 0 點(diǎn).
“L” 代表 “l(fā)ine” 畫一條0, 0 到 200, 100 的線.
another “L” creates a line to 170, 200.
z” tells forces drawing pen to close current path and finalize the shape.

...

var path = new fabric.Path('M 0 0 L 300 100 L 200 300 z');

...

path.set({ fill: 'red', stroke: 'green', opacity: 0.5 });

canvas.add(path);


path也可以設(shè)置canvas屬性

當(dāng)然,太困然了,所以你可以使用 fabric.loadSVGfromString or fabric.loadSVGfromURL 方法。

Afterword

看些demo吧。


上面我們學(xué)習(xí)了基礎(chǔ)用法,現(xiàn)在我們開始一些好玩的。

Animation

我們先回顧設(shè)置一下正方形角度方法

rect.set('angle', 45);

這是沒有動(dòng)畫的

Fabric object都有animate方法

rect.animate('angle', 45, {
  onChange: canvas.renderAll.bind(canvas)
});

那么正方形會(huì)從0到45有一個(gè)動(dòng)畫過度

從左到右進(jìn)行變動(dòng)

rect.animate('left', '+=100', { onChange: canvas.renderAll.bind(canvas) });

逆時(shí)針轉(zhuǎn)5度

rect.animate('angle', '-=5', { onChange: canvas.renderAll.bind(canvas) });

當(dāng)然animate還支持這些方法

  1. from: Allows to specify starting value of animatable property (if we don't want 2. current value to be used).

  2. duration: Defaults to 500 (ms). Can be used to change duration of an animation.

  3. onComplete: Callback that's invoked at the end of the animation.

  4. easing: Easing function.

rect.animate('left', '+=100', {
    onChange: canvas.renderAll.bind(canvas),
    duration: 3000,
    easing: fabric.util.ease.easeOutBounce
});

Image filters

圖片可以使用filter效果

fabric.Image.fromURL('pug.jpg', function(img) {
  // add filter
  img.filters.push(new fabric.Image.filters.Grayscale());
  // apply filters and re-render canvas when done
  img.applyFilters(canvas.renderAll.bind(canvas));
  // add image onto canvas
  canvas.add(img);
});

filter一次可以使用多個(gè)效果

當(dāng)然 你也可以自己定義filter

fabric.Image.filters.Redify = fabric.util.createClass({
  type: 'Redify',
  applyTo: function(canvasEl) {    var context = canvasEl.getContext('2d'),
        imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
        data = imageData.data;
        for (var i = 0, len = data.length; i < len; i += 4) {
              data[i + 1] = 0;
              data[i + 2] = 0;
    }
    context.putImageData(imageData, 0, 0);
  }
});
fabric.Image.filters.Redify.fromObject = function(object) {
  return new fabric.Image.filters.Redify(object);
};

Colors

fabric 支持 hex rgb rgba顏色

new fabric.Color('#f55');
new fabric.Color('#123123');
new fabric.Color('356735');
new fabric.Color('rgb(100,0,100)');
new fabric.Color('rgba(10, 20, 30, 0.5)');

并且支持相互轉(zhuǎn)換

new fabric.Color('#f55').toRgb(); // "rgb(255,85,85)"
new fabric.Color('rgb(100,100,100)').toHex(); // "646464"
new fabric.Color('fff').toHex(); // "FFFFFF"

兩種顏色可以疊加 并且你可以使用一些特定效果

var redish = new fabric.Color('#f55');
var greenish = new fabric.Color('#5f5');
redish.overlayWith(greenish).toHex(); // "AAAA55"
redish.toGrayscale().toHex(); // "A1A1A1"

Gradients

可以使用漸變色

var circle = new fabric.Circle({  left: 100,  top: 100,  radius: 50});
circle.setGradient('fill', {
  x1: 0,  y1: -circle.height / 2,  x2: 0,  y2: circle.height / 2,  colorStops: {
    0: '#000',    1: '#fff'
  }
});

首先確定兩個(gè)點(diǎn) 在其距離中以百分比定位顏色

circle.setGradient('fill', {
  x1: -circle.width / 2,
  y1: 0,  x2: circle.width / 2,  y2: 0,  colorStops: {
      0: "red",    0.2: "orange",    0.4: "yellow",    0.6: "green",    0.8: "blue",    1: "purple"
  }
});

Text

  1. Multiline support. Native text methods unfortunately simply ignore new lines.

  2. Text alignment. Left, center, right. Useful when working with multiline text.

  3. Text background. Background also respects text alignment.

  4. Text decoration. Underline, overline, strike-through.

  5. Line height. Useful when working with multiline text.

如何添加文字

var text = new fabric.Text('hello world', { left: 100, top: 100 });
canvas.add(text);

fontFamily

var comicSansText = new fabric.Text("I'm in Comic Sans", {fontFamily: 'Comic Sans'});

fontSize

var text40 = new fabric.Text("I'm at fontSize 40", {fontSize: 40});
var text20 = new fabric.Text("I'm at fontSize 20", {fontSize: 20});

fontWeight

var normalText = new fabric.Text("I'm a normal text", {fontWeight: 'normal'});
var boldText = new fabric.Text("I'm at bold text", {fontWeight: 'bold'});

textDecoration

var underlineText = new fabric.Text("I'm an underlined text", {textDecoration: 'underline'});
var strokeThroughText = new fabric.Text("I'm a stroke-through text", {textDecoration: 'line-through'});
var overlineText = new fabric.Text("I'm an overline text", {textDecoration: 'overline'});

shadow

var shadowText1 = new fabric.Text("I'm a text with shadow", {  shadow: 'rgba(0,0,0,0.3) 5px 5px 5px'});
var shadowText2 = new fabric.Text("And another shadow", {  shadow: 'rgba(0,0,0,0.2) 0 0 5px'});
var shadowText3 = new fabric.Text("Lorem ipsum dolor sit", {  shadow: 'green -5px -5px 3px'});

fontStyle

var italicText = new fabric.Text("A very fancy italic text", {  fontStyle: 'italic',  fontFamily: 'Delicious'});
var anotherItalicText = new fabric.Text("another italic text", {  fontStyle: 'italic',  fontFamily: 'Hoefler Text'});

stroke & strokeWidth

var textWithStroke = new fabric.Text("Text with a stroke", {  stroke: '#ff1318',  strokeWidth: 1});
var loremIpsumDolor = new fabric.Text("Lorem ipsum dolor", {  fontFamily: 'Impact',  stroke: '#c3bfbf',  strokeWidth: 3});

textAlign

var text = 'this is\na multiline\ntext\naligned right!';
var alignedRightText = new fabric.Text(text, {  textAlign: 'right'});

lineHeight

var lineHeight3 = new fabric.Text('Lorem ipsum ...', {  lineHeight: 3});
var lineHeight1 = new fabric.Text('Lorem ipsum ...', {  lineHeight: 1});

textBackgroundColor

var text = 'this is\na multiline\ntext\nwith\ncustom lineheight\n&background';
var textWithBackground = new fabric.Text(text, {  textBackgroundColor: 'rgb(0,200,0)'});

Events

怎么可以沒有事件呢

事件以on off使用 canvas 可以捕捉事件

mouseevent
"mouse:down", "mouse:move", and "mouse:up".

renderevent
"after:render".

selectionevent
"before:selection:cleared", "selection:created", "selection:cleared".

objectevent
object ones: "object:modified", "object:selected", "object:moving", "object:scaling", "object:rotating", "object:added", and "object:removed"

var canvas = new fabric.Canvas('...');
canvas.on('mouse:down', function(options) {
    console.log(options.e.clientX, options.e.clientY);
});

同樣這些事件也可以用任何fabric對(duì)象監(jiān)聽

var rect = new fabric.Rect({ width: 100, height: 50, fill: 'green' });
rect.on('selected', function() {
 console.log('selected a rectangle');
});
var circle = new fabric.Circle({ radius: 75, fill: 'blue' });
circle.on('selected', function() {
 console.log('selected a circle');
});


上面我們學(xué)習(xí)了基礎(chǔ)和高級(jí)特性,現(xiàn)在介紹更神奇的東西。

Groups

話說這個(gè)功能我最喜歡,組成群組可以統(tǒng)一修改其中所有組件屬性,如何定義:

var circle = new fabric.Circle({
  radius: 100,
  fill: '#eef',
  scaleY: 0.5,
  originX: 'center',
  originY: 'center'
});
var text = new fabric.Text('hello world', {
  fontSize: 30,
  originX: 'center',
  originY: 'center'
});
var group = new fabric.Group([ circle, text ], {
  left: 150,
  top: 100,
  angle: -10
});
canvas.add(group);

圖片描述

現(xiàn)在我們就可以對(duì)其中的對(duì)象集修改

group.item(0).setFill('red');
group.item(1).set({
  text: 'trololo',
  fill: 'white'
});

圖片描述

group中的元素相對(duì)于group定位

圖片描述

但是由于要確保之前得到卻切位置 所以要異步

fabric.Image.fromURL('/assets/pug.jpg', function(img) {
  var img1 = img.scale(0.1).set({ left: 100, top: 100 });
  fabric.Image.fromURL('/assets/pug.jpg', function(img) {
    var img2 = img.scale(0.1).set({ left: 175, top: 175 });
    fabric.Image.fromURL('/assets/pug.jpg', function(img) {
      var img3 = img.scale(0.1).set({ left: 250, top: 250 });
      canvas.add(new fabric.Group([ img1, img2, img3], { left: 200, top: 200 }))
    });
  });
});

group 可以動(dòng)態(tài)添加

group.add(new fabric.Rect({
  ...
  originX: 'center',
  originY: 'center'
}));

添加并修改group

group.addWithupdate(new fabric.Rect({
  ...
  left: group.getLeft(),
  top: group.getTop(),
  originX: 'center',
  originY: 'center'
}));

當(dāng)然 你可以使用canvas上已有的進(jìn)行克隆 組合

// create a group with copies of existing (2) objects
var group = new fabric.Group([
  canvas.item(0).clone(),
  canvas.item(1).clone()
]);
// remove all objects and re-render
canvas.clear().renderAll();
// add group onto canvas
canvas.add(group);

Serialization

序列化是為了相互傳輸

toObject, toJSON

canvas 實(shí)現(xiàn)了toJSON接口 可以被序列化

var canvas = new fabric.Canvas('c');
JSON.stringify(canvas); // '{"objects":[],"background":"rgba(0, 0, 0, 0)"}'

canvas 可以隨時(shí)被修改 json數(shù)據(jù)會(huì)被修改

canvas.backgroundColor = 'red';
JSON.stringify(canvas); // '{"objects":[],"background":"red"}'

添加新對(duì)象 也會(huì)改變json數(shù)據(jù)

canvas.add(new fabric.Rect({  left: 50,  top: 50,  height: 20,  width: 20,  fill: 'green'}));
console.log(JSON.stringify(canvas));
'{"objects":[{"type":"rect","left":50,"top":50,"width":20,"height":20,"fill":"green","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0}],"background":"rgba(0, 0, 0, 0)"}'

再添加一個(gè)

canvas.add(new fabric.Circle({  left: 100,  top: 100,  radius: 50,  fill: 'red'}));
console.log(JSON.stringify(canvas));
'{"objects":[{"type":"rect","left":50,"top":50,"width":20,"height":20,"fill":"green","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0},{"type":"circle","left":100,"top":100,"width":100,"height":100,"fill":"red","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"radius":50}],"background":"rgba(0, 0, 0, 0)"}'
toObject

可以轉(zhuǎn)化成js object對(duì)象

{ "background" : "rgba(0, 0, 0, 0)",
  "objects" : [
    {
      "angle" : 0,
      "fill" : "green",
      "flipX" : false,
      "flipY" : false,
      "hasBorders" : true,
      "hasControls" : true,
      "hasRotatingPoint" : false,
      "height" : 20,
      "left" : 50,
      "opacity" : 1,
      "overlayFill" : null,
      "perPixelTargetFind" : false,
      "scaleX" : 1,
      "scaleY" : 1,
      "selectable" : true,
      "stroke" : null,
      "strokeDashArray" : null,
      "strokeWidth" : 1,
      "top" : 50,
      "transparentCorners" : true,
      "type" : "rect",
      "width" : 20
    }
  ]}

每個(gè)fabric對(duì)象有toObject方法 這和toJSON 也有關(guān) 可以自定義

var rect = new fabric.Rect();
rect.toObject = function() {
  return { name: 'trololo' };
};
canvas.add(rect);
console.log(JSON.stringify(canvas));
'{"objects":[{"name":"trololo"}],"background":"rgba(0, 0, 0, 0)"}'

當(dāng)然我們可以保留原有的數(shù)據(jù) 新增數(shù)據(jù)

var rect = new fabric.Rect();rect.toObject = (function(toObject) {
  return function() {
    return fabric.util.object.extend(toObject.call(this), {
      name: this.name
    });
  };
})(rect.toObject);
canvas.add(rect);rect.name = 'trololo';
console.log(JSON.stringify(canvas));
'{"objects":[{"type":"rect","left":0,"top":0,"width":0,"height":0,"fill":"rgb(0,0,0)","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0,"name":"trololo"}],"background":"rgba(0, 0, 0, 0)"}'
toSvg

怎么能不支持轉(zhuǎn)成svg呢

canvas.add(new fabric.Rect({ left: 50,  top: 50,  height: 20,  width: 20,  fill: 'green'}));
console.log(canvas.toSVG());
'<?xml version="1.0" standalone="no" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="800" height="700" xml:space="preserve"><desc>created with Fabric.js 0.9.21</desc><rect x="-10" y="-10" rx="0" ry="0" width="20" height="20" style="stroke: none; stroke-width: 1; stroke-dasharray: ; fill: green; opacity: 1;" transform="translate(50 50)" /></svg>'

Deserialization, SVG parser

fabric.Canvas#loadfromJSON
fabric.Canvas#loadfromDatalessJSON
fabric.loadSVGfromURL
fabric.loadSVGfromString

var canvas = new fabric.Canvas();
canvas.loadfromJSON('{"objects":[{"type":"rect","left":50,"top":50,"width":20,"height":20,"fill":"green","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0},{"type":"circle","left":100,"top":100,"width":100,"height":100,"fill":"red","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"radius":50}],"background":"rgba(0, 0, 0, 0)"}');

通常情況下 svg 會(huì)被序列化 但是可以使用 fabric.Canvas#toDatalessJSON

canvas.item(0).sourcePath = '/assets/dragon.svg';
console.log(JSON.stringify(canvas.toDatalessJSON()));
{"objects":[{"type":"path","left":143,"top":143,"width":175,"height":151,"fill":"#231F20","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":-19,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"path":"/assets/dragon.svg"}],"background":"rgba(0, 0, 0, 0)"}

Subclassing

構(gòu)造類

var Point = fabric.util.createClass({
  initialize: function(x, y) {    this.x = x || 0;    this.y = y || 0;
  },
  toString: function() {    return this.x + '/' + this.y;
  }
});

繼承類

var ColoredPoint = fabric.util.createClass(Point, {
  initialize: function(x, y, color) {    this.callSuper('initialize', x, y);    this.color = color || '#000';
  },
  toString: function() {    return this.callSuper('toString') + ' (color: ' + this.color + ')';
  }
});

繼承默認(rèn)類

var LabeledRect = fabric.util.createClass(fabric.Rect, {
  type: 'labeledRect',
  initialize: function(options) {
    options || (options = { });    this.callSuper('initialize', options);    this.set('label', options.label || '');
  },
  toObject: function() {    return fabric.util.object.extend(this.callSuper('toObject'), {
      label: this.get('label')
    });
  },
  _render: function(ctx) {    this.callSuper('_render', ctx);
    ctx.font = '20px Helvetica';
    ctx.fillStyle = '#333';
    ctx.fillText(this.label, -this.width/2, -this.height/2 + 20);
  }
});

不過其實(shí)沒必要的。


該文章在 2023/5/23 16:49:36 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 国产日韩无码影院一区二区三区 | 国产精品福利在线观看 | 国产成人在线小视频 | 91精品国产亚洲爽啪在线观看 | 国产深夜福利精品一区二区 | 国产精品二区在线 | 国产精品va一区二区三区 | 91成人精品爽啪在线观看 | 国产一区二区三区亚洲精选 | 国产成人涩涩涩视频在线观 | 国产精品成人免费公开视频 | 国产欧美日韩视频怡春院 | 精品久久久久久免费影院8 精品久久久久久清纯 | 国产精品一品二区三区四区五区 | 国产成人无码精品久久久免费 | 国自产拍偷拍精品啪啪一区二 | 91探花在线 | 精品国产一区二区三区不 | 国产欧美日韩综合视频专区 | 果冻传媒视频电影 | av无码精品一区二区三区宅 | 国产一区二区三区在线观看视频 | 国产精品高清在线看 | 国产一区二区三区视频在线观看 | 国产无套视频免费看 | 国产精品白丝jk喷水视频 | 国产丝袜一区二区在线播放 | 国产av无码专区亚洲精品网站 | 国产精品亚洲欧美日韩久久 | 国产视频一区二区在线播放 | 高清视频在线观看一区二区三区 | 18禁裸乳无遮挡啪啪无码免费 | 国产尤物二区三区在线观看 | 国产精品欧美一区喷水 | 韩国欧美福利视频一区二区 | 国产精品成人∨a在线观看 国产精品成人3p一区二区三区 | 国产欧美日韩在线视综合网频 | 成人精品综合免费视频 | 岛国毛片一级一级特 | 国产三香港三韩国三 | 99久久国产自偷自自偷蜜月 |