1 | import h from "virtual-dom/h";
|
2 | import { secondsToPixels } from "./utils/conversions";
|
3 | import TimeScaleHook from "./render/TimeScaleHook";
|
4 |
|
5 | class TimeScale {
|
6 | constructor(duration, offset, samplesPerPixel, sampleRate, marginLeft = 0, colors) {
|
7 | this.duration = duration;
|
8 | this.offset = offset;
|
9 | this.samplesPerPixel = samplesPerPixel;
|
10 | this.sampleRate = sampleRate;
|
11 | this.marginLeft = marginLeft;
|
12 | this.colors = colors;
|
13 | this.timeinfo = {
|
14 | 20000: {
|
15 | marker: 30000,
|
16 | bigStep: 10000,
|
17 | smallStep: 5000,
|
18 | secondStep: 5
|
19 | },
|
20 | 12000: {
|
21 | marker: 15000,
|
22 | bigStep: 5000,
|
23 | smallStep: 1000,
|
24 | secondStep: 1
|
25 | },
|
26 | 10000: {
|
27 | marker: 10000,
|
28 | bigStep: 5000,
|
29 | smallStep: 1000,
|
30 | secondStep: 1
|
31 | },
|
32 | 5000: {
|
33 | marker: 5000,
|
34 | bigStep: 1000,
|
35 | smallStep: 500,
|
36 | secondStep: 1 / 2
|
37 | },
|
38 | 2500: {
|
39 | marker: 2000,
|
40 | bigStep: 1000,
|
41 | smallStep: 500,
|
42 | secondStep: 1 / 2
|
43 | },
|
44 | 1500: {
|
45 | marker: 2000,
|
46 | bigStep: 1000,
|
47 | smallStep: 200,
|
48 | secondStep: 1 / 5
|
49 | },
|
50 | 700: {
|
51 | marker: 1000,
|
52 | bigStep: 500,
|
53 | smallStep: 100,
|
54 | secondStep: 1 / 10
|
55 | }
|
56 | };
|
57 | }
|
58 |
|
59 | getScaleInfo(resolution) {
|
60 | let keys = Object.keys(this.timeinfo).map(item => parseInt(item, 10));
|
61 |
|
62 | keys = keys.sort((a, b) => a - b);
|
63 |
|
64 | for (let i = 0; i < keys.length; i += 1) {
|
65 | if (resolution <= keys[i]) {
|
66 | return this.timeinfo[keys[i]];
|
67 | }
|
68 | }
|
69 |
|
70 | return this.timeinfo[keys[0]];
|
71 | }
|
72 | |
73 |
|
74 |
|
75 |
|
76 |
|
77 | static formatTime(milliseconds) {
|
78 | const seconds = milliseconds / 1000;
|
79 | let s = seconds % 60;
|
80 | const m = (seconds - s) / 60;
|
81 |
|
82 | if (s < 10) {
|
83 | s = `0${s}`;
|
84 | }
|
85 |
|
86 | return `${m}:${s}`;
|
87 | }
|
88 |
|
89 | render() {
|
90 | const widthX = secondsToPixels(this.duration, this.samplesPerPixel, this.sampleRate);
|
91 | const pixPerSec = this.sampleRate / this.samplesPerPixel;
|
92 | const pixOffset = secondsToPixels(this.offset, this.samplesPerPixel, this.sampleRate);
|
93 | const scaleInfo = this.getScaleInfo(this.samplesPerPixel);
|
94 | const canvasInfo = {};
|
95 | const timeMarkers = [];
|
96 | const end = widthX + pixOffset;
|
97 | let counter = 0;
|
98 |
|
99 | for (let i = 0; i < end; i += pixPerSec * scaleInfo.secondStep) {
|
100 | const pixIndex = Math.floor(i);
|
101 | const pix = pixIndex - pixOffset;
|
102 |
|
103 | if (pixIndex >= pixOffset) {
|
104 |
|
105 | if (scaleInfo.marker && counter % scaleInfo.marker === 0) {
|
106 | timeMarkers.push(h("div.time", {
|
107 | attributes: {
|
108 | style: `position: absolute; left: ${pix}px;`
|
109 | }
|
110 | }, [TimeScale.formatTime(counter)]));
|
111 | canvasInfo[pix] = 10;
|
112 | } else if (scaleInfo.bigStep && counter % scaleInfo.bigStep === 0) {
|
113 | canvasInfo[pix] = 5;
|
114 | } else if (scaleInfo.smallStep && counter % scaleInfo.smallStep === 0) {
|
115 | canvasInfo[pix] = 2;
|
116 | }
|
117 | }
|
118 |
|
119 | counter += 1000 * scaleInfo.secondStep;
|
120 | }
|
121 |
|
122 | return h("div.playlist-time-scale", {
|
123 | attributes: {
|
124 | style: `position: relative; left: 0; right: 0; margin-left: ${this.marginLeft}px;`
|
125 | }
|
126 | }, [timeMarkers, h("canvas", {
|
127 | attributes: {
|
128 | width: widthX,
|
129 | height: 30,
|
130 | style: "position: absolute; left: 0; right: 0; top: 0; bottom: 0;"
|
131 | },
|
132 | hook: new TimeScaleHook(canvasInfo, this.offset, this.samplesPerPixel, this.duration, this.colors)
|
133 | })]);
|
134 | }
|
135 |
|
136 | }
|
137 |
|
138 | export default TimeScale; |
\ | No newline at end of file |