aboutsummaryrefslogtreecommitdiff
path: root/src/web/component/timeline/index.js
blob: 81322c667d12d5f2ec07b4769426fbfca0b5fc12 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
const container = Z.by_id('container');

function getRandomColor() {
  var letters = '0123456789ABCDEF';
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}

for (let i = 0; i < 10000; ++i) {
	container.appendChild(Z.native('div', {
		innerText: i,
		className: 'image',
		style: {
			background: getRandomColor(),
			aspectRatio: '1 / ' + (Math.random() + 0.5),
		},
	}));
}

const zoom = new (class {
	constructor() {
		this.committed = 5;
		container.style.gridTemplateColumns = `repeat(5, 1fr)`;
		container.classList.toggle('tiling', this.committed != 1);
		this.por = { x: 0, y: 0 };
		this.eor = null;
		this.y_offset = 0;
		this.distance = 0;
	}

	update(distance, point) {
		const scale = distance / this.distance;
		const x = point.x - this.por.x;
		container.style.transform = `translate(${x}px, 0px) scale(${scale})`;
	}

	set reference({ point, distance }) {
		const rect = container.getClientRects()[0];

		this.por = { x: point.x, y: point.y - rect.y };
		container.style.transformOrigin = `${this.por.x}px ${this.por.y}px`;
		this.eor = Z.document.shadowRoot.elementFromPoint(point.x, point.y);

		const box_rect = this.eor.getBoundingClientRect();
		this.y_offset = box_rect.y;

		this.distance = distance;
	}

	commit(distance) {
		const scale = distance / this.distance;
		this.committed = Math.round(Math.min(Math.max(this.committed / scale, 1), 20));
		container.style.gridTemplateColumns = `repeat(${this.committed}, 1fr)`;
		container.classList.toggle('tiling', this.committed != 1);
		container.style.transform = 'scale(1)';

		const rect = this.eor.getBoundingClientRect();

		Z.document.scrollBy({
			top: rect.y - this.y_offset,
			behavior: 'instant',
		});
	}

	increase_line_by(n) {
		this.committed = Math.min(Math.max(this.committed + n, 1), 20);
		container.style.gridTemplateColumns = `repeat(${this.committed}, 1fr)`;
		container.classList.toggle('tiling', this.committed != 1);
		container.style.transform = 'scale(1)';
	}
});

Z.document.onwheel = (event) => {
	if (!event.ctrlKey) {
		return;
	}
	event.preventDefault();
	zoom.increase_line_by(event.wheelDeltaY / 120);
};

const pinch = new Pinch(Z.document);

pinch.onstart = (event) => {
	zoom.reference = event;
};

pinch.onpinch = (event) => {
	zoom.update(event.distance, event.point);
};

pinch.onfinish = (event) => {
	zoom.commit(event.distance);
};