mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-03-16 22:10:32 +00:00
Refactor brushes
This commit is contained in:
parent
21ee892c28
commit
8a74303443
6 changed files with 282 additions and 92 deletions
4
build.js
4
build.js
|
|
@ -115,8 +115,12 @@ var filesToInclude = [
|
|||
|
||||
'src/static_canvas.class.js',
|
||||
|
||||
ifSpecifiedInclude('freedrawing', 'src/base_brush.class.js'),
|
||||
|
||||
ifSpecifiedInclude('freedrawing', 'src/pencil_brush.class.js'),
|
||||
ifSpecifiedInclude('freedrawing', 'src/circle_brush.class.js'),
|
||||
ifSpecifiedInclude('freedrawing', 'src/spray_brush.class.js'),
|
||||
ifSpecifiedInclude('freedrawing', 'src/pattern_brush.class.js'),
|
||||
|
||||
ifSpecifiedInclude('interaction', 'src/canvas.class.js'),
|
||||
|
||||
|
|
|
|||
75
src/base_brush.class.js
Normal file
75
src/base_brush.class.js
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* BaseBrush class
|
||||
* @class fabric.BaseBrush
|
||||
*/
|
||||
fabric.BaseBrush = fabric.util.createClass({
|
||||
|
||||
/**
|
||||
* Color of a brush
|
||||
* @property
|
||||
* @type String
|
||||
*/
|
||||
color: 'rgb(0, 0, 0)',
|
||||
|
||||
/**
|
||||
* Width of a brush
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
width: 1,
|
||||
|
||||
/**
|
||||
* Shadow blur of a brush
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
shadowBlur: 0,
|
||||
|
||||
/**
|
||||
* Shadow color of a brush
|
||||
* @property
|
||||
* @type String
|
||||
*/
|
||||
shadowColor: '',
|
||||
|
||||
/**
|
||||
* Shadow offset x of a brush
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
shadowOffsetX: 0,
|
||||
|
||||
/**
|
||||
* Shadow offset y of a brush
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
shadowOffsetY: 0,
|
||||
|
||||
/**
|
||||
* Sets brush styles
|
||||
* @method setBrushStyles
|
||||
*/
|
||||
setBrushStyles: function() {
|
||||
var ctx = this.canvas.contextTop;
|
||||
|
||||
ctx.strokeStyle = this.color;
|
||||
ctx.lineWidth = this.width;
|
||||
ctx.lineCap = ctx.lineJoin = 'round';
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets brush shadow styles
|
||||
* @method setShadowStyles
|
||||
*/
|
||||
setShadowStyles: function() {
|
||||
var ctx = this.canvas.contextTop;
|
||||
|
||||
if (this.shadowBlur) {
|
||||
ctx.shadowBlur = this.shadowBlur;
|
||||
ctx.shadowColor = this.shadowColor || this.color;
|
||||
ctx.shadowOffsetX = this.shadowOffsetX;
|
||||
ctx.shadowOffsetY = this.shadowOffsetY;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -2,14 +2,7 @@
|
|||
* CircleBrush class
|
||||
* @class fabric.CircleBrush
|
||||
*/
|
||||
fabric.CircleBrush = fabric.util.createClass( /** @scope fabric.CircleBrush.prototype */ {
|
||||
|
||||
/**
|
||||
* Color of the brush
|
||||
* @property
|
||||
* @type String
|
||||
*/
|
||||
color: 'rgb(0, 0, 0)',
|
||||
fabric.CircleBrush = fabric.util.createClass( fabric.BaseBrush, /** @scope fabric.CircleBrush.prototype */ {
|
||||
|
||||
/**
|
||||
* Width of a brush
|
||||
|
|
@ -18,34 +11,6 @@ fabric.CircleBrush = fabric.util.createClass( /** @scope fabric.CircleBrush.prot
|
|||
*/
|
||||
width: 10,
|
||||
|
||||
/**
|
||||
* Shadow blur of a pencil
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
shadowBlur: 0,
|
||||
|
||||
/**
|
||||
* Shadow color of a pencil
|
||||
* @property
|
||||
* @type String
|
||||
*/
|
||||
shadowColor: '',
|
||||
|
||||
/**
|
||||
* Shadow offset x of a pencil
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
shadowOffsetX: 0,
|
||||
|
||||
/**
|
||||
* Shadow offset y of a pencil
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
shadowOffsetY: 0,
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @method initialize
|
||||
|
|
|
|||
41
src/pattern_brush.class.js
Normal file
41
src/pattern_brush.class.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* PatternBrush class
|
||||
* @class fabric.PatternBrush
|
||||
* @extends fabric.BaseBrush
|
||||
*/
|
||||
fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @scope fabric.PatternBrush.prototype */ {
|
||||
|
||||
createPattern: function(patternCanvas) {
|
||||
|
||||
var dotWidth = 20,
|
||||
dotDistance = 5,
|
||||
patternCtx = patternCanvas.getContext('2d');
|
||||
|
||||
patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;
|
||||
|
||||
patternCtx.fillStyle = this.color;
|
||||
patternCtx.beginPath();
|
||||
patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false);
|
||||
patternCtx.closePath();
|
||||
patternCtx.fill();
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates "pattern" instance property
|
||||
* @method createPattern
|
||||
*/
|
||||
getPattern: function() {
|
||||
var patternCanvas = fabric.document.createElement('canvas');
|
||||
this.createPattern(patternCanvas);
|
||||
return this.canvas.contextTop.createPattern(patternCanvas, 'repeat');
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets brush styles
|
||||
* @method setBrushStyles
|
||||
*/
|
||||
setBrushStyles: function() {
|
||||
this.callSuper('setBrushStyles');
|
||||
this.canvas.contextTop.strokeStyle = this.getPattern();
|
||||
}
|
||||
});
|
||||
|
|
@ -6,50 +6,9 @@
|
|||
/**
|
||||
* PencilBrush class
|
||||
* @class fabric.PencilBrush
|
||||
* @extends fabric.BaseBrush
|
||||
*/
|
||||
fabric.PencilBrush = fabric.util.createClass( /** @scope fabric.PencilBrush.prototype */ {
|
||||
|
||||
/**
|
||||
* Color of the pencil
|
||||
* @property
|
||||
* @type String
|
||||
*/
|
||||
color: 'rgb(0, 0, 0)',
|
||||
|
||||
/**
|
||||
* Width of a pencil
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
width: 1,
|
||||
|
||||
/**
|
||||
* Shadow blur of a pencil
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
shadowBlur: 0,
|
||||
|
||||
/**
|
||||
* Shadow color of a pencil
|
||||
* @property
|
||||
* @type String
|
||||
*/
|
||||
shadowColor: '',
|
||||
|
||||
/**
|
||||
* Shadow offset x of a pencil
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
shadowOffsetX: 0,
|
||||
|
||||
/**
|
||||
* Shadow offset y of a pencil
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
shadowOffsetY: 0,
|
||||
fabric.PencilBrush = fabric.util.createClass( fabric.BaseBrush, /** @scope fabric.PencilBrush.prototype */ {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
|
@ -126,19 +85,8 @@
|
|||
_reset: function() {
|
||||
this._points.length = 0;
|
||||
|
||||
var ctx = this.canvas.contextTop;
|
||||
|
||||
ctx.strokeStyle = this.color;
|
||||
ctx.lineWidth = this.width;
|
||||
|
||||
if (this.shadowBlur) {
|
||||
ctx.shadowBlur = this.shadowBlur;
|
||||
ctx.shadowColor = this.shadowColor || this.color;
|
||||
ctx.shadowOffsetX = this.shadowOffsetX;
|
||||
ctx.shadowOffsetY = this.shadowOffsetY;
|
||||
}
|
||||
|
||||
ctx.lineCap = ctx.lineJoin = 'round';
|
||||
this.setBrushStyles();
|
||||
this.setShadowStyles();
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
157
src/spray_brush.class.js
Normal file
157
src/spray_brush.class.js
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/**
|
||||
* SprayBrush class
|
||||
* @class fabric.SprayBrush
|
||||
*/
|
||||
fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @scope fabric.SprayBrush.prototype */ {
|
||||
|
||||
/**
|
||||
* Width of a spray
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
width: 10,
|
||||
|
||||
/**
|
||||
* Density of a spray (number of dots per chunk)
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
density: 20,
|
||||
|
||||
/**
|
||||
* Width of spray dots
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
dotWidth: 1,
|
||||
|
||||
/**
|
||||
* Width variance of spray dots
|
||||
* @property
|
||||
* @type Number
|
||||
*/
|
||||
dotWidthVariance: 1,
|
||||
|
||||
/**
|
||||
* Whether opacity of a dot should be random
|
||||
* @property
|
||||
* @type Boolean
|
||||
*/
|
||||
randomOpacity: false,
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @method initialize
|
||||
* @param {fabric.Canvas} canvas
|
||||
* @return {fabric.SprayBrush} Instance of a spray brush
|
||||
*/
|
||||
initialize: function(canvas) {
|
||||
this.canvas = canvas;
|
||||
this.sprayChunks = [ ];
|
||||
},
|
||||
|
||||
/**
|
||||
* @method onMouseDown
|
||||
* @param {Object} pointer
|
||||
*/
|
||||
onMouseDown: function(pointer) {
|
||||
this.sprayChunks.length = 0;
|
||||
this.canvas.clearContext(this.canvas.contextTop);
|
||||
this.setShadowStyles();
|
||||
|
||||
this.addSprayChunk(pointer);
|
||||
this.render();
|
||||
},
|
||||
|
||||
/**
|
||||
* @method onMouseMove
|
||||
* @param {Object} pointer
|
||||
*/
|
||||
onMouseMove: function(pointer) {
|
||||
this.addSprayChunk(pointer);
|
||||
this.render();
|
||||
},
|
||||
|
||||
/**
|
||||
* @method onMouseUp
|
||||
*/
|
||||
onMouseUp: function() {
|
||||
var originalRenderOnAddition = this.canvas.renderOnAddition;
|
||||
this.canvas.renderOnAddition = false;
|
||||
|
||||
for (var i = 0, ilen = this.sprayChunks.length; i < ilen; i++) {
|
||||
var sprayChunk = this.sprayChunks[i];
|
||||
|
||||
for (var j = 0, jlen = sprayChunk.length; j < jlen; j++) {
|
||||
|
||||
var rect = new fabric.Rect({
|
||||
width: sprayChunk[j].width,
|
||||
height: sprayChunk[j].width,
|
||||
left: sprayChunk[j].x + 1,
|
||||
top: sprayChunk[j].y + 1,
|
||||
fill: this.color
|
||||
});
|
||||
|
||||
this.canvas.add(rect);
|
||||
}
|
||||
}
|
||||
|
||||
this.canvas.renderOnAddition = originalRenderOnAddition;
|
||||
this.canvas.clearContext(this.canvas.contextTop);
|
||||
this.canvas.renderAll();
|
||||
},
|
||||
|
||||
/**
|
||||
* @method render
|
||||
*/
|
||||
render: function() {
|
||||
var ctx = this.canvas.contextTop;
|
||||
ctx.fillStyle = this.color;
|
||||
ctx.save();
|
||||
|
||||
for (var i = 0, len = this.sprayChunkPoints.length; i < len; i++) {
|
||||
var point = this.sprayChunkPoints[i];
|
||||
if (typeof point.opacity !== 'undefined') {
|
||||
ctx.globalAlpha = point.opacity;
|
||||
}
|
||||
ctx.fillRect(point.x, point.y, point.width, point.width);
|
||||
}
|
||||
ctx.restore();
|
||||
},
|
||||
|
||||
/**
|
||||
* @method addSprayChunk
|
||||
* @param {Object} pointer
|
||||
*/
|
||||
addSprayChunk: function(pointer) {
|
||||
this.sprayChunkPoints = [ ];
|
||||
|
||||
var x, y, width, radius = this.width / 2;
|
||||
|
||||
for (var i = 0; i < this.density; i++) {
|
||||
|
||||
x = fabric.util.getRandomInt(pointer.x - radius, pointer.x + radius);
|
||||
y = fabric.util.getRandomInt(pointer.y - radius, pointer.y + radius);
|
||||
|
||||
if (this.dotWidthVariance) {
|
||||
width = fabric.util.getRandomInt(
|
||||
// bottom clamp width to 1
|
||||
Math.max(1, this.dotWidth - this.dotWidthVariance),
|
||||
this.dotWidth + this.dotWidthVariance);
|
||||
}
|
||||
else {
|
||||
width = this.dotWidth;
|
||||
}
|
||||
|
||||
var point = { x: x, y: y, width: width };
|
||||
|
||||
if (this.randomOpacity) {
|
||||
point.opacity = fabric.util.getRandomInt(0, 100) / 100;
|
||||
}
|
||||
|
||||
this.sprayChunkPoints.push(point);
|
||||
}
|
||||
|
||||
this.sprayChunks.push(this.sprayChunkPoints);
|
||||
}
|
||||
});
|
||||
Loading…
Reference in a new issue