diff --git a/package-lock.json b/package-lock.json index 9a7495f..96d748c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svc-ng", - "version": "1.4.13", + "version": "1.4.14", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 6698249..98f678f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "svc-ng", - "version": "1.4.13", + "version": "1.4.14", "license": "MIT AND GPL-3.0-or-later", "author": "Kerry Shetline ", "scripts": { diff --git a/src/app/app.component.html b/src/app/app.component.html index 37cf72d..8a3d400 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -2,7 +2,7 @@
lunar eclipse

Sky View Café NP

- Version 1.4.13

+ Version 1.4.14

Copyright © 2016-2018 Kerry Shetline.
diff --git a/src/app/svc/generic-view.ts b/src/app/svc/generic-view.ts index 8503fcf..e85a09e 100644 --- a/src/app/svc/generic-view.ts +++ b/src/app/svc/generic-view.ts @@ -20,19 +20,20 @@ other uses are restricted. */ -import { AfterViewInit } from '@angular/core'; +import { AfterViewInit, ElementRef, ViewChild } from '@angular/core'; import { AppService, CurrentTab } from '../app.service'; import { ASTEROID_BASE, COMET_BASE, EARTH, FIRST_PLANET, HALF_MINUTE, ISkyObserver, LAST_PLANET, NO_MATCH, SkyObserver, SolarSystem, StarCatalog, UT_to_TDB } from 'ks-astronomy'; import { ceil, max, round, sqrt } from 'ks-math'; -import { FontMetrics, getFontMetrics, isSafari } from 'ks-util'; +import { FontMetrics, getFontMetrics, isSafari, padLeft } from 'ks-util'; import * as _ from 'lodash'; import { KsDateTime } from 'ks-date-time-zone'; import { SafeStyle } from '@angular/platform-browser'; import { Subscription, BehaviorSubject, Observable } from 'rxjs'; import { getXYForTouchEvent } from '../util/ks-touch-events'; +import { KsMarqueeComponent } from '../widgets/ks-marquee/ks-marquee.component'; export const PROPERTY_ADDITIONALS = 'additionals'; export enum ADDITIONALS {NONE, ALL_ASTEROIDS, ALL_COMETS, ALL} @@ -69,6 +70,9 @@ export abstract class GenericView implements AfterViewInit { protected wrapper: HTMLDivElement; protected canvas: HTMLCanvasElement; + protected marquee: HTMLElement; + protected lastMarqueeClick = 0; + protected marqueeClickCount = 0; protected canvasScaling = 1; protected touchGuard: HTMLDivElement; protected lastWidth = -1; @@ -99,6 +103,10 @@ export abstract class GenericView implements AfterViewInit { protected planetsToDraw: number[] = []; protected additional: ADDITIONALS | string = ADDITIONALS.NONE; + protected showMetrics = false; + protected lastDrawStart = 0; + protected lastFullDrawTime: number; + protected sanitizedHandCursor: SafeStyle; protected sanitizedLabelCrosshair: SafeStyle; @@ -106,6 +114,8 @@ export abstract class GenericView implements AfterViewInit { protected readonly mediumLabelFont = '11px Arial, Helvetica, sans-serif'; protected readonly smallLabelFont = '10px Arial, Helvetica, sans-serif'; + @ViewChild(KsMarqueeComponent, {read: ElementRef}) protected marqueeRef: ElementRef; + public marqueeText = ''; cursor: SafeStyle; @@ -184,6 +194,47 @@ export abstract class GenericView implements AfterViewInit { GenericView.getPrintingUpdate(printing => { this.doResize(printing); }); + + if (this.marqueeRef) { + this.marquee = this.marqueeRef.nativeElement as HTMLElement; + this.marquee.addEventListener('click', event => this.marqueeClick(event)); + this.marquee.addEventListener('touchstart', event => this.marqueeTouch(event)); + } + } + + private marqueeClick(event: MouseEvent): void { + if (event.detail === 3) + this.toggleMarqueeMetrics(); + else if (event.detail === 0 || event.detail === undefined) + this.countMarqueeClicks(); + } + + private marqueeTouch(event: TouchEvent): void { + if (event.touches.length > 2) + this.toggleMarqueeMetrics(); + else if (event.touches.length === 1) + this.countMarqueeClicks(); + } + + private countMarqueeClicks(): void { + const now = performance.now(); + + if (now > this.lastMarqueeClick + 500) + this.marqueeClickCount = 1; + else if (++this.marqueeClickCount === 3) + this.toggleMarqueeMetrics(); + + this.lastMarqueeClick = now; + } + + private toggleMarqueeMetrics(): void { + const saveBackground = this.marquee.style.backgroundColor; + + this.showMetrics = !this.showMetrics; + this.marqueeText = ''; + this.clearMouseHighlighting(); + this.marquee.style.backgroundColor = 'cyan'; + setTimeout(() => this.marquee.style.backgroundColor = saveBackground, 500); } onResize(): void { @@ -410,14 +461,15 @@ export abstract class GenericView implements AfterViewInit { this.lastDrawingContext = dc; const now = performance.now(); + const drawingTime = now - startTime; if (dc.fullDraw) { - const fullDrawingTime = now - startTime; + this.lastFullDrawTime = max(drawingTime, 1); if (forceFullDraw) this.slowFrameCount = 0; - if (fullDrawingTime > SLOW_DRAWING_THRESHOLD) { + if (this.lastFullDrawTime > SLOW_DRAWING_THRESHOLD) { ++this.slowFrameCount; this.lastSlowFrameTime = now; } @@ -426,6 +478,18 @@ export abstract class GenericView implements AfterViewInit { this.debouncedFullRedraw(); this.lastSlowFrameTime = now; } + + if (this.showMetrics) { + const interval = max(startTime - this.lastDrawStart, 1); + + this.marqueeText = padLeft(drawingTime.toFixed(1), 6, '\u2007') + (dc.fullDraw ? 'F' : 'Q') + ', ' + + padLeft(interval.toFixed(1), 6, '\u2007'); + + if (!dc.fullDraw) + this.marqueeText += ', ' + padLeft(this.lastFullDrawTime.toFixed(1), 6, '\u2007') + 'F'; + } + + this.lastDrawStart = startTime; } protected additionalDrawingSetup(dc: DrawingContext): void { diff --git a/src/app/svc/svc-orbit-view/svc-orbit-view.component.ts b/src/app/svc/svc-orbit-view/svc-orbit-view.component.ts index f9b6852..34009d2 100644 --- a/src/app/svc/svc-orbit-view/svc-orbit-view.component.ts +++ b/src/app/svc/svc-orbit-view/svc-orbit-view.component.ts @@ -74,7 +74,6 @@ const EYE_OFFSET_DIVISOR = 30.0; const MARKER_SIZE = 9; const MARKER_SIZE2 = floor(MARKER_SIZE / 2); -const MARKER_GAP = 2; const DRAG_LOCK_DELTA = 5; @@ -277,6 +276,9 @@ export class SvcOrbitViewComponent extends GenericPlanetaryView implements After let colorIndex = planet; if (SolarSystem.isAsteroidOrComet(planet)) { + if (!dc.fullDraw) + continue; + // Don't use this orbit drawing method for highly eccentric asteroids and comets. if (!oe || oe.e > 0.98) { specialCases.push(planet); diff --git a/src/app/widgets/ks-sequence-editor/ks-sequence-editor.component.ts b/src/app/widgets/ks-sequence-editor/ks-sequence-editor.component.ts index 40dc34c..87ac111 100644 --- a/src/app/widgets/ks-sequence-editor/ks-sequence-editor.component.ts +++ b/src/app/widgets/ks-sequence-editor/ks-sequence-editor.component.ts @@ -87,6 +87,7 @@ export class KsSequenceEditorComponent implements AfterViewInit, OnInit, OnDestr private static useHiddenInput = isAndroid(); private static addFocusOutline = isEdge() || isIE() || isIOS(); private static checkForRepeatedKeyTimestamps = isIOS(); + private static disableContentEditable = isEdge() || isIE(); private keyTimer: Subscription; private clickTimer: Subscription; @@ -228,6 +229,9 @@ export class KsSequenceEditorComponent implements AfterViewInit, OnInit, OnDestr this.canvas.setAttribute('tabindex', '-1'); } + if (KsSequenceEditorComponent.disableContentEditable) + this.canvas.contentEditable = 'false'; + this.computeSize(); this.draw(); } diff --git a/src/assets/about.html b/src/assets/about.html index 529c9dd..d1e208d 100644 --- a/src/assets/about.html +++ b/src/assets/about.html @@ -60,6 +60,8 @@

What's New / Version History

+

1.4.14, 2018-08-14: Added quick drawing mode for Orbits view. Added speed metrics.

+

1.4.13, 2018-08-13: Increased graphics resolution for high resolution displays. Added quick, lower-resolution drawing mode for slow devices. Added three-finger gesture for escaping "zoom traps".