Skip to content

Commit 8c88887

Browse files
committed
Improve adaptation to different screen and window sizes. Add flick rejection to touch dragging.
1 parent 505d605 commit 8c88887

13 files changed

Lines changed: 86 additions & 204 deletions

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "svc-ng",
3-
"version": "1.4.10",
3+
"version": "1.4.11",
44
"license": "MIT AND GPL-3.0-or-later",
55
"author": "Kerry Shetline <kerry@shetline.com>",
66
"scripts": {

src/app/app.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div class="about-dialog">
33
<img src="/assets/resources/svc_lunar_eclipse.png" alt="lunar eclipse" width="64" height="64">
44
<h2>Sky View Café NP</h2>
5-
Version 1.4.10<br><br>
5+
Version 1.4.11<br><br>
66
Copyright © 2016-2018 Kerry Shetline.
77
</div>
88
</p-dialog>
@@ -56,7 +56,7 @@ <h2>Sky View Café NP</h2>
5656
<button type="button" pButton icon="fas fa-list" label="More..." (click)="moremenu.toggle($event)"></button>
5757
</div>
5858
</div>
59-
<div class="lower-panel flex-container" fxFlex="100%" fxLayout="row" fxLayoutAlign="start stretch" fxLayoutWrap="none" fxLayoutGap="4px">
59+
<div class="lower-panel flex-container" fxFlex="100%" fxLayout="row" fxLayoutAlign="start stretch" fxLayoutGap="4px">
6060
<ks-tab-view fxFlex="1 0 auto" (onChange)="tabChanged($event)" [activeTab]="selectedTab">
6161
<ks-tab header="Sky">
6262
<svc-sky-view></svc-sky-view>

src/app/svc/generic-view.ts

Lines changed: 16 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright © 2017 Kerry Shetline, kerry@shetline.com.
2+
Copyright © 2017-2018 Kerry Shetline, kerry@shetline.com.
33
44
This code is free software: you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@ import {
2626
ASTEROID_BASE, COMET_BASE, EARTH, FIRST_PLANET, HALF_MINUTE, ISkyObserver, LAST_PLANET, NO_MATCH, SkyObserver, SolarSystem,
2727
StarCatalog, UT_to_TDB
2828
} from 'ks-astronomy';
29-
import { abs, ceil, max, Point, sqrt } from 'ks-math';
29+
import { max, Point, sqrt } from 'ks-math';
3030
import { FontMetrics, getFontMetrics, isSafari } from 'ks-util';
3131
import * as _ from 'lodash';
3232
import { KsDateTime } from 'ks-date-time-zone';
@@ -36,8 +36,7 @@ import { Subscription, BehaviorSubject, Observable } from 'rxjs';
3636
export const PROPERTY_ADDITIONALS = 'additionals';
3737
export enum ADDITIONALS {NONE, ALL_ASTEROIDS, ALL_COMETS, ALL}
3838

39-
const MAX_RESIZE_TOLERANCE = 4;
40-
const MAX_RESIZE_CYCLES = 3;
39+
const FLICK_REJECTION_THRESHOLD = 250;
4140

4241
export interface DrawingContext {
4342
context: CanvasRenderingContext2D;
@@ -78,8 +77,9 @@ export abstract class GenericView implements AfterViewInit {
7877
protected canTouchZoom = false;
7978
protected initialZoomSpread = 0; // 0 means not zooming.
8079
protected goodDragStart = false;
80+
protected dragStartTime = 0;
8181
protected throttledRedraw: () => void;
82-
protected debouncedResize: () => void;
82+
protected throttledResize: () => void;
8383
protected dragging = false;
8484
protected excludedPlanets: number[] = [EARTH];
8585
protected isSafari = false;
@@ -88,10 +88,6 @@ export abstract class GenericView implements AfterViewInit {
8888
protected lastDrawingContext: DrawingContext;
8989
protected planetsToDraw: number[] = [];
9090
protected additional: ADDITIONALS | string = ADDITIONALS.NONE;
91-
protected waitingForResizeToSettle = false;
92-
protected resizeTolerance = 0;
93-
protected lastSizeDiff = 0;
94-
protected resizeCycles = 0;
9591

9692
protected sanitizedHandCursor: SafeStyle;
9793
protected sanitizedLabelCrosshair: SafeStyle;
@@ -130,6 +126,10 @@ export abstract class GenericView implements AfterViewInit {
130126
this.draw();
131127
}, 100);
132128

129+
this.throttledResize = _.throttle(() => {
130+
this.doResize();
131+
}, 100);
132+
133133
appService.getCurrentTabUpdates((currentTab: CurrentTab) => {
134134
if (this.tabId === currentTab)
135135
setTimeout(() => this.onResize());
@@ -158,64 +158,17 @@ export abstract class GenericView implements AfterViewInit {
158158
}
159159

160160
onResize(): void {
161-
this.waitingForResizeToSettle = false;
162-
this.resizeCycles = 0;
163-
this.onResizeAux();
164-
}
165-
166-
protected onResizeAux(): void {
167-
if (!this.debouncedResize) {
168-
this.debouncedResize = _.debounce(() => {
169-
this.doResize();
170-
171-
setTimeout(() => {
172-
// Ideally this.wrapper.clientWidth and this.canvas.clientWidth are equal after resizing,
173-
// but in Firefox (and possibly other browsers) they don't match exactly even after an extra
174-
// cycle of resizing. Below we try to dynamically figure out how much tolerance in width
175-
// difference to allow for.
176-
const sizeDiff = abs(this.wrapper.clientWidth - this.canvas.clientWidth);
177-
let resizeAgain = true;
178-
179-
if (sizeDiff > this.resizeTolerance) {
180-
if (this.waitingForResizeToSettle && sizeDiff <= MAX_RESIZE_TOLERANCE) {
181-
if (sizeDiff === this.lastSizeDiff) {
182-
if (++this.resizeCycles === MAX_RESIZE_CYCLES) {
183-
this.resizeTolerance = sizeDiff;
184-
resizeAgain = false;
185-
this.waitingForResizeToSettle = false;
186-
}
187-
}
188-
else
189-
this.resizeCycles = 0;
190-
}
191-
192-
this.lastSizeDiff = sizeDiff;
193-
194-
if (resizeAgain) {
195-
this.waitingForResizeToSettle = true;
196-
this.onResizeAux();
197-
}
198-
}
199-
}, 50);
200-
}, 50);
201-
}
202-
203161
this.marqueeText = '';
204-
this.debouncedResize();
162+
this.throttledResize();
205163
}
206164

207165
private doResize(): void {
208-
const top = ceil(this.canvas.getBoundingClientRect().top);
209-
const marqueeHeight = this.marquee.getBoundingClientRect().height;
210-
211166
this.width = this.wrapper.clientWidth;
212-
// Using the document's clientHeight instead of the window's innerHeight accounts for possible scroll bar.
213-
this.height = max(window.document.documentElement.clientHeight - top - marqueeHeight - 12, 250);
214-
167+
this.height = this.wrapper.clientHeight;
215168
this.canvas.width = this.width;
216169
this.canvas.height = this.height;
217170
this.canvas.style.height = this.height + 'px';
218-
this.wrapper.style.height = this.height + 'px';
171+
this.canvas.style.height = this.height + 'px';
219172

220173
this.draw();
221174
}
@@ -249,6 +202,7 @@ export abstract class GenericView implements AfterViewInit {
249202

250203
if (this.isInsideView()) {
251204
this.goodDragStart = true;
205+
this.dragStartTime = performance.now();
252206
this.draw();
253207
event.preventDefault();
254208

@@ -275,6 +229,7 @@ export abstract class GenericView implements AfterViewInit {
275229
}
276230

277231
onTouchMove(event: TouchEvent): void {
232+
const notAFlick = performance.now() > this.dragStartTime + FLICK_REJECTION_THRESHOLD;
278233
const pt0 = this.getXYForTouchEvent(event);
279234
const pt = _.clone(pt0);
280235
let pt1;
@@ -285,7 +240,7 @@ export abstract class GenericView implements AfterViewInit {
285240
pt.y = (pt0.y + pt1.y) / 2;
286241
}
287242

288-
if (this.goodDragStart)
243+
if (this.goodDragStart && notAFlick && event.touches.length === 1 || this.canTouchZoom)
289244
this.handleMouseMove(pt.x, pt.y, true);
290245

291246
if (this.initialZoomSpread) {
@@ -301,7 +256,7 @@ export abstract class GenericView implements AfterViewInit {
301256
this.initialZoomSpread = 0;
302257
}
303258

304-
if (this.isInsideView())
259+
if (this.isInsideView() && notAFlick)
305260
event.preventDefault();
306261
}
307262

@@ -352,8 +307,6 @@ export abstract class GenericView implements AfterViewInit {
352307
if (event.touches.length === 1)
353308
this.onTouchStart(event);
354309
else if (event.touches.length === 0) {
355-
this.resetCursor();
356-
this.draw();
357310
this.dragging = false;
358311
event.preventDefault();
359312
}

src/app/svc/svc-calendar-view/svc-calendar-view.component.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
:host {
22
display: flex;
3-
height: 100%;
3+
height: calc(100% - 2px);
44
flex-direction: column;
55
justify-content: space-between;
66
align-items: stretch;

src/app/svc/svc-calendar-view/svc-calendar-view.component.ts

Lines changed: 10 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import {
3232
VISIBLE_ALL_DAY, WINTER_SOLSTICE
3333
} from 'ks-astronomy';
3434
import { DatePipe } from '@angular/common';
35-
import { abs, ceil, floor, max, min, round } from 'ks-math';
35+
import { ceil, floor, max, min, round } from 'ks-math';
3636
import { isEdge, isFirefox, isIE } from 'ks-util';
3737
import * as _ from 'lodash';
3838
import { MoonDrawer } from '../moon-drawer';
@@ -52,9 +52,6 @@ const MIN_MOON_IMAGE_SIZE = 32;
5252

5353
const DAY_HIGHLIGHT = '#000044';
5454

55-
const MAX_RESIZE_TOLERANCE = 4;
56-
const MAX_RESIZE_CYCLES = 3;
57-
5855
interface TextAndTime {
5956
text: string;
6057
time: number;
@@ -110,13 +107,9 @@ export class SvcCalendarViewComponent implements AfterViewInit {
110107
private equisolstice = true;
111108
private dailyMoonPhase = true;
112109
private dailyDaylight = true;
113-
private debouncedResize: () => void;
110+
private throttledResize: () => void;
114111
private eventFinder = new EventFinder();
115112
private moonDrawer: MoonDrawer;
116-
protected waitingForResizeToSettle = false;
117-
protected resizeTolerance = 0;
118-
protected lastSizeDiff = 0;
119-
protected resizeCycles = 0;
120113

121114
private eventTypes: EventType[] = [
122115
{planet: SUN, altitude: 0},
@@ -153,6 +146,10 @@ export class SvcCalendarViewComponent implements AfterViewInit {
153146
// TODO: Call method below whenever first day of week changes.
154147
this.updateDayHeadings();
155148

149+
this.throttledResize = _.throttle(() => {
150+
this.doResize();
151+
}, 100);
152+
156153
appService.getCurrentTabUpdates((currentTab: CurrentTab) => {
157154
if (currentTab === CurrentTab.CALENDAR) {
158155
setTimeout(() => {
@@ -226,65 +223,20 @@ export class SvcCalendarViewComponent implements AfterViewInit {
226223
}
227224

228225
onResize(): void {
229-
this.waitingForResizeToSettle = false;
230-
this.resizeCycles = 0;
231-
this.onResizeAux();
232-
}
233-
234-
protected onResizeAux(): void {
235-
if (!this.debouncedResize) {
236-
this.debouncedResize = _.debounce(() => {
237-
this.doResize();
238-
239-
setTimeout(() => {
240-
// Ideally this.wrapper.clientWidth and this.canvas.clientWidth are equal after resizing,
241-
// but in Firefox (and possibly other browsers) they don't match exactly even after an extra
242-
// cycle of resizing. Below we try to dynamically figure out how much tolerance in width
243-
// difference to allow for.
244-
const sizeDiff = abs(this.wrapper.clientWidth - this.canvas.clientWidth);
245-
let resizeAgain = true;
246-
247-
if (sizeDiff > this.resizeTolerance) {
248-
if (this.waitingForResizeToSettle && sizeDiff <= MAX_RESIZE_TOLERANCE) {
249-
if (sizeDiff === this.lastSizeDiff) {
250-
if (++this.resizeCycles === MAX_RESIZE_CYCLES) {
251-
this.resizeTolerance = sizeDiff;
252-
resizeAgain = false;
253-
this.waitingForResizeToSettle = false;
254-
}
255-
}
256-
else
257-
this.resizeCycles = 0;
258-
}
259-
260-
this.lastSizeDiff = sizeDiff;
261-
262-
if (resizeAgain) {
263-
this.waitingForResizeToSettle = true;
264-
this.onResizeAux();
265-
}
266-
}
267-
}, 50);
268-
}, 50);
269-
}
270-
271-
this.debouncedResize();
226+
this.throttledResize();
272227
}
273228

274229
private doResize(): void {
275-
const top = ceil(this.wrapper.getBoundingClientRect().top);
276-
277230
this.width = this.wrapper.clientWidth;
278-
// Using the document's clientHeight instead of the window's innerHeight accounts for possible scroll bar.
279-
this.height = max(window.document.documentElement.clientHeight - top - 5, 250);
231+
this.height = this.wrapper.clientHeight;
280232
this.dayTop = (<HTMLElement> (this.titleRowRef.nativeElement)).clientHeight + (<HTMLElement> (this.weekdaysRowRef.nativeElement)).clientHeight;
281233

282234
this.canvas.width = this.width;
283235
this.canvas.height = this.height;
284-
this.wrapper.style.height = this.height + 'px';
285236
this.canvas.style.height = this.height + 'px';
237+
this.canvas.style.height = this.height + 'px';
238+
this.calendarTable.style.height = this.height + 'px';
286239
this.calendarTable.style.height = this.height + 'px';
287-
this.wrapper.style.height = this.height + 'px';
288240

289241
this.draw();
290242
}

src/app/svc/svc-orbit-view/svc-orbit-view.component.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,9 @@ export class SvcOrbitViewComponent extends GenericPlanetaryView implements After
546546

547547
onTouchMove(event: TouchEvent): void {
548548
super.onTouchMove(event);
549-
this.continueDrag(event.shiftKey);
549+
550+
if (event.defaultPrevented)
551+
this.continueDrag(event.shiftKey);
550552
}
551553

552554
onMouseMove(event: MouseEvent): void {
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<!--suppress XmlUnboundNsPrefix -->
22
<div class="table-controls">
3-
<p-dropdown #tableTypesDropdown [options]="tableTypes" [(ngModel)]="tableType" [autoWidth]="true"></p-dropdown>
3+
<p-dropdown #tableTypesDropdown [options]="tableTypes" [(ngModel)]="tableType" [autoWidth]="true"></p-dropdown>&nbsp;&nbsp;
44
<p-dropdown #planetsDropdown [options]="planetChoices" [(ngModel)]="planetChoice" [autoWidth]="true" [disabled]="!planetChoiceEnabled"></p-dropdown>
55
</div>
66
<div #wrapper class="wrapper" (window:resize)="onResize()">
7-
<div #tableContainer class="table-container" [innerHtml]='tableHtml'></div>
8-
</div>
7+
<div #tableContainer class="table-container" [innerHtml]='tableHtml'>&nbsp;</div>
8+
</div>

src/app/svc/svc-table-view/svc-table-view.component.scss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@
77
}
88

99
div.wrapper {
10+
position: relative;
1011
flex-grow: 1;
1112
}
1213

1314
.table-container {
14-
width: auto;
15+
position: absolute;
16+
left: 0;
17+
top: 0;
1518
overflow: auto;
19+
white-space: nowrap;
1620
}
1721

1822
.table-controls {

0 commit comments

Comments
 (0)