本文整理汇总了TypeScript中app/model/paths.Path.mutate方法的典型用法代码示例。如果您正苦于以下问题:TypeScript Path.mutate方法的具体用法?TypeScript Path.mutate怎么用?TypeScript Path.mutate使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类app/model/paths.Path
的用法示例。
在下文中一共展示了Path.mutate方法的7个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的TypeScript代码示例。
示例1:
const deleteCollapsingSubPathsFn = (p: Path) => {
return p.getSubPaths().some(s => s.isCollapsing())
? p
.mutate()
.deleteCollapsingSubPaths()
.build()
: p;
};
示例2: permuteSubPath
function permuteSubPath(from: Path, to: Path, subIdx: number): [Path, Path] {
if (from.isClockwise(subIdx) !== to.isClockwise(subIdx)) {
// Make sure the paths share the same direction.
to = to
.mutate()
.reverseSubPath(subIdx)
.build();
}
// Create and return a list of reversed and shifted from paths to test.
// Each generated 'from path' will be aligned with the target 'to path'.
const fromPaths: Path[] = [from];
if (from.getSubPath(subIdx).isClosed()) {
for (let i = 1; i < from.getSubPath(subIdx).getCommands().length - 1; i++) {
// TODO: we need to find a way to reduce the number of paths to try.
fromPaths.push(
from
.mutate()
.shiftSubPathBack(subIdx, i)
.build(),
);
}
}
let bestFromPath = from;
let min = Infinity;
for (const fromPath of fromPaths) {
const fromCmds = fromPath.getSubPath(subIdx).getCommands();
let sumOfSquares = 0;
const toCmds = to.getSubPath(subIdx).getCommands();
fromCmds.forEach(
(c, cmdIdx) => (sumOfSquares += MathUtil.distance(c.end, toCmds[cmdIdx].end) ** 2),
);
if (sumOfSquares < min) {
min = sumOfSquares;
bestFromPath = fromPath;
}
}
return [bestFromPath, to];
}
示例3: autoConvertSubPath
function autoConvertSubPath(from: Path, to: Path, subIdx: number): [Path, Path] {
const numFrom = from.getSubPath(subIdx).getCommands().length;
const numTo = to.getSubPath(subIdx).getCommands().length;
if (numFrom !== numTo) {
// Only auto convert when the number of commands in both subpaths are equal.
return [from, to];
}
const fromPm = from.mutate();
const toPm = to.mutate();
for (let cmdIdx = 0; cmdIdx < numFrom; cmdIdx++) {
const fromCmd = from.getCommand(subIdx, cmdIdx);
const toCmd = to.getCommand(subIdx, cmdIdx);
if (fromCmd.type === toCmd.type) {
continue;
}
if (fromCmd.canConvertTo(toCmd.type)) {
fromPm.convertCommand(subIdx, cmdIdx, toCmd.type);
} else if (toCmd.canConvertTo(fromCmd.type)) {
toPm.convertCommand(subIdx, cmdIdx, fromCmd.type);
}
}
return [fromPm.build(), toPm.build()];
}
示例4: orderSubPaths
/**
* Reorders the subpaths in each path to minimize the distance each shape will
* travel during the morph.
*/
function orderSubPaths(from: Path, to: Path): [Path, Path] {
if (from.getSubPaths().length > 8 || to.getSubPaths().length > 8) {
// Don't attempt to order paths with many subpaths.
return [from, to];
}
const shouldSwap = from.getSubPaths().length < to.getSubPaths().length;
if (shouldSwap) {
[from, to] = [to, from];
}
const fromSubPaths = from.getSubPaths();
const toSubPaths = to.getSubPaths();
const distances = fromSubPaths.map((f, i) => {
return toSubPaths.map((t, j) => {
const pole1 = from.getPoleOfInaccessibility(i);
const pole2 = to.getPoleOfInaccessibility(j);
return MathUtil.distance(pole1, pole2);
});
});
let min = Infinity;
let best: number[] = [];
(function recurseFn(arr: number[], order: number[] = []) {
if (order.length === toSubPaths.length) {
let sum = 0;
for (let i = 0; i < order.length; i++) {
sum += distances[order[i]][i];
}
if (sum < min) {
min = sum;
best = order;
}
return;
}
for (let i = 0; i < arr.length; i++) {
const [cur] = arr.splice(i, 1);
recurseFn([...arr], [...order, cur]);
if (arr.length) {
arr.splice(i, 0, cur);
}
}
})(_.range(fromSubPaths.length));
const pm = from.mutate();
for (let i = 0; i < best.length; i++) {
const m = best[i];
pm.moveSubPath(m, i);
for (let j = i + 1; j < best.length; j++) {
const n = best[j];
if (n < m) {
best[j]++;
}
}
}
from = pm.build();
if (shouldSwap) {
[from, to] = [to, from];
}
return [from, to];
}
示例5: alignSubPath
/** Aligns two paths using the Needleman-Wunsch algorithm. */
function alignSubPath(from: Path, to: Path, subIdx: number): [Path, Path] {
// Create and return a list of reversed and shifted from paths to test.
// Each generated 'from path' will be aligned with the target 'to path'.
const fromPaths: ReadonlyArray<Path> = _.flatMap(
[
from,
from
.mutate()
.reverseSubPath(subIdx)
.build(),
],
p => {
const paths = [p];
if (p.getSubPath(subIdx).isClosed()) {
for (let i = 1; i < p.getSubPath(subIdx).getCommands().length - 1; i++) {
// TODO: we need to find a way to reduce the number of paths to try.
paths.push(
p
.mutate()
.shiftSubPathBack(subIdx, i)
.build(),
);
}
}
return paths;
},
);
// The scoring function to use to calculate the alignment. Convert-able
// commands are considered matches. However, the farther away the points
// are from each other, the lower the score.
const getScoreFn = (a: Command, b: Command) => {
const charA = a.type;
const charB = b.type;
if (charA !== charB && !a.canConvertTo(charB) && !b.canConvertTo(charA)) {
return MISMATCH;
}
const { x, y } = a.end;
const start = { x, y };
const end = b.end;
return 1 / Math.max(MATCH, MathUtil.distance(start, end));
};
const alignmentInfos = fromPaths.map(generatedFromPath => {
const fromCmds = generatedFromPath.getSubPath(subIdx).getCommands();
const toCmds = to.getSubPath(subIdx).getCommands();
return {
generatedFromPath,
alignment: align(fromCmds, toCmds, getScoreFn),
};
});
// Find the alignment with the highest score.
const alignmentInfo = alignmentInfos.reduce((prev, curr) => {
const prevScore = prev.alignment.score;
const currScore = curr.alignment.score;
return prevScore > currScore ? prev : curr;
});
interface CmdInfo {
readonly isGap: boolean;
readonly isNextGap: boolean;
readonly nextCmdIdx: number;
}
// For each alignment, determine whether it and its neighbor is a gap.
const processAlignmentsFn = (
alignments: ReadonlyArray<Alignment<Command>>,
): ReadonlyArray<CmdInfo> => {
let nextCmdIdx = 0;
return alignments.map((alignment, i) => {
const isGap = !alignment.obj;
const isNextGap = i + 1 < alignments.length && !alignments[i + 1].obj;
if (!isGap) {
nextCmdIdx++;
}
return { isGap, isNextGap, nextCmdIdx } as CmdInfo;
});
};
const fromCmdInfos = processAlignmentsFn(alignmentInfo.alignment.from);
const toCmdInfos = processAlignmentsFn(alignmentInfo.alignment.to);
// Process each list of alignments. Each streak of gaps represents a series
// of one or more splits we'll perform on the path.
const createGapStreaksFn = (cmdInfos: ReadonlyArray<CmdInfo>) => {
const gapStreaks: CmdInfo[][] = [];
let currentGapStreak: CmdInfo[] = [];
for (const cmdInfo of cmdInfos) {
if (cmdInfo.isGap) {
currentGapStreak.push(cmdInfo);
if (!cmdInfo.isNextGap) {
gapStreaks.push(currentGapStreak);
currentGapStreak = [];
}
}
}
return gapStreaks as ReadonlyTable<CmdInfo>;
};
//.........这里部分代码省略.........
示例6: cloneValue
// @Override
cloneValue(value: Path) {
return value ? value.mutate().build() : undefined;
}
示例7: getNodeTransforms
const nodeToLayerFn = (node: Element, transforms: ReadonlyArray<Matrix>): Layer => {
if (
!node ||
node.nodeType === Node.TEXT_NODE ||
node.nodeType === Node.COMMENT_NODE ||
node instanceof SVGDefsElement ||
node instanceof SVGUseElement
) {
return undefined;
}
const nodeTransforms = getNodeTransforms(node as SVGGraphicsElement);
transforms = [...transforms, ...nodeTransforms];
const flattenedTransforms = Matrix.flatten(transforms);
// Get the referenced clip-path ID, if one exists.
const refClipPathId = getReferencedClipPathId(node);
const maybeWrapClipPathInGroupFn = (layer: Layer) => {
if (!refClipPathId) {
return layer;
}
const paths = (clipPathMap[refClipPathId] || []).map(p => {
return new Path(
p
.mutate()
.transform(flattenedTransforms)
.build()
.getPathString(),
);
});
if (!paths.length) {
// If the clipPath has no children, then clip the entire layer.
paths.push(new Path('M 0 0 Z'));
}
const groupChildren: Layer[] = paths.map(p => {
return new ClipPathLayer({
name: makeFinalNodeIdFn(refClipPathId, 'mask'),
pathData: p,
children: [],
});
});
groupChildren.push(layer);
return new GroupLayer({
name: makeFinalNodeIdFn('wrapper', 'group'),
children: groupChildren,
});
};
if (node instanceof SVGPathElement && node.getAttribute('d')) {
const path = node.getAttribute('d');
const attrMap: Dictionary<any> = {};
const simpleAttrFn = (nodeAttr: string, contextAttr: string) => {
if (node.hasAttribute(nodeAttr)) {
attrMap[contextAttr] = node.getAttribute(nodeAttr);
}
};
simpleAttrFn('stroke', 'strokeColor');
simpleAttrFn('stroke-width', 'strokeWidth');
simpleAttrFn('stroke-linecap', 'strokeLinecap');
simpleAttrFn('stroke-linejoin', 'strokeLinejoin');
simpleAttrFn('stroke-miterlimit', 'strokeMiterLimit');
simpleAttrFn('stroke-opacity', 'strokeAlpha');
simpleAttrFn('fill', 'fillColor');
simpleAttrFn('fill-opacity', 'fillAlpha');
simpleAttrFn('fill-rule', 'fillType');
// Set the default values as specified by the SVG spec. Note that some of these default
// values are different than the default values used by VectorDrawables.
const fillColor =
'fillColor' in attrMap ? ColorUtil.svgToAndroidColor(attrMap['fillColor']) : '#000';
const strokeColor =
'strokeColor' in attrMap ? ColorUtil.svgToAndroidColor(attrMap['strokeColor']) : undefined;
const fillAlpha = 'fillAlpha' in attrMap ? Number(attrMap['fillAlpha']) : 1;
let strokeWidth = 'strokeWidth' in attrMap ? Number(attrMap['strokeWidth']) : 1;
const strokeAlpha = 'strokeAlpha' in attrMap ? Number(attrMap['strokeAlpha']) : 1;
const strokeLinecap: StrokeLineCap =
'strokeLinecap' in attrMap ? attrMap['strokeLinecap'] : 'butt';
const strokeLinejoin: StrokeLineJoin =
'strokeLinejoin' in attrMap ? attrMap['strokeLinecap'] : 'miter';
const strokeMiterLimit =
'strokeMiterLimit' in attrMap ? Number(attrMap['strokeMiterLimit']) : 4;
const fillRuleToFillTypeFn = (fillRule: string) => {
return fillRule === 'evenodd' ? 'evenOdd' : 'nonZero';
};
const fillType: FillType =
'fillType' in attrMap ? fillRuleToFillTypeFn(attrMap['fillType']) : 'nonZero';
let pathData = new Path(path);
if (transforms.length) {
pathData = new Path(
pathData
.mutate()
.transform(flattenedTransforms)
.build()
.getPathString(),
);
strokeWidth = MathUtil.round(strokeWidth * flattenedTransforms.getScaleFactor());
}
//.........这里部分代码省略.........