Fabric.js介绍 第八部分

新的clipPath属性

在2.4.0中,我们为所有对象引入了clipPath属性。 ClipPath将替换clipTo: funcion() {},试图获得相同的灵活性但更好的兼容性。

如何使用

创建自己的clipPath作为普通的Fabric对象,并将其指定给要剪辑的对象的clipPath属性。
根据SVG规范中的定义,clipPath没有描边,而是充满黑色,与黑色像素重叠的对象的像素将是可见的,而与黑色像素重叠的对象的像素将是可见的。
让我们从一些基本的例子开始,让我们看看它是什么样的。
在第一个示例中,一个红色的rectable被一个圆圈夹住,只有圆圈内的部分是可见的。虽然不是很有用,但是基本的功能是这样的。
请注意:clipPath位于从物体中心开始的位置,物体的originX和originY不起任何作用,而clipPath的originX和originY则起作用,定位逻辑与fabric.Group相同。

查看demo

(function() {
  var canvas = new fabric.Canvas('ex1');
  var clipPath = new fabric.Circle({
    radius: 40,
    top: -40,
    left: -40
  });
  var rect = new fabric.Rect({
    width: 200,
    height: 100,
    fill: 'red'
  });
  rect.clipPath = clipPath;
  canvas.add(rect);
})()

我们可以剪下一个组合:
查看demo

(function() {
  var canvas = new fabric.Canvas('ex2');
  var clipPath = new fabric.Circle({
    radius: 100,
    top: -100,
    left: -100
  });
  var group = new fabric.Group([
    new fabric.Rect({ width: 100, height: 100, fill: 'red' }),
    new fabric.Rect({ width: 100, height: 100, fill: 'yellow', left: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'blue', top: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'green', left: 100, top: 100 })
  ]);
  group.clipPath = clipPath;
  canvas.add(group);
})()

或者我们可以用组合来剪辑。在组合的情况下,记住组合中的每个对象在逻辑上都是,没有非零偶数的剪裁规则:

查看demo

(function() {
  var canvas = new fabric.Canvas('ex3');
  var clipPath = new fabric.Group([
    new fabric.Circle({ radius: 70, top: -70, left: -70 }),
    new fabric.Circle({ radius: 40, left: -95, top: -95 }),
    new fabric.Circle({ radius: 40, left: 15, top: 15 }),
  ], { left: -95, top: -95 });
  var group = new fabric.Group([
    new fabric.Rect({ width: 100, height: 100, fill: 'red' }),
    new fabric.Rect({ width: 100, height: 100, fill: 'yellow', left: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'blue', top: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'green', left: 100, top: 100 })
  ]);
  group.clipPath = clipPath;
  canvas.add(group);
})()

更多高级用法

嵌套clipPaths

clipTo的一个问题和canvas.clip()的用法是你不能有多个clipPath。
通过这种实现,clippaths可以有自己的clippaths。虽然手动编程不太直观,但它允许将clipPaths交叉到一起。

查看demo

(function() {
  var canvas = new fabric.Canvas('ex4');
  var clipPath = new fabric.Circle({ radius: 70, top: -50, left: -50 });
  var innerClipPath = new fabric.Circle({ radius: 70, top: -90, left: -90 });
  clipPath.clipPath = innerClipPath;
  var group = new fabric.Group([
    new fabric.Rect({ width: 100, height: 100, fill: 'red' }),
    new fabric.Rect({ width: 100, height: 100, fill: 'yellow', left: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'blue', top: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'green', left: 100, top: 100 })
  ]);
  group.clipPath = clipPath;
  canvas.add(group);
})()

组合内对象中的ClipPath应与组本身的clipPath隔离:

查看demo

(function() {
  var canvas = new fabric.Canvas('ex5');
  var clipPath = new fabric.Circle({ radius: 100, top: -100, left: -100 });
  var small = new fabric.Circle({ radius: 50, top: -50, left: -50 });
  var group = new fabric.Group([
    new fabric.Rect({ width: 100, height: 100, fill: 'red', clipPath: small }),
    new fabric.Rect({ width: 100, height: 100, fill: 'yellow', left: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'blue', top: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'green', left: 100, top: 100 })
  ]);
  group.clipPath = clipPath;
  canvas.add(group);
})()

文字剪裁

用文本进行剪裁也是不可能的,开发人员通常不得不依靠模式来实现这一点:

查看demo

(function() {
  var canvas = new fabric.Canvas('ex6');
  var clipPath = new fabric.Text(
    'Hi I\'m the \nnew ClipPath!\nI hope we\'ll\nbe friends',
    { top: -100, left: -100 });
  var group = new fabric.Group([
    new fabric.Rect({ width: 100, height: 100, fill: 'red' }),
    new fabric.Rect({ width: 100, height: 100, fill: 'yellow', left: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'blue', top: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'green', left: 100, top: 100 })
  ]);
  group.clipPath = clipPath;
  canvas.add(group);
})()

剪裁canvas

我们可以对静态画布应用clipPath,就像对对象一样。在这种情况下,clipPath受到缩放和平移的影响,与物体相反。clipPath被放置在左上角。

查看demo

(function() {
  var canvas = new fabric.Canvas('ex7');
  var clipPath = new fabric.Circle({ radius: 100, top: 0, left: 50 });
  var group = new fabric.Group([
    new fabric.Rect({ width: 100, height: 100, fill: 'red' }),
    new fabric.Rect({ width: 100, height: 100, fill: 'yellow', left: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'blue', top: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'green', left: 100, top: 100 })
  ]);
  canvas.clipPath = clipPath;
  canvas.add(group);
})()

作为旧的clipTo函数,clipPath也是剪切控件,除非你使用canvas.controlsAboveOverlay设置为true

查看demo

(function() {
  var canvas = new fabric.Canvas('ex8');
  canvas.controlsAboveOverlay = true;
  var clipPath = new fabric.Circle({ radius: 100, top: 0, left: 50 });
  var group = new fabric.Group([
    new fabric.Rect({ width: 100, height: 100, fill: 'red' }),
    new fabric.Rect({ width: 100, height: 100, fill: 'yellow', left: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'blue', top: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'green', left: 100, top: 100 })
  ]);
  canvas.clipPath = clipPath;
  canvas.add(group);
})()

动画clipPaths

剪贴簿可以像任何其他物体一样进行动画。Canvas clipPath动画非常有效,当动画对象的动画时,每次都会使对象缓存失效。

查看demo

(function() {
  var canvas = new fabric.Canvas('ex9');
  canvas.controlsAboveOverlay = true;
  var clipPath = new fabric.Rect({ width: 100, height: 100, top: 0, left: 0 });
  function animateLeft() {
    clipPath.animate({
      left: 200,
    }, {
      duration: 900,
      onChange: canvas.requestRenderAll.bind(canvas),
      onComplete: animateRight,
    });
  }
  function animateRight() {
    clipPath.animate({
      left: 0,
    }, {
      duration: 1200,
      onChange: canvas.requestRenderAll.bind(canvas),
      onComplete: animateLeft,
    });
  }
  function animateDown() {
    clipPath.animate({
      top: 100,
    }, {
      duration: 500,
      onChange: canvas.requestRenderAll.bind(canvas),
      onComplete: animateUp,
    });
  }
  function animateUp() {
    clipPath.animate({
      top: 0,
    }, {
      duration: 400,
      onChange: canvas.requestRenderAll.bind(canvas),
      onComplete: animateDown,
    });
  }
  var group = new fabric.Group([
    new fabric.Rect({ width: 100, height: 100, fill: 'red' }),
    new fabric.Rect({ width: 100, height: 100, fill: 'yellow', left: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'blue', top: 100 }),
    new fabric.Rect({ width: 100, height: 100, fill: 'green', left: 100, top: 100 })
  ], {
    scaleX: 1.5
  });
  animateLeft();
  animateDown();
  canvas.clipPath = clipPath;
  canvas.add(group);
})()
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,884评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,212评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,351评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,412评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,438评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,127评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,714评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,636评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,173评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,264评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,402评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,073评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,763评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,253评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,382评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,749评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,403评论 2 358