4 Star 5 Fork 2

Gitee 极速下载/zdog

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
此仓库是为了提升国内下载速度的镜像仓库,每日同步一次。 原始仓库: https://github.com/metafizzy/zdog
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
shape.js 5.79 KB
一键复制 编辑 原始数据 按行查看 历史
/**
* Shape
*/
( function( root, factory ) {
// module definition
if ( typeof module == 'object' && module.exports ) {
/* globals module, require */ // CommonJS
module.exports = factory( require('./boilerplate'), require('./vector'),
require('./path-command'), require('./anchor') );
} else {
// browser global
var Zdog = root.Zdog;
Zdog.Shape = factory( Zdog, Zdog.Vector, Zdog.PathCommand, Zdog.Anchor );
}
}( this, function factory( utils, Vector, PathCommand, Anchor ) {
var Shape = Anchor.subclass({
stroke: 1,
fill: false,
color: '#333',
closed: true,
visible: true,
path: [ {} ],
front: { z: 1 },
backface: true,
});
Shape.prototype.create = function( options ) {
Anchor.prototype.create.call( this, options );
this.updatePath();
// front
this.front = new Vector( options.front || this.front );
this.renderFront = new Vector( this.front );
this.renderNormal = new Vector();
};
var actionNames = [
'move',
'line',
'bezier',
'arc',
];
Shape.prototype.updatePath = function() {
this.setPath();
this.updatePathCommands();
};
// place holder for Ellipse, Rect, etc.
Shape.prototype.setPath = function() {};
// parse path into PathCommands
Shape.prototype.updatePathCommands = function() {
var previousPoint;
this.pathCommands = this.path.map( function( pathPart, i ) {
// pathPart can be just vector coordinates -> { x, y, z }
// or path instruction -> { arc: [ {x0,y0,z0}, {x1,y1,z1} ] }
var keys = Object.keys( pathPart );
var method = keys[0];
var points = pathPart[ method ];
// default to line if no instruction
var isInstruction = keys.length == 1 && actionNames.includes( method );
if ( !isInstruction ) {
method = 'line';
points = pathPart;
}
// munge single-point methods like line & move without arrays
var isLineOrMove = method == 'line' || method == 'move';
var isPointsArray = Array.isArray( points );
if ( isLineOrMove && !isPointsArray ) {
points = [ points ];
}
// first action is always move
method = i === 0 ? 'move' : method;
// arcs require previous last point
var command = new PathCommand( method, points, previousPoint );
// update previousLastPoint
previousPoint = command.endRenderPoint;
return command;
});
};
// ----- update ----- //
Shape.prototype.reset = function() {
this.renderOrigin.set( this.origin );
this.renderFront.set( this.front );
// reset command render points
this.pathCommands.forEach( function( command ) {
command.reset();
});
};
Shape.prototype.transform = function( translation, rotation, scale ) {
// calculate render points backface visibility & cone/hemisphere shapes
this.renderOrigin.transform( translation, rotation, scale );
this.renderFront.transform( translation, rotation, scale );
this.renderNormal.set( this.renderOrigin ).subtract( this.renderFront );
// transform points
this.pathCommands.forEach( function( command ) {
command.transform( translation, rotation, scale );
});
// transform children
this.children.forEach( function( child ) {
child.transform( translation, rotation, scale );
});
};
Shape.prototype.updateSortValue = function() {
var sortValueTotal = 0;
this.pathCommands.forEach( function( command ) {
sortValueTotal += command.endRenderPoint.z;
});
// average sort value of all points
// def not geometrically correct, but works for me
this.sortValue = sortValueTotal / this.pathCommands.length;
};
// ----- render ----- //
Shape.prototype.render = function( ctx, renderer ) {
var length = this.pathCommands.length;
if ( !this.visible || !length ) {
return;
}
// do not render if hiding backface
this.isFacingBack = this.renderNormal.z > 0;
if ( !this.backface && this.isFacingBack ) {
return;
}
if ( !renderer ) {
throw new Error( 'Zdog renderer required. Set to ' + renderer );
}
// render dot or path
var isDot = length == 1;
if ( renderer.isCanvas && isDot ) {
this.renderCanvasDot( ctx, renderer );
} else {
this.renderPath( ctx, renderer );
}
};
var TAU = utils.TAU;
// Safari does not render lines with no size, have to render circle instead
Shape.prototype.renderCanvasDot = function( ctx ) {
var lineWidth = this.getLineWidth();
if ( !lineWidth ) {
return;
}
ctx.fillStyle = this.getRenderColor();
var point = this.pathCommands[0].endRenderPoint;
ctx.beginPath();
var radius = lineWidth/2;
ctx.arc( point.x, point.y, radius, 0, TAU );
ctx.fill();
};
Shape.prototype.getLineWidth = function() {
if ( !this.stroke ) {
return 0;
}
if ( this.stroke == true ) {
return 1;
}
return this.stroke;
};
Shape.prototype.getRenderColor = function() {
// use backface color if applicable
var isBackfaceColor = typeof this.backface == 'string' && this.isFacingBack;
var color = isBackfaceColor ? this.backface : this.color;
return color;
};
Shape.prototype.renderPath = function( ctx, renderer ) {
var elem = this.getRenderElement( ctx, renderer );
var isTwoPoints = this.pathCommands.length == 2 &&
this.pathCommands[1].method == 'line';
var isClosed = !isTwoPoints && this.closed;
var color = this.getRenderColor();
renderer.renderPath( ctx, elem, this.pathCommands, isClosed );
renderer.stroke( ctx, elem, this.stroke, color, this.getLineWidth() );
renderer.fill( ctx, elem, this.fill, color );
renderer.end( ctx, elem );
};
var svgURI = 'http://www.w3.org/2000/svg';
Shape.prototype.getRenderElement = function( ctx, renderer ) {
if ( !renderer.isSvg ) {
return;
}
if ( !this.svgElement ) {
// create svgElement
this.svgElement = document.createElementNS( svgURI, 'path');
this.svgElement.setAttribute( 'stroke-linecap', 'round' );
this.svgElement.setAttribute( 'stroke-linejoin', 'round' );
}
return this.svgElement;
};
return Shape;
}));
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/mirrors/zdog.git
git@gitee.com:mirrors/zdog.git
mirrors
zdog
zdog
v1.0.0

搜索帮助

371d5123 14472233 46e8bd33 14472233