restore backup and add opencode support
This commit is contained in:
1 parent
b99d2ff835
commit
c295660631
72 files changed
+7035
-7198
No files matched your search
+906
@@ -0,0 +1,906 @@
|
||||
import { Injectable, RendererFactory2, ViewChild, Component, Input, Output, EventEmitter, HostListener, ElementRef, Directive, NgModule } from '@angular/core';
|
||||
import { randomUniform } from 'd3-random';
|
||||
import { select } from 'd3-selection';
|
||||
import { line, curveBasis } from 'd3-shape';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
|
||||
/**
|
||||
* @fileoverview added by tsickle
|
||||
* @suppress {checkTypes} checked by tsc
|
||||
*/
|
||||
class NlsCanvasService {
|
||||
/**
|
||||
* @param {?} rendererFactory
|
||||
*/
|
||||
constructor(rendererFactory) {
|
||||
this.rendererFactory = rendererFactory;
|
||||
this.renderer = rendererFactory.createRenderer(null, null);
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
get get() {
|
||||
return this.canvas;
|
||||
}
|
||||
/**
|
||||
* @param {?} el
|
||||
* @return {?}
|
||||
*/
|
||||
set(el) {
|
||||
this.canvas = el;
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
adjustToWindow() {
|
||||
if (this.canvas) {
|
||||
this.renderer.setStyle(this.canvas, 'width', this.canvas.innerWidth);
|
||||
this.renderer.setStyle(this.canvas, 'height', this.canvas.innerHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
NlsCanvasService.decorators = [
|
||||
{ type: Injectable },
|
||||
];
|
||||
/** @nocollapse */
|
||||
NlsCanvasService.ctorParameters = () => [
|
||||
{ type: RendererFactory2 }
|
||||
];
|
||||
|
||||
/**
|
||||
* @fileoverview added by tsickle
|
||||
* @suppress {checkTypes} checked by tsc
|
||||
*/
|
||||
class NlsHistoryService {
|
||||
constructor() {
|
||||
this.history = [];
|
||||
}
|
||||
/**
|
||||
* @param {?} graphs
|
||||
* @param {?} config
|
||||
* @return {?}
|
||||
*/
|
||||
save(graphs, config) {
|
||||
this.history.push({
|
||||
date: new Date(),
|
||||
graphs: graphs,
|
||||
config: config,
|
||||
hash: this.hash(graphs)
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @param {?} graphs
|
||||
* @return {?}
|
||||
*/
|
||||
hash(graphs) {
|
||||
return btoa(JSON.stringify(graphs));
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
list() {
|
||||
return this.history;
|
||||
}
|
||||
}
|
||||
NlsHistoryService.decorators = [
|
||||
{ type: Injectable },
|
||||
];
|
||||
/** @nocollapse */
|
||||
NlsHistoryService.ctorParameters = () => [];
|
||||
|
||||
/**
|
||||
* @fileoverview added by tsickle
|
||||
* @suppress {checkTypes} checked by tsc
|
||||
*/
|
||||
class NlsMathService {
|
||||
/**
|
||||
* Calculate distance between to points with coordinates.
|
||||
* @param {?} a
|
||||
* @param {?} b
|
||||
* @return {?}
|
||||
*/
|
||||
Δ(a, b) {
|
||||
return Math.pow(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2), 0.5);
|
||||
}
|
||||
/**
|
||||
* @param {?} point
|
||||
* @param {?} matrix
|
||||
* @return {?}
|
||||
*/
|
||||
getClosestCenter(point, matrix) {
|
||||
if (this.Δ(point, matrix.start) < this.Δ(point, matrix.end)) {
|
||||
return matrix.start;
|
||||
}
|
||||
else {
|
||||
return matrix.end;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {?} point
|
||||
* @param {?} matrix
|
||||
* @return {?}
|
||||
*/
|
||||
getFarestCenter(point, matrix) {
|
||||
if (this.Δ(point, matrix.start) > this.Δ(point, matrix.end)) {
|
||||
return matrix.start;
|
||||
}
|
||||
else {
|
||||
return matrix.end;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {?} matrix
|
||||
* @param {?} overlap
|
||||
* @return {?}
|
||||
*/
|
||||
randomPoint(matrix, overlap) {
|
||||
/** @type {?} */
|
||||
const x = {
|
||||
min: matrix.center.x - matrix.width * overlap,
|
||||
max: matrix.center.x + matrix.width * overlap
|
||||
};
|
||||
/** @type {?} */
|
||||
const y = {
|
||||
min: matrix.center.y - matrix.height * overlap,
|
||||
max: matrix.center.y + matrix.height * overlap
|
||||
};
|
||||
return {
|
||||
x: randomUniform(x.min, x.max)(),
|
||||
y: randomUniform(y.min, y.max)()
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @param {?} width
|
||||
* @param {?} height
|
||||
* @return {?}
|
||||
*/
|
||||
centerOfArea(width, height) {
|
||||
return {
|
||||
x: width * 0.5,
|
||||
y: height * 0.5
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @param {?} p1
|
||||
* @param {?} p2
|
||||
* @return {?}
|
||||
*/
|
||||
centerOfPoints(p1, p2) {
|
||||
return {
|
||||
x: (p1.x + p2.x) * 0.5,
|
||||
y: (p1.y + p2.y) * 0.5
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @param {?} curve
|
||||
* @return {?}
|
||||
*/
|
||||
centerOfCurve(curve) {
|
||||
/** @type {?} */
|
||||
const genMedian = this.medianPoint(curve);
|
||||
/** @type {?} */
|
||||
const p1 = genMedian.next().value;
|
||||
/** @type {?} */
|
||||
const p2 = genMedian.next().value;
|
||||
/** @type {?} */
|
||||
const radians = this.angleRadians(p1, p2);
|
||||
return Object.assign(this.centerOfPoints(p1, p2), { ascent: radians });
|
||||
}
|
||||
/**
|
||||
* @param {?} curve
|
||||
* @return {?}
|
||||
*/
|
||||
medianOfCurve(curve) {
|
||||
/** @type {?} */
|
||||
const genMedian = this.medianPoint(curve);
|
||||
/** @type {?} */
|
||||
const p1 = genMedian.next().value;
|
||||
/** @type {?} */
|
||||
const p2 = genMedian.next().value;
|
||||
/** @type {?} */
|
||||
const p3 = genMedian.next().value;
|
||||
/** @type {?} */
|
||||
const radians = this.angleRadians(p2, p3);
|
||||
// const radians = Math.round(Math.random() * 10000) / 1000;
|
||||
// @todo if nodes are less than 5 error occures
|
||||
return Object.assign(p1, { ascent: radians });
|
||||
}
|
||||
/**
|
||||
* @param {?} p1
|
||||
* @param {?} p2
|
||||
* @return {?}
|
||||
*/
|
||||
angleRadians(p1, p2) {
|
||||
return Math.atan2(p2.y - p1.y, p2.x - p1.x);
|
||||
}
|
||||
/**
|
||||
* @param {?} p1
|
||||
* @param {?} p2
|
||||
* @return {?}
|
||||
*/
|
||||
angleDegree(p1, p2) {
|
||||
return this.angleRadians(p1, p2) * 180 / Math.PI;
|
||||
}
|
||||
/**
|
||||
* @param {?} list
|
||||
* @return {?}
|
||||
*/
|
||||
medianIndex(list) {
|
||||
return Math.floor(list.length * 0.5);
|
||||
}
|
||||
/**
|
||||
* @param {?} points
|
||||
* @return {?}
|
||||
*/
|
||||
*medianPoint(points) {
|
||||
/** @type {?} */
|
||||
let index;
|
||||
/** @type {?} */
|
||||
const list = points.slice();
|
||||
while (list) {
|
||||
index = this.medianIndex(points);
|
||||
yield list[index];
|
||||
list.splice(index, 1);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Generator for sine bounce
|
||||
*
|
||||
* @param {?=} amplitude default to 1 indicates the amplitude in positive as well
|
||||
* in negative range
|
||||
* @param {?=} decimals amount of decimal places
|
||||
* @param {?=} start 0 indicates to initiate with positive numbers, 1 indicates to
|
||||
* start with negative numbers first
|
||||
* @return {?}
|
||||
*/
|
||||
*bounce(amplitude = 1, decimals = 1, start = 0) {
|
||||
/** @type {?} */
|
||||
const power = Math.pow(10, decimals);
|
||||
/** @type {?} */
|
||||
const step = 2 / (power);
|
||||
/** @type {?} */
|
||||
let index = 0;
|
||||
while (true) {
|
||||
/** @type {?} */
|
||||
const radians = Math.PI * step * index + start;
|
||||
yield Math.round((Math.sin(radians) * amplitude) * power) / power;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {?=} startPositive
|
||||
* @return {?}
|
||||
*/
|
||||
*flipSign(startPositive = true) {
|
||||
/** @type {?} */
|
||||
let sign = startPositive ? 1 : -1;
|
||||
while (true) {
|
||||
yield sign = sign * (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
NlsMathService.decorators = [
|
||||
{ type: Injectable },
|
||||
];
|
||||
|
||||
/**
|
||||
* @fileoverview added by tsickle
|
||||
* @suppress {checkTypes} checked by tsc
|
||||
*/
|
||||
class NlsGraphService {
|
||||
/**
|
||||
* @param {?} math
|
||||
*/
|
||||
constructor(math) {
|
||||
this.math = math;
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
get() {
|
||||
return this.graphs;
|
||||
}
|
||||
/**
|
||||
* @param {?} newGraphs
|
||||
* @return {?}
|
||||
*/
|
||||
set(newGraphs) {
|
||||
this.graphs = newGraphs;
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
get isAnimated() {
|
||||
return this.animation;
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
startAnimation() {
|
||||
this.animation = true;
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
stopAnimation() {
|
||||
this.animation = false;
|
||||
}
|
||||
/**
|
||||
* @param {?} start
|
||||
* @param {?} spacing
|
||||
* @return {?}
|
||||
*/
|
||||
*spreadOrthogonal(start, spacing) {
|
||||
/** @type {?} */
|
||||
const sign = this.math.flipSign();
|
||||
/** @type {?} */
|
||||
let currentPoint = start;
|
||||
/** @type {?} */
|
||||
let i = 0;
|
||||
while (true) {
|
||||
/** @type {?} */
|
||||
const currentSpacing = sign.next().value * spacing * i;
|
||||
currentPoint = this.shiftPoint(currentPoint, start.ascent, currentSpacing);
|
||||
yield currentPoint;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {?} point
|
||||
* @param {?} radians
|
||||
* @param {?} spacing
|
||||
* @return {?}
|
||||
*/
|
||||
shiftPoint(point, radians, spacing) {
|
||||
return {
|
||||
x: Math.sin(radians * Math.PI) * spacing + point.x,
|
||||
y: Math.cos(radians * Math.PI) * spacing + point.y
|
||||
};
|
||||
}
|
||||
}
|
||||
NlsGraphService.decorators = [
|
||||
{ type: Injectable },
|
||||
];
|
||||
/** @nocollapse */
|
||||
NlsGraphService.ctorParameters = () => [
|
||||
{ type: NlsMathService }
|
||||
];
|
||||
|
||||
/**
|
||||
* @fileoverview added by tsickle
|
||||
* @suppress {checkTypes} checked by tsc
|
||||
*/
|
||||
/** @type {?} */
|
||||
const RESIZING_TIMEOUT = 800;
|
||||
class NlsGraphsComponent {
|
||||
/**
|
||||
* @param {?} canvasService
|
||||
* @param {?} historyService
|
||||
* @param {?} math
|
||||
* @param {?} graphService
|
||||
*/
|
||||
constructor(canvasService, historyService, math, graphService) {
|
||||
this.canvasService = canvasService;
|
||||
this.historyService = historyService;
|
||||
this.math = math;
|
||||
this.graphService = graphService;
|
||||
this.svgChange = new EventEmitter();
|
||||
this.graphChange = new EventEmitter();
|
||||
this.genLoadedAllGraphs = this.countLoadedGraphs();
|
||||
this.resizingWindow = false;
|
||||
}
|
||||
/**
|
||||
* @param {?} event
|
||||
* @return {?}
|
||||
*/
|
||||
onResize(event) {
|
||||
clearTimeout(this.resizingWindow);
|
||||
this.resizingWindow = setTimeout(() => {
|
||||
this.canvas = this.adjustCanvas();
|
||||
this.matrix = this.calcMatrix();
|
||||
this.updateGraphs();
|
||||
}, RESIZING_TIMEOUT);
|
||||
}
|
||||
/**
|
||||
* @param {?} changes
|
||||
* @return {?}
|
||||
*/
|
||||
ngOnChanges(changes) {
|
||||
this.canvas = this.adjustCanvas();
|
||||
this.matrix = this.calcMatrix();
|
||||
if (changes["config"]) {
|
||||
this.updateGraphs();
|
||||
}
|
||||
if (this.restoredHistory && this.restoredHistory.hash !== this.hash) {
|
||||
this.restoreGraph();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
restoreGraph() {
|
||||
this.graphs = this.restoredHistory.graphs;
|
||||
this.hash = this.restoredHistory.hash;
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
saveHistory() {
|
||||
this.hash = this.historyService.hash(this.graphs);
|
||||
this.historyService.save(this.graphs, this.config);
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
saveGraph() {
|
||||
this.graphService.set(this.graphs);
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
updateGraphs() {
|
||||
/** @type {?} */
|
||||
const genShiftStart = this.shiftPoint(this.matrix.start, this.config.vectors.start);
|
||||
/** @type {?} */
|
||||
const genShiftEnd = this.shiftPoint(this.matrix.end, this.config.vectors.end, false);
|
||||
console.log(this.matrix);
|
||||
/** @type {?} */
|
||||
const curveList = [
|
||||
{
|
||||
color: this.config.colors.primary,
|
||||
start: genShiftStart.next().value,
|
||||
end: genShiftEnd.next().value
|
||||
},
|
||||
{
|
||||
color: this.config.colors.secondary,
|
||||
start: genShiftEnd.next().value,
|
||||
end: genShiftStart.next().value
|
||||
}
|
||||
];
|
||||
this.graphs = curveList.map(curve => {
|
||||
return Object.assign({}, this.adjustGraph(curve), { spread: this.config.spread, interval: this.config.interval });
|
||||
});
|
||||
this.hash = this.historyService.hash(this.graphs);
|
||||
this.saveHistory();
|
||||
this.saveGraph();
|
||||
}
|
||||
/**
|
||||
* @param {?} curve
|
||||
* @return {?}
|
||||
*/
|
||||
adjustGraph(curve) {
|
||||
return Object.assign(curve, {
|
||||
stroke: this.config.stroke,
|
||||
start: Object.assign(curve.start, {
|
||||
direction: this.genVectorPoint(curve.start.point, curve.start.vector)
|
||||
}),
|
||||
end: Object.assign(curve.end, {
|
||||
direction: this.genVectorPoint(curve.end.point, curve.end.vector)
|
||||
}),
|
||||
nodes: this.genRandomPoints(this.config.nodes)
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @param {?} num
|
||||
* @return {?}
|
||||
*/
|
||||
genRandomPoints(num) {
|
||||
/** @type {?} */
|
||||
const generatedPoints = [];
|
||||
for (let i = 0; i < this.config.nodes; i++) {
|
||||
generatedPoints.push(this.math.randomPoint(this.matrix, this.config.overlap));
|
||||
}
|
||||
return generatedPoints;
|
||||
}
|
||||
/**
|
||||
* @param {?} x
|
||||
* @return {?}
|
||||
*/
|
||||
flipflop(x) {
|
||||
return (x === 'start') ? 'end' : 'start';
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
adjustCanvas() {
|
||||
this.canvasService.set(this.canvas);
|
||||
this.canvasService.adjustToWindow();
|
||||
return this.svgElementRef.nativeElement;
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
calcMatrix() {
|
||||
/** @type {?} */
|
||||
const canvasWidth = this.canvas.getBoundingClientRect().width;
|
||||
/** @type {?} */
|
||||
const canvasHeight = this.canvas.getBoundingClientRect().height;
|
||||
/** @type {?} */
|
||||
const totalCenter = this.math.centerOfArea(canvasWidth, canvasHeight);
|
||||
return {
|
||||
start: {
|
||||
x: 0,
|
||||
y: canvasHeight - this.config.vectors.spacing - this.config.margin.y
|
||||
},
|
||||
end: {
|
||||
x: canvasWidth - this.config.vectors.spacing - this.config.margin.x,
|
||||
y: 0
|
||||
},
|
||||
width: canvasWidth,
|
||||
height: canvasHeight,
|
||||
center: totalCenter
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @param {?} point
|
||||
* @param {?} vector
|
||||
* @return {?}
|
||||
*/
|
||||
genVectorPoint(point, vector) {
|
||||
/** @type {?} */
|
||||
const range = this.math.Δ(this.matrix.start, this.matrix.end) * this.config.vectors.range;
|
||||
return {
|
||||
x: range * Math.sin(Math.PI * vector) + point.x,
|
||||
y: range * Math.cos(Math.PI * vector) + point.y
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @param {?} point
|
||||
* @param {?} vector
|
||||
* @param {?=} startPositive
|
||||
* @return {?}
|
||||
*/
|
||||
*shiftPoint(point, vector, startPositive = true) {
|
||||
/** @type {?} */
|
||||
const genShiftX = this.shiftNumber(this.config.vectors.spacing, vector, startPositive);
|
||||
/** @type {?} */
|
||||
const genShiftY = this.shiftNumber(this.config.vectors.spacing, vector, startPositive);
|
||||
while (true) {
|
||||
yield {
|
||||
point: {
|
||||
x: Math.cos(Math.PI * vector) * genShiftX.next().value + point.x,
|
||||
y: Math.sin(Math.PI * vector) * genShiftY.next().value + point.y,
|
||||
},
|
||||
vector: vector
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {?} space
|
||||
* @param {?} vector
|
||||
* @param {?=} startPositive
|
||||
* @return {?}
|
||||
*/
|
||||
*shiftNumber(space, vector, startPositive = true) {
|
||||
/** @type {?} */
|
||||
let current = 0;
|
||||
/** @type {?} */
|
||||
let index = 0;
|
||||
/** @type {?} */
|
||||
const sign = this.math.flipSign(startPositive);
|
||||
while (true) {
|
||||
yield current = sign.next().value * index * space + current;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {?} guillocheElement
|
||||
* @return {?}
|
||||
*/
|
||||
prepareGuillocheExport(guillocheElement) {
|
||||
if (this.genLoadedAllGraphs.next().value) {
|
||||
this.svgChange.emit(this.svgElementRef);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
*countLoadedGraphs() {
|
||||
/** @type {?} */
|
||||
let cycles = 1;
|
||||
while (true) {
|
||||
if (cycles < this.graphs.length) {
|
||||
yield false;
|
||||
cycles++;
|
||||
}
|
||||
else {
|
||||
yield true;
|
||||
cycles = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NlsGraphsComponent.decorators = [
|
||||
{ type: Component, args: [{
|
||||
selector: 'nls-graphs',
|
||||
template: `<svg #svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1" shape-rendering="geometricPrecision">
|
||||
<g nlsGuilloche *ngFor="let graph of graphs" [graph]="graph" [animation]="animation"></g>
|
||||
</svg>
|
||||
`,
|
||||
styles: [`:host{position:absolute;width:100%;height:100%;top:0;left:0;overflow:hidden}`]
|
||||
},] },
|
||||
];
|
||||
/** @nocollapse */
|
||||
NlsGraphsComponent.ctorParameters = () => [
|
||||
{ type: NlsCanvasService },
|
||||
{ type: NlsHistoryService },
|
||||
{ type: NlsMathService },
|
||||
{ type: NlsGraphService }
|
||||
];
|
||||
NlsGraphsComponent.propDecorators = {
|
||||
config: [{ type: Input }],
|
||||
restoredHistory: [{ type: Input }],
|
||||
animation: [{ type: Input }],
|
||||
svgChange: [{ type: Output }],
|
||||
graphChange: [{ type: Output }],
|
||||
svgElementRef: [{ type: ViewChild, args: ['svg',] }],
|
||||
onResize: [{ type: HostListener, args: ['window:resize', ['$event'],] }]
|
||||
};
|
||||
|
||||
/**
|
||||
* @fileoverview added by tsickle
|
||||
* @suppress {checkTypes} checked by tsc
|
||||
*/
|
||||
class NlsGuillocheDirective {
|
||||
/**
|
||||
* @param {?} canvasService
|
||||
* @param {?} el
|
||||
* @param {?} math
|
||||
* @param {?} graphService
|
||||
*/
|
||||
constructor(canvasService, el, math, graphService) {
|
||||
this.canvasService = canvasService;
|
||||
this.el = el;
|
||||
this.math = math;
|
||||
this.graphService = graphService;
|
||||
}
|
||||
/**
|
||||
* @return {?}
|
||||
*/
|
||||
ngOnDestroy() {
|
||||
this.group.selectAll('*').remove();
|
||||
}
|
||||
/**
|
||||
* @param {?} changes
|
||||
* @return {?}
|
||||
*/
|
||||
ngOnChanges(changes) {
|
||||
this.group = select(this.el.nativeElement);
|
||||
this.canvas = select(this.canvasService.get);
|
||||
// @todo modify graph here instead of in graphs.component.ts
|
||||
this.initialNodes = this.graph.nodes.slice();
|
||||
this.initialCurve = [
|
||||
this.graph.start.point,
|
||||
this.graph.start.direction,
|
||||
...this.graph.nodes.slice(),
|
||||
this.graph.end.direction,
|
||||
this.graph.end.point
|
||||
];
|
||||
this.medianPoint = this.math.medianOfCurve(this.initialCurve);
|
||||
this.medianIndex = this.math.medianIndex(this.initialCurve);
|
||||
if (this.animation) {
|
||||
this.graph.nodes = this.graph.nodes.slice().map((node, i) => {
|
||||
return {
|
||||
x: node.x,
|
||||
y: node.y,
|
||||
// ascent: Math.round(Math.random() * 100) / 100
|
||||
ascent: this.medianPoint.ascent + i * 0.5
|
||||
};
|
||||
});
|
||||
this.bounces = this.initialNodes.map(node => {
|
||||
/** @type {?} */
|
||||
const bounceAmplitude = Math.round(Math.random() * 150);
|
||||
return this.math.bounce(bounceAmplitude, 3);
|
||||
});
|
||||
/** @type {?} */
|
||||
let i = 0;
|
||||
this.animationInterval = setInterval(() => {
|
||||
this.animateGraph(i++ % 1000 / 10000);
|
||||
}, this.graph.interval);
|
||||
}
|
||||
else {
|
||||
if (this.animationInterval) {
|
||||
this.bounce = null;
|
||||
clearInterval(this.animationInterval);
|
||||
}
|
||||
}
|
||||
this.group.selectAll('*').remove();
|
||||
this.pathElements = [];
|
||||
/** @type {?} */
|
||||
const graphs = this.spreadLines([
|
||||
this.graph.start.point,
|
||||
this.graph.start.direction,
|
||||
...this.graph.nodes,
|
||||
this.graph.end.direction,
|
||||
this.graph.end.point,
|
||||
]).forEach((points, index) => this.drawGraph(points));
|
||||
}
|
||||
/**
|
||||
* @param {?} x
|
||||
* @return {?}
|
||||
*/
|
||||
animateGraph(x) {
|
||||
/** @type {?} */
|
||||
const graphs = this.spreadLines([
|
||||
this.graph.start.point,
|
||||
this.graph.start.direction,
|
||||
...this.graph.nodes.map((point, i) => {
|
||||
/** @type {?} */
|
||||
const ascent = point.ascent * Math.sin(Math.PI * x);
|
||||
return this.graphService.shiftPoint(point, ascent, this.bounces[i].next().value);
|
||||
}),
|
||||
this.graph.end.direction,
|
||||
this.graph.end.point,
|
||||
]);
|
||||
graphs.forEach((points, i) => this.updateGraph(points, i));
|
||||
}
|
||||
/**
|
||||
* @param {?} points
|
||||
* @return {?}
|
||||
*/
|
||||
spreadLines(points) {
|
||||
/** @type {?} */
|
||||
const shiftedMedians = [];
|
||||
/** @type {?} */
|
||||
const genshiftedMedians = this.graphService.spreadOrthogonal(this.medianPoint, this.graph.spread.spacing);
|
||||
for (let i = 0; i < this.graph.spread.amount; i++) {
|
||||
shiftedMedians.push(genshiftedMedians.next().value);
|
||||
}
|
||||
return shiftedMedians.map(median => {
|
||||
/** @type {?} */
|
||||
const shiftedPoints = points.slice();
|
||||
shiftedPoints.splice(this.medianIndex, 1, median);
|
||||
return shiftedPoints;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @param {?} points
|
||||
* @param {?} index
|
||||
* @return {?}
|
||||
*/
|
||||
updateGraph(points, index) {
|
||||
this.pathElements[index]
|
||||
.attr('d', line()
|
||||
.x(p => p.x)
|
||||
.y(p => p.y)
|
||||
.curve(curveBasis)(points));
|
||||
}
|
||||
/**
|
||||
* @param {?} points
|
||||
* @return {?}
|
||||
*/
|
||||
drawGraph(points) {
|
||||
this.group
|
||||
.attr('stroke', this.graph.color)
|
||||
.attr('stroke-width', this.graph.stroke)
|
||||
.attr('fill', 'none');
|
||||
this.pathElements.push(this.group.append('path')
|
||||
.attr('d', line()
|
||||
.x(p => p.x)
|
||||
.y(p => p.y)
|
||||
.curve(curveBasis)(points)));
|
||||
}
|
||||
/**
|
||||
* @param {?} points
|
||||
* @return {?}
|
||||
*/
|
||||
debugGraph(points) {
|
||||
points.forEach((point, index) => {
|
||||
/** @type {?} */
|
||||
const circle = this.group.append('g');
|
||||
circle.append('circle')
|
||||
.attr('cx', point.x)
|
||||
.attr('cy', point.y)
|
||||
.attr('r', 3)
|
||||
.attr('fill-opacity', 0.6)
|
||||
.attr('fill', this.graph.color);
|
||||
circle.append('text')
|
||||
.attr('x', point.x)
|
||||
.attr('y', point.y)
|
||||
.attr('dx', 8)
|
||||
.attr('dy', 15)
|
||||
.attr('fill', this.graph.color)
|
||||
.text(index);
|
||||
});
|
||||
}
|
||||
}
|
||||
NlsGuillocheDirective.decorators = [
|
||||
{ type: Directive, args: [{
|
||||
selector: '[nlsGuilloche]'
|
||||
},] },
|
||||
];
|
||||
/** @nocollapse */
|
||||
NlsGuillocheDirective.ctorParameters = () => [
|
||||
{ type: NlsCanvasService },
|
||||
{ type: ElementRef },
|
||||
{ type: NlsMathService },
|
||||
{ type: NlsGraphService }
|
||||
];
|
||||
NlsGuillocheDirective.propDecorators = {
|
||||
graph: [{ type: Input }],
|
||||
animation: [{ type: Input }]
|
||||
};
|
||||
|
||||
/**
|
||||
* @fileoverview added by tsickle
|
||||
* @suppress {checkTypes} checked by tsc
|
||||
*/
|
||||
class NlsAnimationService {
|
||||
/**
|
||||
* @param {?} math
|
||||
* @param {?} historyService
|
||||
*/
|
||||
constructor(math, historyService) {
|
||||
this.math = math;
|
||||
this.historyService = historyService;
|
||||
}
|
||||
/**
|
||||
* @param {?} initialGraph
|
||||
* @return {?}
|
||||
*/
|
||||
animate(initialGraph) {
|
||||
/** @type {?} */
|
||||
const newGraph = Object.assign({}, initialGraph);
|
||||
/** @type {?} */
|
||||
const indexMiddle = Math.floor(newGraph.nodes.length * 0.5);
|
||||
/** @type {?} */
|
||||
const pointMiddle = newGraph.nodes[indexMiddle];
|
||||
newGraph.nodes.splice(indexMiddle, 1, {
|
||||
x: pointMiddle.x - 2,
|
||||
y: pointMiddle.y + 2,
|
||||
});
|
||||
return newGraph;
|
||||
// });
|
||||
}
|
||||
}
|
||||
NlsAnimationService.decorators = [
|
||||
{ type: Injectable },
|
||||
];
|
||||
/** @nocollapse */
|
||||
NlsAnimationService.ctorParameters = () => [
|
||||
{ type: NlsMathService },
|
||||
{ type: NlsHistoryService }
|
||||
];
|
||||
|
||||
/**
|
||||
* @fileoverview added by tsickle
|
||||
* @suppress {checkTypes} checked by tsc
|
||||
*/
|
||||
class NlsGuillocheModule {
|
||||
}
|
||||
NlsGuillocheModule.decorators = [
|
||||
{ type: NgModule, args: [{
|
||||
imports: [
|
||||
BrowserModule
|
||||
],
|
||||
declarations: [
|
||||
NlsGraphsComponent,
|
||||
NlsGuillocheDirective
|
||||
],
|
||||
providers: [
|
||||
NlsHistoryService,
|
||||
NlsCanvasService,
|
||||
NlsMathService,
|
||||
NlsGraphService,
|
||||
],
|
||||
exports: [
|
||||
NlsGraphsComponent,
|
||||
NlsGuillocheDirective
|
||||
]
|
||||
},] },
|
||||
];
|
||||
|
||||
/**
|
||||
* @fileoverview added by tsickle
|
||||
* @suppress {checkTypes} checked by tsc
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview added by tsickle
|
||||
* @suppress {checkTypes} checked by tsc
|
||||
*/
|
||||
|
||||
export { NlsGraphsComponent, NlsGuillocheDirective, NlsAnimationService, NlsCanvasService, NlsGraphService, NlsHistoryService, NlsMathService, NlsGuillocheModule };
|
||||
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmxzLWd1aWxsb2NoZS5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vbmxzLWd1aWxsb2NoZS9ubHMvc2VydmljZXMvY2FudmFzLnNlcnZpY2UudHMiLCJuZzovL25scy1ndWlsbG9jaGUvbmxzL3NlcnZpY2VzL2hpc3Rvcnkuc2VydmljZS50cyIsIm5nOi8vbmxzLWd1aWxsb2NoZS9ubHMvc2VydmljZXMvbWF0aC5zZXJ2aWNlLnRzIiwibmc6Ly9ubHMtZ3VpbGxvY2hlL25scy9zZXJ2aWNlcy9ncmFwaC5zZXJ2aWNlLnRzIiwibmc6Ly9ubHMtZ3VpbGxvY2hlL25scy9jb21wb25lbnRzL2dyYXBocy5jb21wb25lbnQudHMiLCJuZzovL25scy1ndWlsbG9jaGUvbmxzL2RpcmVjdGl2ZXMvZ3VpbGxvY2hlLmRpcmVjdGl2ZS50cyIsIm5nOi8vbmxzLWd1aWxsb2NoZS9ubHMvc2VydmljZXMvYW5pbWF0aW9uLnNlcnZpY2UudHMiLCJuZzovL25scy1ndWlsbG9jaGUvbmxzL25scy1ndWlsbG9jaGUubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChDKSAyMDE4IE1pY2hhZWwgQ3plY2hvd3NraSA8bWFpbEBkYWlseXNoLml0PlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXRcbiAqIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlXG4gKiBTb2Z0d2FyZSBGb3VuZGF0aW9uOyB2ZXJzaW9uIDIuXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUXG4gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3JcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvclxuICogbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGhcbiAqIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBJbmMuLCA1MVxuICogRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EuXG4gKi9cblxuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlLCBSZW5kZXJlcjIsIFJlbmRlcmVyRmFjdG9yeTIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIFNlbGVjdGlvbiBmcm9tICdkMy1zZWxlY3Rpb24nO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTmxzQ2FudmFzU2VydmljZSB7XG4gIHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMjtcblxuICBwdWJsaWMgY2FudmFzOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZW5kZXJlckZhY3Rvcnk6IFJlbmRlcmVyRmFjdG9yeTJcbiAgKSB7XG4gICAgdGhpcy5yZW5kZXJlciA9IHJlbmRlcmVyRmFjdG9yeS5jcmVhdGVSZW5kZXJlcihudWxsLCBudWxsKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLmNhbnZhcztcbiAgfVxuXG4gIHB1YmxpYyBzZXQoZWwpIHtcbiAgICB0aGlzLmNhbnZhcyA9IGVsO1xuICB9XG5cbiAgcHVibGljIGFkanVzdFRvV2luZG93KCkge1xuICAgIGlmICh0aGlzLmNhbnZhcykge1xuICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZShcbiAgICAgICAgdGhpcy5jYW52YXMsXG4gICAgICAgICd3aWR0aCcsXG4gICAgICAgIHRoaXMuY2FudmFzLmlubmVyV2lkdGhcbiAgICAgICk7XG4gICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKFxuICAgICAgICB0aGlzLmNhbnZhcyxcbiAgICAgICAgJ2hlaWdodCcsXG4gICAgICAgIHRoaXMuY2FudmFzLmlubmVySGVpZ2h0XG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuIiwiLyoqXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTggTWljaGFlbCBDemVjaG93c2tpIDxtYWlsQGRhaWx5c2guaXQ+XG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdFxuICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWVcbiAqIFNvZnR3YXJlIEZvdW5kYXRpb247IHZlcnNpb24gMi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVRcbiAqIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvclxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yXG4gKiBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYWxvbmcgd2l0aFxuICogdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIEluYy4sIDUxXG4gKiBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQS5cbiAqL1xuXG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIE9wdGlvbmFsLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIFNlbGVjdGlvbiBmcm9tICdkMy1zZWxlY3Rpb24nO1xuXG5pbXBvcnQgeyBHcmFwaCB9IGZyb20gJy4uL21vZGVscy9ncmFwaC5tb2RlbCc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBObHNIaXN0b3J5U2VydmljZSB7XG5cbiAgcHVibGljIGhpc3Rvcnk6IGFueVtdO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuaGlzdG9yeSA9IFtdO1xuICB9XG5cbiAgcHVibGljIHNhdmUoZ3JhcGhzOiBHcmFwaFtdLCBjb25maWcpIHtcbiAgICB0aGlzLmhpc3RvcnkucHVzaCh7XG4gICAgICBkYXRlOiBuZXcgRGF0ZSgpLFxuICAgICAgZ3JhcGhzOiBncmFwaHMsXG4gICAgICBjb25maWc6IGNvbmZpZyxcbiAgICAgIGhhc2g6IHRoaXMuaGFzaChncmFwaHMpXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgaGFzaChncmFwaHMpIHtcbiAgICByZXR1cm4gYnRvYShKU09OLnN0cmluZ2lmeShncmFwaHMpKTtcbiAgfVxuXG4gIHB1YmxpYyBsaXN0KCkge1xuICAgIHJldHVybiB0aGlzLmhpc3Rvcnk7XG4gIH1cbn1cblxuIiwiLyoqXG4gKiBDb3B5cmlnaHQgKEMpIDIwMTggTWljaGFlbCBDemVjaG93c2tpIDxtYWlsQGRhaWx5c2guaXQ+XG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdFxuICogdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWVcbiAqIFNvZnR3YXJlIEZvdW5kYXRpb247IHZlcnNpb24gMi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFd
Line truncated
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"nls-guilloche.js.map","sources":["ng://nls-guilloche/nls/services/canvas.service.ts","ng://nls-guilloche/nls/services/history.service.ts","ng://nls-guilloche/nls/services/math.service.ts","ng://nls-guilloche/nls/services/graph.service.ts","ng://nls-guilloche/nls/components/graphs.component.ts","ng://nls-guilloche/nls/directives/guilloche.directive.ts","ng://nls-guilloche/nls/services/animation.service.ts","ng://nls-guilloche/nls/nls-guilloche.module.ts"],"sourcesContent":["/**\n * Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>\n * This program is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License as published by the Free\n * Software Foundation; version 2.\n *\n * This program is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License along with\n * this program; if not, write to the Free Software Foundation, Inc., 51\n * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n */\n\nimport { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core';\nimport * as Selection from 'd3-selection';\n\n@Injectable()\nexport class NlsCanvasService {\n private renderer: Renderer2;\n\n public canvas: any;\n\n constructor(\n private rendererFactory: RendererFactory2\n ) {\n this.renderer = rendererFactory.createRenderer(null, null);\n }\n\n public get get() {\n return this.canvas;\n }\n\n public set(el) {\n this.canvas = el;\n }\n\n public adjustToWindow() {\n if (this.canvas) {\n this.renderer.setStyle(\n this.canvas,\n 'width',\n this.canvas.innerWidth\n );\n this.renderer.setStyle(\n this.canvas,\n 'height',\n this.canvas.innerHeight\n );\n }\n }\n}\n","/**\n * Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>\n * This program is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License as published by the Free\n * Software Foundation; version 2.\n *\n * This program is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License along with\n * this program; if not, write to the Free Software Foundation, Inc., 51\n * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n */\n\nimport { Inject, Injectable, Optional, ViewChild } from '@angular/core';\nimport * as Selection from 'd3-selection';\n\nimport { Graph } from '../models/graph.model';\n\n@Injectable()\nexport class NlsHistoryService {\n\n public history: any[];\n\n constructor() {\n this.history = [];\n }\n\n public save(graphs: Graph[], config) {\n this.history.push({\n date: new Date(),\n graphs: graphs,\n config: config,\n hash: this.hash(graphs)\n });\n }\n\n public hash(graphs) {\n return btoa(JSON.stringify(graphs));\n }\n\n public list() {\n return this.history;\n }\n}\n\n","/**\n * Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>\n * This program is free software; you can redistribute it and/or modify it\n * under the terms of the GNU General Public License as published by the Free\n * Software Foundation; version 2.\n *\n * This program is distributed in the hope that it will be useful, but WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n * more details.\n *\n * You should have received a copy of the GNU General Public License along with\n * this program; if not, write to the Free Software Foundation, Inc., 51\n * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n */\n\nimport { Inject, Injectable } from '@angular/core';\nimport * as Selection from 'd3-selection';\nimport * as Random from 'd3-random';\n\nimport { Point } from './../models/point.model';\nimport { Graph } from './../models/graph.model';\n\n@Injectable()\nexport class NlsMathService {\n\n /**\n * Calculate distance between to points with coordinates.\n * @param a\n * @param b\n */\n public Î(a: Point, b: Point) {\n return Math.pow(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2), 0.5);\n }\n\n public getClosestCenter(point: Point, matrix: any) {\n if (this.Î(point, matrix.start) < this.Î(point, matrix.end)) {\n return matrix.start;\n } else {\n return matrix.end;\n }\n }\n\n public getFarestCenter(point: Point, matrix: any) {\n if (this.Î(point, matrix.start) > this.Î(point, matrix.end)) {\n return matrix.start;\n } else {Line truncated
|
||||
Reference in new issue
Block a user