@documental-xyz/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +424 -0
- package/integration.ts +113 -0
- package/package.json +83 -0
- package/src/admin/admin.astro +29 -0
- package/src/assets/scripts/App.js +70 -0
- package/src/assets/scripts/EnteringAnimations.js +34 -0
- package/src/assets/scripts/MapBoxHandler.js +680 -0
- package/src/assets/scripts/ScrollProgressionBar.js +24 -0
- package/src/assets/scripts/utils/ScrollObserver.js +166 -0
- package/src/assets/styles/config/_breakpoints.scss +37 -0
- package/src/assets/styles/config/_colors.scss +8 -0
- package/src/assets/styles/config/_config.scss +5 -0
- package/src/assets/styles/config/_functions.scss +90 -0
- package/src/assets/styles/config/_grrr.configs.scss +7 -0
- package/src/assets/styles/config/_mixins.scss +207 -0
- package/src/assets/styles/config/_type.scss +175 -0
- package/src/assets/styles/config/_vars.scss +16 -0
- package/src/assets/styles/globals/_content.scss +47 -0
- package/src/assets/styles/globals/_grrr.scss +18 -0
- package/src/assets/styles/globals/_html.scss +25 -0
- package/src/assets/styles/globals/_lists.scss +19 -0
- package/src/assets/styles/globals/_map-anchors.scss +32 -0
- package/src/assets/styles/globals/_reset.scss +240 -0
- package/src/assets/styles/globals/_reveal-animations.scss +104 -0
- package/src/assets/styles/globals/_root.scss +6 -0
- package/src/assets/styles/globals/_scroll-progression-bar.scss +8 -0
- package/src/assets/styles/main.scss +17 -0
- package/src/assets/styles/utils/.gitkeep +0 -0
- package/src/assets/styles/utils/grrr/_grrr.scss +433 -0
- package/src/assets/styles/utils/list-styles/_list-styles.scss +190 -0
- package/src/components/AnimationToggle.astro +19 -0
- package/src/components/BigNumbers.astro +83 -0
- package/src/components/Button.astro +49 -0
- package/src/components/Caption.astro +15 -0
- package/src/components/Card.astro +68 -0
- package/src/components/Cards.astro +66 -0
- package/src/components/CardsCall.astro +125 -0
- package/src/components/ChartBar.astro +217 -0
- package/src/components/ChartPercentage.astro +137 -0
- package/src/components/Column.astro +54 -0
- package/src/components/ColumnSticky.astro +129 -0
- package/src/components/Columns.astro +139 -0
- package/src/components/Compare.astro +266 -0
- package/src/components/Cta.astro +242 -0
- package/src/components/Gallery.astro +594 -0
- package/src/components/Group.astro +140 -0
- package/src/components/HtmlEmbed.astro +98 -0
- package/src/components/ImageBlock.astro +134 -0
- package/src/components/InnerColumns.astro +54 -0
- package/src/components/LogosGroup.astro +102 -0
- package/src/components/Map.astro +321 -0
- package/src/components/MapBox.astro +96 -0
- package/src/components/MapView.astro +30 -0
- package/src/components/Menu.astro +278 -0
- package/src/components/Pullquote.astro +46 -0
- package/src/components/Slider.astro +223 -0
- package/src/components/Spacer.astro +25 -0
- package/src/components/Text.astro +173 -0
- package/src/components/TextPlaceholder.astro +98 -0
- package/src/components/Timeline.astro +73 -0
- package/src/components/TimelineBullet.astro +67 -0
- package/src/components/VideoEmbed.astro +99 -0
- package/src/content/loader.ts +29 -0
- package/src/content/pages/alter-ameacada.md +80 -0
- package/src/content/pages/expulsions.md +1447 -0
- package/src/content/pages/home.md +346 -0
- package/src/content/pages/nhanderekoa-studio-autonoma.md +3113 -0
- package/src/content/pages/nhanderekoa-terra-ind/303/255gena-jaragu/303/241.md +3806 -0
- package/src/content/pages/nova-landing-page.md +546 -0
- package/src/content/pages/territ/303/263rios-de-exce/303/247/303/243o.md +2199 -0
- package/src/content/pages/teste-alter-do-chao.md +955 -0
- package/src/content/pages/teste-layout.md +1484 -0
- package/src/content/pages/thiago.md +93 -0
- package/src/content/schema/blog.ts +11 -0
- package/src/content/schema/geostorys.ts +13 -0
- package/src/content/schema/index.ts +3 -0
- package/src/content/schema/pages.ts +494 -0
- package/src/content.config.ts +49 -0
- package/src/env.d.ts +1 -0
- package/src/integration/override-aliases.ts +67 -0
- package/src/layouts/components/ButtonLayout.astro +8 -0
- package/src/layouts/components/CardLayout.astro +8 -0
- package/src/layouts/components/CardsCallLayout.astro +26 -0
- package/src/layouts/components/CardsLayout.astro +14 -0
- package/src/layouts/components/ChartBarLayout.astro +21 -0
- package/src/layouts/components/ChartPercentageLayout.astro +17 -0
- package/src/layouts/components/ColumnLayout.astro +11 -0
- package/src/layouts/components/ColumnStickyLayout.astro +10 -0
- package/src/layouts/components/ColumnsLayout.astro +13 -0
- package/src/layouts/components/CompareLayout.astro +22 -0
- package/src/layouts/components/CtaLayout.astro +91 -0
- package/src/layouts/components/GalleryLayout.astro +24 -0
- package/src/layouts/components/GroupLayout.astro +53 -0
- package/src/layouts/components/HtmlEmbedLayout.astro +18 -0
- package/src/layouts/components/ImageBlockLayout.astro +20 -0
- package/src/layouts/components/InnerColumnsLayout.astro +14 -0
- package/src/layouts/components/LogosGroupLayout.astro +22 -0
- package/src/layouts/components/MapLayout.astro +41 -0
- package/src/layouts/components/MapViewLayout.astro +8 -0
- package/src/layouts/components/MapboxLayout.astro +248 -0
- package/src/layouts/components/PullquoteLayout.astro +13 -0
- package/src/layouts/components/SliderLayout.astro +18 -0
- package/src/layouts/components/SpacerLayout.astro +8 -0
- package/src/layouts/components/TextLayout.astro +17 -0
- package/src/layouts/components/TextPlaceholderLayout.astro +7 -0
- package/src/layouts/components/TimelineBulletLayout.astro +14 -0
- package/src/layouts/components/TimelineLayout.astro +10 -0
- package/src/layouts/components/VideoEmbedLayout.astro +28 -0
- package/src/layouts/pages/Layout.astro +90 -0
- package/src/layouts/pages/PageLayout.astro +200 -0
- package/src/lib/collections.ts +1 -0
- package/src/routes/[slug].astro +17 -0
- package/src/routes/index.astro +5 -0
- package/src/vite/yaml-merge-plugin.ts +234 -0
|
@@ -0,0 +1,680 @@
|
|
|
1
|
+
export default class MapBoxHandler {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.transitionScreenPoint = 75;
|
|
4
|
+
this.transitionScreenPointMobile = 65;
|
|
5
|
+
this.mapMobileHeight = 52;
|
|
6
|
+
this.mobileBreakPoint = 992;
|
|
7
|
+
|
|
8
|
+
this.sels = {
|
|
9
|
+
triggers: '[data-map-view]',
|
|
10
|
+
triggersClass: '.map-view',
|
|
11
|
+
anchors: '[data-map-anchor]',
|
|
12
|
+
anchorsHolder: '#map-anchors',
|
|
13
|
+
mapWindows: '.map',
|
|
14
|
+
mapContent: '.map__holder',
|
|
15
|
+
mapFloating: '.map--floating-text',
|
|
16
|
+
mainMap: '#mapbox',
|
|
17
|
+
cloneMap: '#mapbox-clone div',
|
|
18
|
+
captions: '#captions',
|
|
19
|
+
};
|
|
20
|
+
this.labels = {
|
|
21
|
+
displacer: '__displacer__',
|
|
22
|
+
initView: '__initview__',
|
|
23
|
+
};
|
|
24
|
+
this.refs = {
|
|
25
|
+
anchorId: (id = false) =>
|
|
26
|
+
id ? `[data-map-anchor-id="${id}"]` : 'data-map-anchor-id',
|
|
27
|
+
anchorView: (id = false) =>
|
|
28
|
+
id ? `[data-map-anchor="${id}"]` : 'data-map-anchor',
|
|
29
|
+
triggerRef: (id = false) =>
|
|
30
|
+
id ? `[data-ref-id="${id}"]` : 'data-ref-id',
|
|
31
|
+
triggerView: (id = false) =>
|
|
32
|
+
id ? `[data-map-view="${id}"]` : 'data-map-view',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
window.addEventListener('DOMContentLoaded', this.init.bind(this));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async init() {
|
|
39
|
+
this.mapWindows = document.querySelectorAll(this.sels.mapWindows);
|
|
40
|
+
|
|
41
|
+
if (
|
|
42
|
+
typeof window.mapConfig !== 'object' ||
|
|
43
|
+
!window.mapBoxToken ||
|
|
44
|
+
!this.mapWindows.length
|
|
45
|
+
)
|
|
46
|
+
return;
|
|
47
|
+
|
|
48
|
+
this.views = typeof window.mapViews === 'object' ? window.mapViews : false;
|
|
49
|
+
this.views &&
|
|
50
|
+
Object.keys(this.views).forEach((k) => (this.views[k].id = k));
|
|
51
|
+
this.mapAnchors = [];
|
|
52
|
+
this.definedLayers = [...window.mapConfig.layers];
|
|
53
|
+
|
|
54
|
+
const { style, ...initView } = window.mapConfig;
|
|
55
|
+
this.initView = {
|
|
56
|
+
...initView,
|
|
57
|
+
id: this.labels.initView,
|
|
58
|
+
duration: this.views && Object.values(this.views)[0].duration,
|
|
59
|
+
};
|
|
60
|
+
this.currentView = initView;
|
|
61
|
+
|
|
62
|
+
this.mapHolder = document.querySelector(this.sels.mainMap);
|
|
63
|
+
this.mapHolderClone = document.querySelector(this.sels.cloneMap);
|
|
64
|
+
|
|
65
|
+
this.captionHolder = document.createElement('div');
|
|
66
|
+
this.captionHolder.setAttribute('id', this.sels.captions.replace('#', ''));
|
|
67
|
+
|
|
68
|
+
this.viewObserver = null;
|
|
69
|
+
this.map = null;
|
|
70
|
+
this.mapClone = null;
|
|
71
|
+
this.originalFilters = {};
|
|
72
|
+
|
|
73
|
+
this.countIntersectionEvents = 0;
|
|
74
|
+
|
|
75
|
+
await this.initViewAnchors();
|
|
76
|
+
await this.initMaps();
|
|
77
|
+
this.map.on('load', this.mapsOnLoad.bind(this));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async initViewAnchors() {
|
|
81
|
+
await this.setMapWindowDisplacers();
|
|
82
|
+
await this.setMapAnchors();
|
|
83
|
+
|
|
84
|
+
const resizeObserver = new ResizeObserver(
|
|
85
|
+
this.setPosToMapAnchors.bind(this)
|
|
86
|
+
);
|
|
87
|
+
resizeObserver.observe(document.body);
|
|
88
|
+
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async initMaps() {
|
|
93
|
+
mapboxgl.accessToken = window.mapBoxToken;
|
|
94
|
+
this.map = new mapboxgl.Map({
|
|
95
|
+
container: this.mapHolder,
|
|
96
|
+
...window.mapConfig,
|
|
97
|
+
});
|
|
98
|
+
if (this.getHistoryType() !== 'floating') {
|
|
99
|
+
this.mapClone = new mapboxgl.Map({
|
|
100
|
+
container: this.mapHolderClone,
|
|
101
|
+
...window.mapConfig,
|
|
102
|
+
});
|
|
103
|
+
} else {
|
|
104
|
+
this.mapHolderClone.remove();
|
|
105
|
+
this.mapHolderClone = false;
|
|
106
|
+
}
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async mapsOnLoad() {
|
|
111
|
+
this.mapHolder.style.opacity = 1;
|
|
112
|
+
this.mapHolderClone && (this.mapHolderClone.style.opacity = 1);
|
|
113
|
+
this.storeOriginalFilters();
|
|
114
|
+
this.defineLayers();
|
|
115
|
+
this.displayLayers(this.initView.layers, true);
|
|
116
|
+
this.adjustFirstViewOnLoad();
|
|
117
|
+
const resizeObserverView = new ResizeObserver(
|
|
118
|
+
this.observeView.bind(
|
|
119
|
+
this,
|
|
120
|
+
this.mapAnchors,
|
|
121
|
+
this.changeViewByEl.bind(this)
|
|
122
|
+
)
|
|
123
|
+
);
|
|
124
|
+
resizeObserverView.observe(document.body);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
storeOriginalFilters() {
|
|
128
|
+
const style = this.map.getStyle();
|
|
129
|
+
style.layers.forEach(layer => {
|
|
130
|
+
if (layer.filter) {
|
|
131
|
+
this.originalFilters[layer.id] = layer.filter;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
getOriginalLayerFilter(layerName) {
|
|
137
|
+
return this.originalFilters[layerName] || null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* Anchors & Observers */
|
|
141
|
+
|
|
142
|
+
async setMapAnchors() {
|
|
143
|
+
this.mapTriggers = document.querySelectorAll(this.sels.triggers);
|
|
144
|
+
const container = document.createElement('div');
|
|
145
|
+
container.setAttribute('id', this.sels.anchorsHolder.replace('#', ''));
|
|
146
|
+
container.setAttribute('aria-hidden', true);
|
|
147
|
+
container.style.position = 'absolute';
|
|
148
|
+
container.style.inset = 0;
|
|
149
|
+
container.style.zIndex = 9999;
|
|
150
|
+
container.style.pointerEvents = 'none';
|
|
151
|
+
this.mapTriggers &&
|
|
152
|
+
this.mapTriggers.forEach((el, i) => {
|
|
153
|
+
const anchor = document.createElement('div');
|
|
154
|
+
el.setAttribute(this.refs.triggerRef(), i);
|
|
155
|
+
anchor.setAttribute(this.refs.anchorId(), i);
|
|
156
|
+
anchor.setAttribute(
|
|
157
|
+
this.refs.anchorView(),
|
|
158
|
+
el.getAttribute(this.refs.triggerView())
|
|
159
|
+
);
|
|
160
|
+
i % 2 === 0 && anchor.classList.add('odd');
|
|
161
|
+
container.appendChild(anchor);
|
|
162
|
+
this.mapAnchors.push(anchor);
|
|
163
|
+
});
|
|
164
|
+
document.body.insertAdjacentElement('afterbegin', container);
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async setPosToMapAnchors() {
|
|
169
|
+
const scrollPos = window.scrollY;
|
|
170
|
+
document.documentElement.style.scrollBehavior = 'unset';
|
|
171
|
+
window.scrollTo({ top: 0, behavior: 'instant' });
|
|
172
|
+
|
|
173
|
+
const getTopDistance = (el) => {
|
|
174
|
+
let distance = 0;
|
|
175
|
+
while (el) {
|
|
176
|
+
distance += el.offsetTop;
|
|
177
|
+
el = el.offsetParent;
|
|
178
|
+
}
|
|
179
|
+
return distance;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const getMobileAdjustment = (parent, index, top = false) => {
|
|
183
|
+
|
|
184
|
+
const mobileAdjustment =
|
|
185
|
+
!parent.classList.value.includes(
|
|
186
|
+
this.sels.mapFloating.replace('.', '')
|
|
187
|
+
) &&
|
|
188
|
+
this.isMobile() &&
|
|
189
|
+
!parent.previousElementSibling?.closest(
|
|
190
|
+
`${this.sels.mapWindows}:not(${this.sels.mapFloating})`
|
|
191
|
+
) &&
|
|
192
|
+
window.innerHeight;
|
|
193
|
+
return (top && index !== 0) || (!top && index === 0)
|
|
194
|
+
? mobileAdjustment
|
|
195
|
+
: 0;
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
this.mapWindows &&
|
|
199
|
+
this.mapWindows.forEach((parent) => {
|
|
200
|
+
let mapTriggers = parent.querySelectorAll(this.sels.triggers);
|
|
201
|
+
mapTriggers &&
|
|
202
|
+
mapTriggers.forEach((el, index) => {
|
|
203
|
+
const nextElement = mapTriggers[index + 1];
|
|
204
|
+
const anchorRef = document.querySelector(
|
|
205
|
+
this.refs.anchorId(el.getAttribute(this.refs.triggerRef()))
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
anchorRef.style.top = `${
|
|
209
|
+
getTopDistance(el) + getMobileAdjustment(parent, index, true)
|
|
210
|
+
}px`;
|
|
211
|
+
if (nextElement) {
|
|
212
|
+
const distanceToNext =
|
|
213
|
+
getTopDistance(nextElement) - getTopDistance(el);
|
|
214
|
+
anchorRef.style.height = `${
|
|
215
|
+
distanceToNext + getMobileAdjustment(parent, index)
|
|
216
|
+
}px`;
|
|
217
|
+
} else {
|
|
218
|
+
const parentBottomDistance =
|
|
219
|
+
getTopDistance(parent) + parent.offsetHeight;
|
|
220
|
+
const distanceToParentBottom =
|
|
221
|
+
parentBottomDistance -
|
|
222
|
+
getTopDistance(el) -
|
|
223
|
+
getMobileAdjustment(parent, index, true);
|
|
224
|
+
anchorRef.style.height = `${distanceToParentBottom}px`;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
window.scrollTo({ top: scrollPos, behavior: 'instant' });
|
|
229
|
+
document.documentElement.style.scrollBehavior = null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
async setMapWindowDisplacers() {
|
|
233
|
+
let topMapWindows = Array.from(this.mapWindows).filter(
|
|
234
|
+
(el) => !el.querySelector(`${this.sels.triggersClass}:first-child`)
|
|
235
|
+
);
|
|
236
|
+
topMapWindows.length &&
|
|
237
|
+
topMapWindows.forEach((el) =>
|
|
238
|
+
el
|
|
239
|
+
.querySelector(this.sels.mapContent)
|
|
240
|
+
.insertAdjacentHTML(
|
|
241
|
+
'afterbegin',
|
|
242
|
+
`<div class="${this.sels.triggersClass.replace(
|
|
243
|
+
'.',
|
|
244
|
+
''
|
|
245
|
+
)}" ${this.refs.triggerView()}="${this.labels.displacer}"></div>`
|
|
246
|
+
)
|
|
247
|
+
);
|
|
248
|
+
return topMapWindows.length;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
adjustFirstViewOnLoad() {
|
|
252
|
+
const isTop = () => {
|
|
253
|
+
let el = Array.from(this.mapTriggers)[0];
|
|
254
|
+
let pos = el && el.getBoundingClientRect().top;
|
|
255
|
+
let ref =
|
|
256
|
+
el &&
|
|
257
|
+
document.querySelector(
|
|
258
|
+
this.refs.anchorId(el.getAttribute(this.refs.triggerRef()))
|
|
259
|
+
);
|
|
260
|
+
return (
|
|
261
|
+
el &&
|
|
262
|
+
window.scrollY < pos &&
|
|
263
|
+
pos < window.innerHeight * (this.getScreenTransitionPoint() * 0.01) &&
|
|
264
|
+
ref
|
|
265
|
+
);
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
// change to first view if the view is above transition point
|
|
269
|
+
setTimeout(() => {
|
|
270
|
+
const isTopEl = isTop();
|
|
271
|
+
isTopEl && this.changeViewByEl(isTopEl, true);
|
|
272
|
+
}, 80);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
observeView(els, callback) {
|
|
276
|
+
if (!els || !els.length) return;
|
|
277
|
+
this.viewObserver && this.viewObserver.disconnect();
|
|
278
|
+
this.viewObserver = new IntersectionObserver(
|
|
279
|
+
(entries) => {
|
|
280
|
+
entries.forEach((entry) =>
|
|
281
|
+
callback(entry.target, entry.isIntersecting)
|
|
282
|
+
);
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
rootMargin: `${this.getScreenTransitionPoint() * -1}% 0px ${
|
|
286
|
+
(100 - this.getScreenTransitionPoint()) * -1
|
|
287
|
+
}% 0px`,
|
|
288
|
+
threshold: 0,
|
|
289
|
+
}
|
|
290
|
+
);
|
|
291
|
+
els.forEach((element) => this.viewObserver.observe(element));
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/* Layers management */
|
|
295
|
+
|
|
296
|
+
defineLayers() {
|
|
297
|
+
Object.values(this.views).forEach((view) => {
|
|
298
|
+
if (view.layers) {
|
|
299
|
+
// Normalizar layers - pode vir como string (texto com quebras de linha) ou array
|
|
300
|
+
const normalizedLayers = Array.isArray(view.layers) ? view.layers :
|
|
301
|
+
(typeof view.layers === 'string' ? view.layers.split('\n').map(line => line.trim()).filter(line => line.length > 0) : []);
|
|
302
|
+
|
|
303
|
+
normalizedLayers.forEach((layer) => {
|
|
304
|
+
const layerName = typeof layer === 'string' ? layer : layer.name;
|
|
305
|
+
if (layerName) {
|
|
306
|
+
this.definedLayers.push(layerName);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
displayLayers(layers = [], show = false) {
|
|
314
|
+
// Processar layers em lote para melhor performance
|
|
315
|
+
const layerUpdates = [];
|
|
316
|
+
|
|
317
|
+
// Normalizar layers - pode vir como string (texto com quebras de linha) ou array
|
|
318
|
+
const normalizedLayers = Array.isArray(layers) ? layers :
|
|
319
|
+
(typeof layers === 'string' ? layers.split('\n').map(line => line.trim()).filter(line => line.length > 0) : []);
|
|
320
|
+
|
|
321
|
+
normalizedLayers.forEach((layer) => {
|
|
322
|
+
const layerName = typeof layer === 'string' ? layer : layer.name;
|
|
323
|
+
if (layerName && this.layerExists(layerName)) {
|
|
324
|
+
layerUpdates.push({
|
|
325
|
+
name: layerName,
|
|
326
|
+
visibility: show ? 'visible' : 'none',
|
|
327
|
+
filter: typeof layer === 'object' ? layer.filter : null,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
// Aplicar todas as atualizações
|
|
333
|
+
this.applyLayerUpdates(layerUpdates);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
layerExists(layerName) {
|
|
337
|
+
try {
|
|
338
|
+
return this.map.getLayer(layerName) !== undefined;
|
|
339
|
+
} catch (e) {
|
|
340
|
+
console.warn(`Layer '${layerName}' não encontrada no mapa`);
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
applyLayerUpdates(updates) {
|
|
346
|
+
updates.forEach((update) => {
|
|
347
|
+
try {
|
|
348
|
+
this.map.setLayoutProperty(
|
|
349
|
+
update.name,
|
|
350
|
+
'visibility',
|
|
351
|
+
update.visibility
|
|
352
|
+
);
|
|
353
|
+
this.mapClone &&
|
|
354
|
+
this.mapClone.setLayoutProperty(
|
|
355
|
+
update.name,
|
|
356
|
+
'visibility',
|
|
357
|
+
update.visibility
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
if (update.filter) {
|
|
361
|
+
this.map.setFilter(update.name, update.filter);
|
|
362
|
+
this.mapClone && this.mapClone.setFilter(update.name, update.filter);
|
|
363
|
+
} else {
|
|
364
|
+
const originalFilter = this.getOriginalLayerFilter(update.name);
|
|
365
|
+
this.map.setFilter(update.name, originalFilter);
|
|
366
|
+
this.mapClone && this.mapClone.setFilter(update.name, originalFilter);
|
|
367
|
+
}
|
|
368
|
+
} catch (e) {
|
|
369
|
+
console.error(`Erro ao atualizar layer '${update.name}':`, e);
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
toggleLayersVisibility(visibleLayers) {
|
|
375
|
+
// Normalizar layers - pode vir como string (texto com quebras de linha) ou array
|
|
376
|
+
const normalizedLayers = Array.isArray(visibleLayers) ? visibleLayers :
|
|
377
|
+
(typeof visibleLayers === 'string' ? visibleLayers.split('\n').map(line => line.trim()).filter(line => line.length > 0) : []);
|
|
378
|
+
|
|
379
|
+
const visibleLayerNames = normalizedLayers.map((layer) =>
|
|
380
|
+
typeof layer === 'string' ? layer : layer.name
|
|
381
|
+
);
|
|
382
|
+
const hideLayers = this.definedLayers.filter(
|
|
383
|
+
(entry) => !visibleLayerNames.includes(entry)
|
|
384
|
+
);
|
|
385
|
+
|
|
386
|
+
// Preparar atualizações para esconder layers
|
|
387
|
+
const hideUpdates = hideLayers.map((layerName) => ({
|
|
388
|
+
name: layerName,
|
|
389
|
+
visibility: 'none',
|
|
390
|
+
filter: null,
|
|
391
|
+
}));
|
|
392
|
+
|
|
393
|
+
// Preparar atualizações para mostrar layers
|
|
394
|
+
const showUpdates = [];
|
|
395
|
+
normalizedLayers.forEach((layer) => {
|
|
396
|
+
const layerName = typeof layer === 'string' ? layer : layer.name;
|
|
397
|
+
if (layerName && this.layerExists(layerName)) {
|
|
398
|
+
showUpdates.push({
|
|
399
|
+
name: layerName,
|
|
400
|
+
visibility: 'visible',
|
|
401
|
+
filter: typeof layer === 'object' ? layer.filter : null,
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
// Aplicar todas as atualizações de uma vez
|
|
407
|
+
this.applyLayerUpdates([...hideUpdates, ...showUpdates]);
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/* Map Movement */
|
|
411
|
+
|
|
412
|
+
async move(view, refEl = false, fly = true) {
|
|
413
|
+
this.animationStartTime = Date.now();
|
|
414
|
+
const isAnimating = this.map.isMoving() || this.map.isZooming();
|
|
415
|
+
const viewParameters = this.getViewParameters(view);
|
|
416
|
+
const destiny = refEl
|
|
417
|
+
? { ...viewParameters, offset: this.getDiplacedOffset(refEl) }
|
|
418
|
+
: viewParameters;
|
|
419
|
+
|
|
420
|
+
refEl &&
|
|
421
|
+
setTimeout(() => {
|
|
422
|
+
this.generateCaptionsHTML(
|
|
423
|
+
view.captions,
|
|
424
|
+
refEl.closest(this.sels.mapWindows)
|
|
425
|
+
);
|
|
426
|
+
this.captionHolder.classList.remove('hidden');
|
|
427
|
+
this.countIntersectionEvents = 0;
|
|
428
|
+
}, 20);
|
|
429
|
+
this.toggleLayersVisibility(view.layers);
|
|
430
|
+
|
|
431
|
+
if (destiny.id === this.currentView.id && !isAnimating) {
|
|
432
|
+
destiny.duration = 1500;
|
|
433
|
+
fly = false;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
this.currentView = view;
|
|
437
|
+
fly
|
|
438
|
+
? this.mapClone && this.mapClone.flyTo(destiny)
|
|
439
|
+
: this.mapClone && this.mapClone.easeTo(destiny);
|
|
440
|
+
return fly ? this.map.flyTo(destiny) : this.map.easeTo(destiny);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
changeViewByEl(target, intersection) {
|
|
444
|
+
if (!intersection) {
|
|
445
|
+
if (!this.countIntersectionEvents) {
|
|
446
|
+
this.captionHolder.classList.add('hidden');
|
|
447
|
+
this.maybeBackToInitialView();
|
|
448
|
+
++this.countIntersectionEvents;
|
|
449
|
+
}
|
|
450
|
+
return false;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
let viewId = target.getAttribute(this.refs.anchorView());
|
|
454
|
+
let mapTrigger = document.querySelector(
|
|
455
|
+
this.refs.triggerRef(target.getAttribute(this.refs.anchorId()))
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
if (this.views.hasOwnProperty(viewId)) {
|
|
459
|
+
this.move(this.views[viewId], mapTrigger);
|
|
460
|
+
return true;
|
|
461
|
+
}
|
|
462
|
+
if (viewId === this.labels.displacer) {
|
|
463
|
+
const lastAnchor = this.getPreviousAnchorInfo(target);
|
|
464
|
+
lastAnchor
|
|
465
|
+
? this.move(lastAnchor.view, mapTrigger)
|
|
466
|
+
: this.move(this.initView);
|
|
467
|
+
return true;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
console.warn('view not found');
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
maybeBackToInitialView() {
|
|
475
|
+
const isTop = () => {
|
|
476
|
+
let el = Array.from(this.mapTriggers)[0];
|
|
477
|
+
let pos = el.getBoundingClientRect().top;
|
|
478
|
+
return (
|
|
479
|
+
pos >
|
|
480
|
+
window.innerHeight * (this.getScreenTransitionPoint() * 0.01) && el
|
|
481
|
+
);
|
|
482
|
+
};
|
|
483
|
+
const isTopEl = isTop();
|
|
484
|
+
isTopEl && this.move(this.initView);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/* Captions */
|
|
488
|
+
|
|
489
|
+
generateCaptionsHTML(captions, holder) {
|
|
490
|
+
if (!captions) {
|
|
491
|
+
this.captionHolder.innerHTML = '';
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
const infoSvg = `
|
|
495
|
+
<button data-toggle-caption>
|
|
496
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
497
|
+
<rect width="24" height="24" rx="12" fill="#000000"/>
|
|
498
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 22.5C17.799 22.5 22.5 17.799 22.5 12C22.5 6.20101 17.799 1.5 12 1.5C6.20101 1.5 1.5 6.20101 1.5 12C1.5 17.799 6.20101 22.5 12 22.5ZM12 24C18.6274 24 24 18.6274 24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24Z" fill="#FFFFFF"/>
|
|
499
|
+
<path d="M11.3032 17.8065C11.1926 17.8065 11.0986 17.7666 11.0212 17.687C10.9438 17.6074 10.9051 17.5107 10.9051 17.397V9.34364C10.9051 9.22989 10.9438 9.13321 11.0212 9.05359C11.0986 8.97396 11.1926 8.93415 11.3032 8.93415H12.6802C12.8018 8.93415 12.8959 8.97396 12.9622 9.05359C13.0396 9.13321 13.0783 9.22989 13.0783 9.34364V17.397C13.0783 17.5107 13.0396 17.6074 12.9622 17.687C12.8959 17.7666 12.8018 17.8065 12.6802 17.8065H11.3032ZM11.2369 7.46681C11.1263 7.46681 11.0323 7.427 10.9548 7.34737C10.8774 7.26775 10.8387 7.17107 10.8387 7.05732V5.82885C10.8387 5.7151 10.8774 5.61841 10.9548 5.53879C11.0323 5.45917 11.1263 5.41935 11.2369 5.41935H12.7465C12.8682 5.41935 12.9677 5.45917 13.0452 5.53879C13.1226 5.61841 13.1613 5.7151 13.1613 5.82885V7.05732C13.1613 7.17107 13.1226 7.26775 13.0452 7.34737C12.9677 7.427 12.8682 7.46681 12.7465 7.46681H11.2369Z" fill="#FFFFFF"/>
|
|
500
|
+
</svg>
|
|
501
|
+
</button>`;
|
|
502
|
+
this.captionsId = this.sels.captions.replace('#', '');
|
|
503
|
+
this.captionHolder.innerHTML = infoSvg;
|
|
504
|
+
|
|
505
|
+
let container = document.createElement('div');
|
|
506
|
+
if (captions.title) {
|
|
507
|
+
let title = document.createElement('span');
|
|
508
|
+
title.className = `${this.captionsId}__title`;
|
|
509
|
+
title.innerText = captions.title || 'Legenda:';
|
|
510
|
+
container.appendChild(title);
|
|
511
|
+
}
|
|
512
|
+
captions.items &&
|
|
513
|
+
captions.items.length &&
|
|
514
|
+
captions.items.forEach((item) => {
|
|
515
|
+
let itemContainer = document.createElement('span');
|
|
516
|
+
itemContainer.className = `${this.captionsId}__item`;
|
|
517
|
+
|
|
518
|
+
let iconContainer = document.createElement('span');
|
|
519
|
+
iconContainer.innerHTML = item.icon;
|
|
520
|
+
itemContainer.appendChild(iconContainer);
|
|
521
|
+
|
|
522
|
+
let textContainer = document.createElement('span');
|
|
523
|
+
textContainer.innerText = item.text;
|
|
524
|
+
itemContainer.appendChild(textContainer);
|
|
525
|
+
|
|
526
|
+
container.appendChild(itemContainer);
|
|
527
|
+
});
|
|
528
|
+
if (captions.notes) {
|
|
529
|
+
let notes = document.createElement('span');
|
|
530
|
+
notes.className = `${this.captionsId}__notes`;
|
|
531
|
+
notes.innerText = captions.notes;
|
|
532
|
+
container.appendChild(notes);
|
|
533
|
+
}
|
|
534
|
+
this.captionHolder.innerHTML += container.innerHTML;
|
|
535
|
+
holder.insertAdjacentElement('beforeend', this.captionHolder);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/* Helpers */
|
|
539
|
+
|
|
540
|
+
isMobile() {
|
|
541
|
+
return window.matchMedia(`(max-width:${this.mobileBreakPoint}px`).matches;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
getViewParameters(view) {
|
|
545
|
+
let isMobile =
|
|
546
|
+
view &&
|
|
547
|
+
this.isMobile() &&
|
|
548
|
+
view.hasOwnProperty('mobile') &&
|
|
549
|
+
view.mobile &&
|
|
550
|
+
Object.values(view.mobile).length;
|
|
551
|
+
let mobileView = isMobile && { ...view.mobile };
|
|
552
|
+
|
|
553
|
+
// Converter centerLng/centerLat para center se necessário
|
|
554
|
+
let processedView = isMobile ? { ...view, ...mobileView } : view;
|
|
555
|
+
if (processedView.centerLng !== undefined && processedView.centerLat !== undefined) {
|
|
556
|
+
processedView.center = {
|
|
557
|
+
lng: parseFloat(processedView.centerLng),
|
|
558
|
+
lat: parseFloat(processedView.centerLat)
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
return processedView;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
getDiplacedOffset(el) {
|
|
566
|
+
const parent = el.closest(this.sels.mapWindows);
|
|
567
|
+
const parentClasses = parent.classList.value;
|
|
568
|
+
const offset = { x: 0, y: 0 };
|
|
569
|
+
|
|
570
|
+
if (
|
|
571
|
+
(parentClasses.includes(this.sels.mapFloating.replace('.', '')) &&
|
|
572
|
+
this.isMobile()) ||
|
|
573
|
+
parentClasses.includes('center')
|
|
574
|
+
)
|
|
575
|
+
return Object.values(offset);
|
|
576
|
+
|
|
577
|
+
if (this.isMobile()) {
|
|
578
|
+
offset.y = this.isMobile()
|
|
579
|
+
? window.innerHeight * ((1 - this.mapMobileHeight) * 0.005)
|
|
580
|
+
: 0;
|
|
581
|
+
} else {
|
|
582
|
+
offset.x = parent
|
|
583
|
+
.querySelector(this.sels.mapContent)
|
|
584
|
+
.getBoundingClientRect().width;
|
|
585
|
+
offset.x *= parentClasses.includes('alignleft')
|
|
586
|
+
? 0.5
|
|
587
|
+
: parentClasses.includes('alignright')
|
|
588
|
+
? -0.5
|
|
589
|
+
: 0;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
return Object.values(offset);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
getScreenTransitionPoint() {
|
|
596
|
+
const screenPoint = this.isMobile()
|
|
597
|
+
? this.transitionScreenPointMobile
|
|
598
|
+
: this.transitionScreenPoint;
|
|
599
|
+
return screenPoint;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
getCurrentAnimationRemaingDuration() {
|
|
603
|
+
let remainingDuration =
|
|
604
|
+
this.getViewParameters(this.currentView).duration -
|
|
605
|
+
(Date.now() - this.animationStartTime);
|
|
606
|
+
return remainingDuration < 0 ? 0 : remainingDuration;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
getHistoryType() {
|
|
610
|
+
let columnViews = Array.from(this.mapWindows).filter(
|
|
611
|
+
(el) =>
|
|
612
|
+
!el.classList.value.includes(this.sels.mapFloating.replace('.', ''))
|
|
613
|
+
).length;
|
|
614
|
+
let floatingViews = Array.from(this.mapWindows).filter((el) =>
|
|
615
|
+
el.classList.value.includes(this.sels.mapFloating.replace('.', ''))
|
|
616
|
+
).length;
|
|
617
|
+
return columnViews && floatingViews
|
|
618
|
+
? 'mixed'
|
|
619
|
+
: columnViews
|
|
620
|
+
? 'columns'
|
|
621
|
+
: 'floating';
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
getAnchorInfo(el) {
|
|
625
|
+
if (!el.getAttribute(this.refs.anchorView())) {
|
|
626
|
+
console.warn('Not an anchor');
|
|
627
|
+
return false;
|
|
628
|
+
}
|
|
629
|
+
let view = { ...this.views[el.getAttribute(this.refs.anchorView())] };
|
|
630
|
+
if (view && Object.keys(view).length) {
|
|
631
|
+
let trigger = document.querySelector(
|
|
632
|
+
this.refs.triggerRef(el.getAttribute(this.refs.anchorId()))
|
|
633
|
+
);
|
|
634
|
+
let mapWindow = trigger.closest(this.sels.mapWindows);
|
|
635
|
+
return {
|
|
636
|
+
el: el,
|
|
637
|
+
view: view,
|
|
638
|
+
viewname: el.getAttribute(this.refs.anchorView()),
|
|
639
|
+
anchor: el,
|
|
640
|
+
ref: el.getAttribute(this.refs.anchorId()),
|
|
641
|
+
trigger: trigger,
|
|
642
|
+
mapWindow: mapWindow,
|
|
643
|
+
mapWindowClasses: mapWindow.classList.value,
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
return false;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
getNextAnchorInfo(el) {
|
|
650
|
+
if (!el.getAttribute(this.refs.anchorView())) {
|
|
651
|
+
console.warn('Not an anchor');
|
|
652
|
+
return false;
|
|
653
|
+
}
|
|
654
|
+
let next = false;
|
|
655
|
+
while (el.nextElementSibling && !next) {
|
|
656
|
+
el = el.nextElementSibling;
|
|
657
|
+
next =
|
|
658
|
+
el.getAttribute(this.refs.anchorView()) === this.labels.displacer
|
|
659
|
+
? false
|
|
660
|
+
: true;
|
|
661
|
+
}
|
|
662
|
+
return next && this.getAnchorInfo(el);
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
getPreviousAnchorInfo(el) {
|
|
666
|
+
if (!el.getAttribute(this.refs.anchorView())) {
|
|
667
|
+
console.warn('Not an anchor');
|
|
668
|
+
return false;
|
|
669
|
+
}
|
|
670
|
+
let next = false;
|
|
671
|
+
while (el.previousElementSibling && !next) {
|
|
672
|
+
el = el.previousElementSibling;
|
|
673
|
+
next =
|
|
674
|
+
el.getAttribute(this.refs.anchorView()) === this.labels.displacer
|
|
675
|
+
? false
|
|
676
|
+
: true;
|
|
677
|
+
}
|
|
678
|
+
return next && this.getAnchorInfo(el);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export default class ScrollProgressionBar {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.addProgressionBar();
|
|
4
|
+
this.onScroll();
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
updateProgressionBar() {
|
|
8
|
+
const scrollPercentage = (window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100;
|
|
9
|
+
this.progressionBar.style.width = `${scrollPercentage}%`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
addProgressionBar() {
|
|
13
|
+
this.progressionBar = document.createElement('div');
|
|
14
|
+
this.progressionBar.classList.add('scroll-progression-bar');
|
|
15
|
+
this.progressionBar.style.width = '0%';
|
|
16
|
+
document.body.appendChild(this.progressionBar);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
onScroll() {
|
|
20
|
+
window.addEventListener('scroll', () => {
|
|
21
|
+
this.updateProgressionBar();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|