prepared library publishing
This commit is contained in:
@@ -26,6 +26,9 @@
|
||||
"url": "https://dailysh.it"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"d3": "^5.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^6.0.0-rc.0 || ^6.0.0",
|
||||
"@angular/core": "^6.0.0-rc.0 || ^6.0.0"
|
||||
|
||||
193
projects/nls-guilloche/src/lib/directives/guilloche.directive.ts
Normal file
193
projects/nls-guilloche/src/lib/directives/guilloche.directive.ts
Normal file
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
import { ElementRef, HostListener, Input, Directive, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
|
||||
import * as Selection from 'd3-selection';
|
||||
import * as Shape from 'd3-shape';
|
||||
import * as Random from 'd3-random';
|
||||
import * as Drag from 'd3-drag';
|
||||
import * as Ease from 'd3-ease';
|
||||
import * as Timer from 'd3-timer';
|
||||
|
||||
import { Config } from './../models/config.model';
|
||||
import { Graph } from './../models/graph.model';
|
||||
import { Point } from './../models/point.model';
|
||||
import { Param } from './../models/param.model';
|
||||
import { NlsCanvasService } from './../services/canvas.service';
|
||||
import { NlsMathService } from './../services/math.service';
|
||||
import { NlsGraphService } from '../services/graph.service';
|
||||
|
||||
const ANIMATION_INTERVAL = 60;
|
||||
|
||||
@Directive({
|
||||
selector: '[nlsGuilloche]'
|
||||
})
|
||||
export class NlsGuillocheDirective implements OnChanges, OnDestroy {
|
||||
|
||||
private canvas: any;
|
||||
private group: any;
|
||||
private bounce: any | null;
|
||||
private bounces: any | null;
|
||||
private initialNodes: any;
|
||||
private initialCurve: any;
|
||||
private animationInterval: any;
|
||||
private medianPoint: Point;
|
||||
private medianIndex: number;
|
||||
private pathElements: any;
|
||||
|
||||
@Input() graph: Graph;
|
||||
@Input() matrix: any;
|
||||
@Input() config: any;
|
||||
@Input() animate: boolean;
|
||||
|
||||
constructor(
|
||||
private canvasService: NlsCanvasService,
|
||||
private el: ElementRef,
|
||||
private math: NlsMathService,
|
||||
private graphService: NlsGraphService
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.group.selectAll('*').remove();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
this.group = Selection.select(this.el.nativeElement);
|
||||
this.canvas = Selection.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.graphService.isAnimated) {
|
||||
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 => {
|
||||
const bounceAmplitude = Math.round(Math.random() * 150);
|
||||
return this.math.bounce(bounceAmplitude, 3);
|
||||
});
|
||||
let i = 0;
|
||||
this.animationInterval = setInterval(() => {
|
||||
// this.animateGraph();
|
||||
this.animateGraph(i++ % 1000 / 10000);
|
||||
}, ANIMATION_INTERVAL);
|
||||
} else {
|
||||
if (this.animationInterval) {
|
||||
this.bounce = null;
|
||||
clearInterval(this.animationInterval);
|
||||
// return;
|
||||
}
|
||||
}
|
||||
|
||||
this.group.selectAll('*').remove();
|
||||
this.pathElements = [];
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
private animateGraph(x) {
|
||||
const graphs = this.spreadLines([
|
||||
this.graph.start.point,
|
||||
this.graph.start.direction,
|
||||
...this.graph.nodes.map((point, i) => {
|
||||
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));
|
||||
}
|
||||
|
||||
private spreadLines(points: Point[]) {
|
||||
const shiftedMedians = [];
|
||||
const genshiftedMedians = this.graphService.spreadOrthogonal(this.medianPoint, this.config.spread.spacing);
|
||||
|
||||
for (let i = 0; i < this.config.spread.amount; i++) {
|
||||
shiftedMedians.push(genshiftedMedians.next().value);
|
||||
}
|
||||
|
||||
return shiftedMedians.map(median => {
|
||||
const shiftedPoints = points.slice();
|
||||
shiftedPoints.splice(this.medianIndex, 1, median);
|
||||
return shiftedPoints;
|
||||
});
|
||||
}
|
||||
|
||||
private updateGraph(points: Point[], index: number): void {
|
||||
this.pathElements[index]
|
||||
.attr('d', Shape.line()
|
||||
.x(p => p.x)
|
||||
.y(p => p.y)
|
||||
.curve(Shape.curveBasis)(points));
|
||||
}
|
||||
|
||||
private drawGraph(points: Point[]): void {
|
||||
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', Shape.line()
|
||||
.x(p => p.x)
|
||||
.y(p => p.y)
|
||||
.curve(Shape.curveBasis)(points)));
|
||||
}
|
||||
|
||||
private debugGraph(points: Point[]) {
|
||||
points.forEach((point, index) => {
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
37
projects/nls-guilloche/src/lib/models/config.model.ts
Normal file
37
projects/nls-guilloche/src/lib/models/config.model.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
export interface Config {
|
||||
width: number;
|
||||
height: number;
|
||||
start: {
|
||||
x: number;
|
||||
y: number;
|
||||
color: string;
|
||||
};
|
||||
end: {
|
||||
x: number;
|
||||
y: number;
|
||||
color: string;
|
||||
};
|
||||
vectors: {
|
||||
spacing: number
|
||||
};
|
||||
spread: {
|
||||
amount: number;
|
||||
spacing: number
|
||||
};
|
||||
}
|
||||
34
projects/nls-guilloche/src/lib/models/graph.model.ts
Normal file
34
projects/nls-guilloche/src/lib/models/graph.model.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
import { Point } from './point.model';
|
||||
|
||||
export interface Graph {
|
||||
id: string;
|
||||
color: string; // can be set in enviroment
|
||||
start: {
|
||||
point: Point;
|
||||
direction?: Point;
|
||||
vector: number; // degree between 0 and 360
|
||||
};
|
||||
end: {
|
||||
point: Point;
|
||||
direction?: Point;
|
||||
vector: number; // degree between 0 and 360
|
||||
};
|
||||
stroke: number; // stroke width
|
||||
nodes?: Point[]; // orientation points
|
||||
}
|
||||
33
projects/nls-guilloche/src/lib/models/param.model.ts
Normal file
33
projects/nls-guilloche/src/lib/models/param.model.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
export interface Param {
|
||||
colors: {
|
||||
start: string,
|
||||
end: string
|
||||
};
|
||||
points: number;
|
||||
margin: {
|
||||
x: number,
|
||||
y: number
|
||||
};
|
||||
spread: number;
|
||||
space: number;
|
||||
stroke?: {
|
||||
width: number;
|
||||
};
|
||||
showGrid?: boolean;
|
||||
}
|
||||
22
projects/nls-guilloche/src/lib/models/point.model.ts
Normal file
22
projects/nls-guilloche/src/lib/models/point.model.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
export interface Point {
|
||||
x: number;
|
||||
y: number;
|
||||
color?: string;
|
||||
ascent?: number;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { NlsGuillocheComponent } from './nls-guilloche.component';
|
||||
|
||||
describe('NlsGuillocheComponent', () => {
|
||||
let component: NlsGuillocheComponent;
|
||||
let fixture: ComponentFixture<NlsGuillocheComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ NlsGuillocheComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(NlsGuillocheComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,19 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'lib-nls-guilloche',
|
||||
template: `
|
||||
<p>
|
||||
nls-guilloche works!
|
||||
</p>
|
||||
`,
|
||||
styles: []
|
||||
})
|
||||
export class NlsGuillocheComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { NlsGuillocheComponent } from './nls-guilloche.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
],
|
||||
declarations: [NlsGuillocheComponent],
|
||||
exports: [NlsGuillocheComponent]
|
||||
})
|
||||
export class NlsGuillocheModule { }
|
||||
@@ -1,15 +0,0 @@
|
||||
import { TestBed, inject } from '@angular/core/testing';
|
||||
|
||||
import { NlsGuillocheService } from './nls-guilloche.service';
|
||||
|
||||
describe('NlsGuillocheService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [NlsGuillocheService]
|
||||
});
|
||||
});
|
||||
|
||||
it('should be created', inject([NlsGuillocheService], (service: NlsGuillocheService) => {
|
||||
expect(service).toBeTruthy();
|
||||
}));
|
||||
});
|
||||
@@ -1,9 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class NlsGuillocheService {
|
||||
|
||||
constructor() { }
|
||||
}
|
||||
60
projects/nls-guilloche/src/lib/services/animation.service.ts
Normal file
60
projects/nls-guilloche/src/lib/services/animation.service.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
import { Inject, Injectable, Optional, ViewChild } from '@angular/core';
|
||||
import { interval, Observable } from 'rxjs';
|
||||
import * as Selection from 'd3-selection';
|
||||
|
||||
import { Graph } from '../models/graph.model';
|
||||
import { NlsMathService } from './math.service';
|
||||
import { NlsHistoryService } from './history.service';
|
||||
|
||||
@Injectable()
|
||||
export class NlsAnimationService {
|
||||
|
||||
public graphs: Graph[];
|
||||
public speed: number;
|
||||
public range: number;
|
||||
// public genAnimation: any;
|
||||
// private timer: Observable<number>;
|
||||
// private subscribtion: any;
|
||||
|
||||
constructor(
|
||||
private math: NlsMathService,
|
||||
private historyService: NlsHistoryService,
|
||||
) {
|
||||
}
|
||||
|
||||
// public animate(initialGraphs: Graph[]) {
|
||||
public animate(initialGraph: Graph) {
|
||||
// const newGraphs = initialGraphs.slice();
|
||||
|
||||
// return newGraphs.map(graph => {
|
||||
|
||||
const newGraph = Object.assign({}, initialGraph);
|
||||
const indexMiddle = Math.floor(newGraph.nodes.length * 0.5);
|
||||
const pointMiddle = newGraph.nodes[indexMiddle];
|
||||
|
||||
newGraph.nodes.splice(indexMiddle, 1, {
|
||||
x: pointMiddle.x - 2,
|
||||
y: pointMiddle.y + 2,
|
||||
});
|
||||
|
||||
return newGraph;
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
54
projects/nls-guilloche/src/lib/services/canvas.service.ts
Normal file
54
projects/nls-guilloche/src/lib/services/canvas.service.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
import { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core';
|
||||
import * as Selection from 'd3-selection';
|
||||
|
||||
@Injectable()
|
||||
export class NlsCanvasService {
|
||||
private renderer: Renderer2;
|
||||
|
||||
public canvas: any;
|
||||
|
||||
constructor(
|
||||
private rendererFactory: RendererFactory2
|
||||
) {
|
||||
this.renderer = rendererFactory.createRenderer(null, null);
|
||||
}
|
||||
|
||||
public get get() {
|
||||
return this.canvas;
|
||||
}
|
||||
|
||||
public set(el) {
|
||||
this.canvas = el;
|
||||
}
|
||||
|
||||
public adjustToWindow() {
|
||||
if (this.canvas) {
|
||||
this.renderer.setStyle(
|
||||
this.canvas,
|
||||
'width',
|
||||
window.innerWidth
|
||||
);
|
||||
this.renderer.setStyle(
|
||||
this.canvas,
|
||||
'height',
|
||||
window.innerHeight
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
75
projects/nls-guilloche/src/lib/services/graph.service.ts
Normal file
75
projects/nls-guilloche/src/lib/services/graph.service.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { Validators } from '@angular/forms';
|
||||
/**
|
||||
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
import { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core';
|
||||
import * as Selection from 'd3-selection';
|
||||
|
||||
import { NlsMathService } from './math.service';
|
||||
import { Graph } from './../models/graph.model';
|
||||
import { Point } from './../models/point.model';
|
||||
|
||||
@Injectable()
|
||||
export class NlsGraphService {
|
||||
private graphs: Graph[];
|
||||
private animation: boolean | null;
|
||||
|
||||
constructor(
|
||||
private math: NlsMathService
|
||||
) {}
|
||||
|
||||
public get() {
|
||||
return this.graphs;
|
||||
}
|
||||
|
||||
public set(newGraphs: Graph[]) {
|
||||
this.graphs = newGraphs;
|
||||
}
|
||||
|
||||
public get isAnimated() {
|
||||
return this.animation;
|
||||
}
|
||||
|
||||
public startAnimation() {
|
||||
this.animation = true;
|
||||
}
|
||||
|
||||
public stopAnimation() {
|
||||
this.animation = false;
|
||||
}
|
||||
|
||||
public *spreadOrthogonal(start: Point, spacing: number) {
|
||||
const sign = this.math.flipSign();
|
||||
let currentPoint = start;
|
||||
let i = 0;
|
||||
|
||||
while (true) {
|
||||
const currentSpacing = sign.next().value * spacing * i;
|
||||
currentPoint = this.shiftPoint(currentPoint, start.ascent, currentSpacing);
|
||||
|
||||
yield currentPoint;
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public shiftPoint(point: Point, radians: number, spacing: number): Point {
|
||||
return {
|
||||
x: Math.sin(radians * Math.PI) * spacing + point.x,
|
||||
y: Math.cos(radians * Math.PI) * spacing + point.y
|
||||
};
|
||||
}
|
||||
}
|
||||
48
projects/nls-guilloche/src/lib/services/history.service.ts
Normal file
48
projects/nls-guilloche/src/lib/services/history.service.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
import { Inject, Injectable, Optional, ViewChild } from '@angular/core';
|
||||
import * as Selection from 'd3-selection';
|
||||
|
||||
import { Graph } from '../models/graph.model';
|
||||
|
||||
@Injectable()
|
||||
export class NlsHistoryService {
|
||||
|
||||
public history: any[];
|
||||
|
||||
constructor() {
|
||||
this.history = [];
|
||||
}
|
||||
|
||||
public save(graphs: Graph[], config) {
|
||||
this.history.push({
|
||||
date: new Date(),
|
||||
graphs: graphs,
|
||||
config: config,
|
||||
hash: this.hash(graphs)
|
||||
});
|
||||
}
|
||||
|
||||
public hash(graphs) {
|
||||
return btoa(JSON.stringify(graphs));
|
||||
}
|
||||
|
||||
public list() {
|
||||
return this.history;
|
||||
}
|
||||
}
|
||||
|
||||
160
projects/nls-guilloche/src/lib/services/math.service.ts
Normal file
160
projects/nls-guilloche/src/lib/services/math.service.ts
Normal file
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* Copyright (C) 2018 Michael Czechowski <mail@dailysh.it>
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import * as Selection from 'd3-selection';
|
||||
import * as Random from 'd3-random';
|
||||
|
||||
import { Point } from './../models/point.model';
|
||||
import { Graph } from './../models/graph.model';
|
||||
|
||||
@Injectable()
|
||||
export class NlsMathService {
|
||||
|
||||
/**
|
||||
* Calculate distance between to points with coordinates.
|
||||
* @param a
|
||||
* @param b
|
||||
*/
|
||||
public Δ(a: Point, b: Point) {
|
||||
return Math.pow(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2), 0.5);
|
||||
}
|
||||
|
||||
public getClosestCenter(point: Point, matrix: any) {
|
||||
if (this.Δ(point, matrix.start) < this.Δ(point, matrix.end)) {
|
||||
return matrix.start;
|
||||
} else {
|
||||
return matrix.end;
|
||||
}
|
||||
}
|
||||
|
||||
public getFarestCenter(point: Point, matrix: any) {
|
||||
if (this.Δ(point, matrix.start) > this.Δ(point, matrix.end)) {
|
||||
return matrix.start;
|
||||
} else {
|
||||
return matrix.end;
|
||||
}
|
||||
}
|
||||
|
||||
public randomPoint(matrix: any, overlap: number) {
|
||||
const x = {
|
||||
min: matrix.center.x - matrix.width * overlap,
|
||||
max: matrix.center.x + matrix.width * overlap
|
||||
};
|
||||
const y = {
|
||||
min: matrix.center.y - matrix.height * overlap,
|
||||
max: matrix.center.y + matrix.height * overlap
|
||||
};
|
||||
|
||||
return {
|
||||
x: Random.randomUniform(x.min, x.max)(),
|
||||
y: Random.randomUniform(y.min, y.max)()
|
||||
};
|
||||
}
|
||||
|
||||
public centerOfArea(width, height): Point {
|
||||
return {
|
||||
x: width * 0.5,
|
||||
y: height * 0.5
|
||||
};
|
||||
}
|
||||
|
||||
public centerOfPoints(p1: Point, p2: Point) {
|
||||
return {
|
||||
x: (p1.x + p2.x) * 0.5,
|
||||
y: (p1.y + p2.y) * 0.5
|
||||
};
|
||||
}
|
||||
|
||||
public centerOfCurve(curve: Point[]) {
|
||||
const genMedian = this.medianPoint(curve);
|
||||
const p1 = genMedian.next().value;
|
||||
const p2 = genMedian.next().value;
|
||||
const radians = this.angleRadians(p1, p2);
|
||||
|
||||
return Object.assign(this.centerOfPoints(p1, p2), { ascent: radians });
|
||||
}
|
||||
|
||||
public medianOfCurve(curve: Point[]) {
|
||||
const genMedian = this.medianPoint(curve);
|
||||
const p1 = genMedian.next().value;
|
||||
const p2 = genMedian.next().value;
|
||||
const p3 = genMedian.next().value;
|
||||
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 });
|
||||
}
|
||||
|
||||
public angleRadians(p1: Point, p2: Point) {
|
||||
return Math.atan2(p2.y - p1.y, p2.x - p1.x);
|
||||
}
|
||||
|
||||
public angleDegree(p1: Point, p2: Point) {
|
||||
return this.angleRadians(p1, p2) * 180 / Math.PI;
|
||||
}
|
||||
|
||||
public medianIndex(list: any): number {
|
||||
return Math.floor(list.length * 0.5);
|
||||
}
|
||||
|
||||
public *medianPoint(points: Point[]) {
|
||||
let index: number;
|
||||
const list: Point[] = points.slice();
|
||||
|
||||
while (list) {
|
||||
index = this.medianIndex(points);
|
||||
yield list[index];
|
||||
|
||||
list.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generator for sine bounce
|
||||
*
|
||||
* @param start 0 indicates to initiate with positive numbers, 1 indicates to
|
||||
* start with negative numbers first
|
||||
* @param amplitude default to 1 indicates the amplitude in positive as well
|
||||
* in negative range
|
||||
* @param decimals amount of decimal places
|
||||
*/
|
||||
|
||||
public *bounce(
|
||||
amplitude: number = 1,
|
||||
decimals: number = 1,
|
||||
start: number = 0
|
||||
) {
|
||||
const power = Math.pow(10, decimals);
|
||||
const step = 2 / (power);
|
||||
let index = 0;
|
||||
|
||||
while (true) {
|
||||
const radians = Math.PI * step * index + start;
|
||||
yield Math.round((Math.sin(radians) * amplitude) * power) / power;
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
public *flipSign(startPositive: boolean = true) {
|
||||
let sign = startPositive ? 1 : -1;
|
||||
|
||||
while (true) {
|
||||
yield sign = sign * (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,13 @@
|
||||
* Public API Surface of nls-guilloche
|
||||
*/
|
||||
|
||||
export * from './lib/nls-guilloche.service';
|
||||
export * from './lib/nls-guilloche.component';
|
||||
export * from './lib/nls-guilloche.module';
|
||||
export * from './lib/directives/guilloche.directive';
|
||||
export * from './lib/models/config.model';
|
||||
export * from './lib/models/graph.model';
|
||||
export * from './lib/models/param.model';
|
||||
export * from './lib/models/point.model';
|
||||
export * from './lib/services/animation.service';
|
||||
export * from './lib/services/canvas.service';
|
||||
export * from './lib/services/graph.service';
|
||||
export * from './lib/services/history.service';
|
||||
export * from './lib/services/math.service';
|
||||
|
||||
Reference in New Issue
Block a user