diff --git a/index.html b/index.html index 23f1e58..0dd3d59 100644 --- a/index.html +++ b/index.html @@ -1,372 +1,417 @@ - - - - - - + + - Analyzing the Internals of Neural Radiance Fields - - - + + + + + Analyzing the Internals of Neural Radiance Fields + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -
-
- Analyzing the Internals of Neural Radiance Fields
- We propose a novel approach for approximating a weight distribution from the activations of trained NeRFs.
-
- -
- - - - - - -
-
- Lukas Radl
- Graz University of Technology -
-
-
- Andreas Kurz
- Graz University of Technology -
-
-
- Markus Steinberger
- Graz University of Technology -
-
-
- - - - - - -
-
- -
-
-
- -
-
- -
-
- -
- - - - -
-
- -
-
-
- -
- - -

Abstract

- - - -
- Modern Neural Radiance Fields (NeRFs) learn a mapping from position to volumetric density via proposal network samplers. - In contrast to the coarse-to-fine sampling approach with two NeRFs, this offers significant potential for speedups using lower network capacity as the task of mapping spatial coordinates to volumetric density involves no view-dependent effects and is thus much easier to learn. - Given that most of the network capacity is utilized to estimate radiance, NeRFs could store valuable density information in their parameters or their deep features. - To this end, we take one step back and analyze large, trained ReLU-MLPs used in coarse-to-fine sampling. - We find that trained NeRFs, Mip-NeRFs and proposal network samplers map samples with high density to local minima along a ray in activation feature space. - We show how these large MLPs can be accelerated by transforming the intermediate activations to a weight estimate, without any modifications to the parameters post-optimization. - With our approach, we can reduce the computational requirements of trained NeRFs by up to 50% with only a slight hit in rendering quality and no changes to the training protocol or architecture. - We evaluate our approach on a variety of architectures and datasets, showing that our proposition holds in various settings. -
-
-
-

Obtaining density estimates from activations.

- -
-
- - - -
-
- - - - - - -
-
-
-
- -
-
- - - - - - - - - - - - - - - -
- We analyze the histograms of trained NeRFs, Mip-NeRFs and proposal networks samples (as in Mip-NeRF 360) - and find that their intermediate activations are useful in finding a density estimate. -
- Using our simple and efficient method, we can extract a density estimate from the activations of early - layers in coarse-to-fine sampling, which leads to a reduction in run-time with comparable visual quality. -
- Our approach requires no pre-training or fine-tuning. To our knowledge, we are the first to use activations - from coordinate-based MLPs during inference. -
- We evaluate our approach on real-world and synthetic data and obtain similar visual quality compared with NeRF, Mip-NeRf and a modified nerfacto model, - with lower inference cost. -
- Our project is built upon Nerfstudio and our modules can be installed as a Python Package. -
-
- - - - - - -
-
-
-
- -
-
-

Paper and Supplementary Material

- - - - -
Lukas Radl, Andreas Kurz, Markus Steinberger.
- Analyzing the Internals of Neural Radiance Fields.
- arXiv preprint arXiv:2306.00696,
2023.
- (hosted on arXiv)
-
-
-
+
+
+
+
+ +
+

Analyzing the Internals of Neural Radiance Fields +

+

+ CVPRW 2024 +

+

+ Workshop on Neural Rendering Intelligence +

+ + +
+ Graz University of Technology +
+ + +
+
+
+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+

Abstract

+
+

+ Modern Neural Radiance Fields (NeRFs) learn a mapping from position to volumetric density leveraging proposal network samplers. + In contrast to the coarse-to-fine sampling approach with two NeRFs, this offers significant potential for acceleration using lower network capacity. + Given that NeRFs utilize most of their network capacity to estimate radiance, they could store valuable density information in their parameters or their deep features. +

+ To investigate this proposition, we take one step back and analyze large, trained ReLU-MLPs used in coarse-to-fine sampling. + Building on our novel activation visualization method, we find that trained NeRFs, Mip-NeRFs and proposal network samplers map samples with high density to local minima along a ray in activation feature space. + We show how these large MLPs can be accelerated by transforming intermediate activations to a weight estimate, without any modifications to the training protocol or the network architecture. +

+ With our approach, we can reduce the computational requirements of trained NeRFs by up to 50% with only a slight hit in rendering quality. + Extensive experimental evaluation on a variety of datasets and architectures demonstrates the effectiveness of our approach. + Consequently, our methodology provides valuable insight into the inner workings of NeRFs. +

+
+
+
+
+
+ +
+
+ + +
+
+

Image Comparisons

+
+

+ Here, provide comparisons of renderings from our method against the baseline. +

+
+
+
+
+
+
+
+
+
+ Ours + Nerfacto +
+
+
+
+
+
+
+
+
+
+ Ours + Nerfacto +
+
+
+
+
+
+
+
+
+
+
+
+ Ours + NeRF +
+
+
+
+
+
+
+
+
+
+ Ours + NeRF +
+
+
+
+
+
+
+
+
+
+
+
+ Ours + Mip-NeRF +
+
+
+
+
+
+
+
+
+
+ Ours + Mip-NeRF +
+
+
+
+
+
+
+ +
+ +
+
+ + +
+
+

Activation Visualization

+
+

+ Here, we show how different normalizations look for exemplary scenes. +

+
+
+
+
+ + + + + + + + + + + +
+ + + + + + + + + + + + + +
01234567
+
+
+ + + + + +
+
+
+
+
+
+
+

Coarse Activations

+
+ Ours + Ground-Truth +
+
+
+
+
+
+
+
+
+

Fine Activations

+
+ Ours + Ground-Truth +
+
+
+
+
+
+
+ +
+ + +
+ +
+
+

Deriving Densities from Activations

+
+

+ Our approach for density estimation is driven by analyzing real-world-activations. + We observe that minima in activation feature space correspond to samples with high density. + Consequently, our approach does not require fine-tuning and can be applied to various NeRF-based methods. +

+
+
+
+
+
+ +
+
+
+ +
+
+

BibTeX

+
+

+ If you find our work useful, consider using a citation. +

+
+
@inproceedings{radl2024nerfinternals,
+  author    = {Radl, Lukas and Kurz, Andreas and Steiner, Michael and Steinberger, Markus},
+  title     = {{Analyzing the Internals of Neural Radiance Fields}},
+  booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition Workshops (CVPRW)},
+  year      = {2024},
+}
+
+
+ + -
-

Citation

- - - - - -
- @article(Radl2023NerfInternals, -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - title    - - = {{Analyzing the Internals of Neural Radiance Fields}}, -
- - author - - = {Radl, Lukas and Kurz, Andreas and Steinberger, Markus}, -
- - journal - - = {arXiv preprint arXiv:2306.00696}, -
- - year - - = {2023}, -
- } - - - - -
-
-
- - - - - -
- -

Acknowledgements

- This template was originally made by Phillip Isola and Richard Zhang for a colorful ECCV project; the code can be found here. -
-
- -
- - - diff --git a/resources/activations/chair_coarse_00.png b/resources/activations/chair_coarse_00.png new file mode 100755 index 0000000..d12ab79 Binary files /dev/null and b/resources/activations/chair_coarse_00.png differ diff --git a/resources/activations/chair_coarse_01.png b/resources/activations/chair_coarse_01.png new file mode 100755 index 0000000..1b44190 Binary files /dev/null and b/resources/activations/chair_coarse_01.png differ diff --git a/resources/activations/chair_coarse_02.png b/resources/activations/chair_coarse_02.png new file mode 100755 index 0000000..a4cda61 Binary files /dev/null and b/resources/activations/chair_coarse_02.png differ diff --git a/resources/activations/chair_coarse_03.png b/resources/activations/chair_coarse_03.png new file mode 100755 index 0000000..b80eea2 Binary files /dev/null and b/resources/activations/chair_coarse_03.png differ diff --git a/resources/activations/chair_coarse_04.png b/resources/activations/chair_coarse_04.png new file mode 100755 index 0000000..65774fe Binary files /dev/null and b/resources/activations/chair_coarse_04.png differ diff --git a/resources/activations/chair_coarse_05.png b/resources/activations/chair_coarse_05.png new file mode 100755 index 0000000..83383ae Binary files /dev/null and b/resources/activations/chair_coarse_05.png differ diff --git a/resources/activations/chair_coarse_06.png b/resources/activations/chair_coarse_06.png new file mode 100755 index 0000000..39a1a47 Binary files /dev/null and b/resources/activations/chair_coarse_06.png differ diff --git a/resources/activations/chair_coarse_07.png b/resources/activations/chair_coarse_07.png new file mode 100755 index 0000000..173126f Binary files /dev/null and b/resources/activations/chair_coarse_07.png differ diff --git a/resources/activations/chair_fine_00.png b/resources/activations/chair_fine_00.png new file mode 100755 index 0000000..d2b4399 Binary files /dev/null and b/resources/activations/chair_fine_00.png differ diff --git a/resources/activations/chair_fine_01.png b/resources/activations/chair_fine_01.png new file mode 100755 index 0000000..0f2013b Binary files /dev/null and b/resources/activations/chair_fine_01.png differ diff --git a/resources/activations/chair_fine_02.png b/resources/activations/chair_fine_02.png new file mode 100755 index 0000000..4a56d6c Binary files /dev/null and b/resources/activations/chair_fine_02.png differ diff --git a/resources/activations/chair_fine_03.png b/resources/activations/chair_fine_03.png new file mode 100755 index 0000000..5714a86 Binary files /dev/null and b/resources/activations/chair_fine_03.png differ diff --git a/resources/activations/chair_fine_04.png b/resources/activations/chair_fine_04.png new file mode 100755 index 0000000..469aaa9 Binary files /dev/null and b/resources/activations/chair_fine_04.png differ diff --git a/resources/activations/chair_fine_05.png b/resources/activations/chair_fine_05.png new file mode 100755 index 0000000..80709e0 Binary files /dev/null and b/resources/activations/chair_fine_05.png differ diff --git a/resources/activations/chair_fine_06.png b/resources/activations/chair_fine_06.png new file mode 100755 index 0000000..e150af6 Binary files /dev/null and b/resources/activations/chair_fine_06.png differ diff --git a/resources/activations/chair_fine_07.png b/resources/activations/chair_fine_07.png new file mode 100755 index 0000000..248f197 Binary files /dev/null and b/resources/activations/chair_fine_07.png differ diff --git a/resources/activations/chair_target.png b/resources/activations/chair_target.png new file mode 100755 index 0000000..d76ccad Binary files /dev/null and b/resources/activations/chair_target.png differ diff --git a/resources/activations/fern_coarse_00.png b/resources/activations/fern_coarse_00.png new file mode 100755 index 0000000..a0247b1 Binary files /dev/null and b/resources/activations/fern_coarse_00.png differ diff --git a/resources/activations/fern_coarse_01.png b/resources/activations/fern_coarse_01.png new file mode 100755 index 0000000..5232794 Binary files /dev/null and b/resources/activations/fern_coarse_01.png differ diff --git a/resources/activations/fern_coarse_02.png b/resources/activations/fern_coarse_02.png new file mode 100755 index 0000000..e834442 Binary files /dev/null and b/resources/activations/fern_coarse_02.png differ diff --git a/resources/activations/fern_coarse_03.png b/resources/activations/fern_coarse_03.png new file mode 100755 index 0000000..48231ae Binary files /dev/null and b/resources/activations/fern_coarse_03.png differ diff --git a/resources/activations/fern_coarse_04.png b/resources/activations/fern_coarse_04.png new file mode 100755 index 0000000..16a5f12 Binary files /dev/null and b/resources/activations/fern_coarse_04.png differ diff --git a/resources/activations/fern_coarse_05.png b/resources/activations/fern_coarse_05.png new file mode 100755 index 0000000..0d4088a Binary files /dev/null and b/resources/activations/fern_coarse_05.png differ diff --git a/resources/activations/fern_coarse_06.png b/resources/activations/fern_coarse_06.png new file mode 100755 index 0000000..644ea1e Binary files /dev/null and b/resources/activations/fern_coarse_06.png differ diff --git a/resources/activations/fern_coarse_07.png b/resources/activations/fern_coarse_07.png new file mode 100755 index 0000000..25808df Binary files /dev/null and b/resources/activations/fern_coarse_07.png differ diff --git a/resources/activations/fern_fine_00.png b/resources/activations/fern_fine_00.png new file mode 100755 index 0000000..ac572c8 Binary files /dev/null and b/resources/activations/fern_fine_00.png differ diff --git a/resources/activations/fern_fine_01.png b/resources/activations/fern_fine_01.png new file mode 100755 index 0000000..a39175a Binary files /dev/null and b/resources/activations/fern_fine_01.png differ diff --git a/resources/activations/fern_fine_02.png b/resources/activations/fern_fine_02.png new file mode 100755 index 0000000..a8f5366 Binary files /dev/null and b/resources/activations/fern_fine_02.png differ diff --git a/resources/activations/fern_fine_03.png b/resources/activations/fern_fine_03.png new file mode 100755 index 0000000..b6a16d2 Binary files /dev/null and b/resources/activations/fern_fine_03.png differ diff --git a/resources/activations/fern_fine_04.png b/resources/activations/fern_fine_04.png new file mode 100755 index 0000000..0b4dd53 Binary files /dev/null and b/resources/activations/fern_fine_04.png differ diff --git a/resources/activations/fern_fine_05.png b/resources/activations/fern_fine_05.png new file mode 100755 index 0000000..b130899 Binary files /dev/null and b/resources/activations/fern_fine_05.png differ diff --git a/resources/activations/fern_fine_06.png b/resources/activations/fern_fine_06.png new file mode 100755 index 0000000..cf1dc6b Binary files /dev/null and b/resources/activations/fern_fine_06.png differ diff --git a/resources/activations/fern_fine_07.png b/resources/activations/fern_fine_07.png new file mode 100755 index 0000000..9e8c791 Binary files /dev/null and b/resources/activations/fern_fine_07.png differ diff --git a/resources/activations/fern_target.png b/resources/activations/fern_target.png new file mode 100755 index 0000000..9558e28 Binary files /dev/null and b/resources/activations/fern_target.png differ diff --git a/resources/activations/ficus_coarse_00.png b/resources/activations/ficus_coarse_00.png new file mode 100755 index 0000000..5ca0b3c Binary files /dev/null and b/resources/activations/ficus_coarse_00.png differ diff --git a/resources/activations/ficus_coarse_01.png b/resources/activations/ficus_coarse_01.png new file mode 100755 index 0000000..251cd5d Binary files /dev/null and b/resources/activations/ficus_coarse_01.png differ diff --git a/resources/activations/ficus_coarse_02.png b/resources/activations/ficus_coarse_02.png new file mode 100755 index 0000000..006f635 Binary files /dev/null and b/resources/activations/ficus_coarse_02.png differ diff --git a/resources/activations/ficus_coarse_03.png b/resources/activations/ficus_coarse_03.png new file mode 100755 index 0000000..aa6e81a Binary files /dev/null and b/resources/activations/ficus_coarse_03.png differ diff --git a/resources/activations/ficus_coarse_04.png b/resources/activations/ficus_coarse_04.png new file mode 100755 index 0000000..9925ad1 Binary files /dev/null and b/resources/activations/ficus_coarse_04.png differ diff --git a/resources/activations/ficus_coarse_05.png b/resources/activations/ficus_coarse_05.png new file mode 100755 index 0000000..74c2752 Binary files /dev/null and b/resources/activations/ficus_coarse_05.png differ diff --git a/resources/activations/ficus_coarse_06.png b/resources/activations/ficus_coarse_06.png new file mode 100755 index 0000000..2373e1c Binary files /dev/null and b/resources/activations/ficus_coarse_06.png differ diff --git a/resources/activations/ficus_coarse_07.png b/resources/activations/ficus_coarse_07.png new file mode 100755 index 0000000..0ba31a5 Binary files /dev/null and b/resources/activations/ficus_coarse_07.png differ diff --git a/resources/activations/ficus_fine_00.png b/resources/activations/ficus_fine_00.png new file mode 100755 index 0000000..1a3ec45 Binary files /dev/null and b/resources/activations/ficus_fine_00.png differ diff --git a/resources/activations/ficus_fine_01.png b/resources/activations/ficus_fine_01.png new file mode 100755 index 0000000..d48f07e Binary files /dev/null and b/resources/activations/ficus_fine_01.png differ diff --git a/resources/activations/ficus_fine_02.png b/resources/activations/ficus_fine_02.png new file mode 100755 index 0000000..606160d Binary files /dev/null and b/resources/activations/ficus_fine_02.png differ diff --git a/resources/activations/ficus_fine_03.png b/resources/activations/ficus_fine_03.png new file mode 100755 index 0000000..217db4b Binary files /dev/null and b/resources/activations/ficus_fine_03.png differ diff --git a/resources/activations/ficus_fine_04.png b/resources/activations/ficus_fine_04.png new file mode 100755 index 0000000..93bb3bf Binary files /dev/null and b/resources/activations/ficus_fine_04.png differ diff --git a/resources/activations/ficus_fine_05.png b/resources/activations/ficus_fine_05.png new file mode 100755 index 0000000..95e6b4d Binary files /dev/null and b/resources/activations/ficus_fine_05.png differ diff --git a/resources/activations/ficus_fine_06.png b/resources/activations/ficus_fine_06.png new file mode 100755 index 0000000..70049d1 Binary files /dev/null and b/resources/activations/ficus_fine_06.png differ diff --git a/resources/activations/ficus_fine_07.png b/resources/activations/ficus_fine_07.png new file mode 100755 index 0000000..85e5386 Binary files /dev/null and b/resources/activations/ficus_fine_07.png differ diff --git a/resources/activations/ficus_target.png b/resources/activations/ficus_target.png new file mode 100755 index 0000000..b28419e Binary files /dev/null and b/resources/activations/ficus_target.png differ diff --git a/resources/activations/lego_coarse_00.png b/resources/activations/lego_coarse_00.png new file mode 100755 index 0000000..41350a9 Binary files /dev/null and b/resources/activations/lego_coarse_00.png differ diff --git a/resources/activations/lego_coarse_01.png b/resources/activations/lego_coarse_01.png new file mode 100755 index 0000000..f2daf54 Binary files /dev/null and b/resources/activations/lego_coarse_01.png differ diff --git a/resources/activations/lego_coarse_02.png b/resources/activations/lego_coarse_02.png new file mode 100755 index 0000000..b96ea55 Binary files /dev/null and b/resources/activations/lego_coarse_02.png differ diff --git a/resources/activations/lego_coarse_03.png b/resources/activations/lego_coarse_03.png new file mode 100755 index 0000000..2267734 Binary files /dev/null and b/resources/activations/lego_coarse_03.png differ diff --git a/resources/activations/lego_coarse_04.png b/resources/activations/lego_coarse_04.png new file mode 100755 index 0000000..4bc5ffe Binary files /dev/null and b/resources/activations/lego_coarse_04.png differ diff --git a/resources/activations/lego_coarse_05.png b/resources/activations/lego_coarse_05.png new file mode 100755 index 0000000..26a97c3 Binary files /dev/null and b/resources/activations/lego_coarse_05.png differ diff --git a/resources/activations/lego_coarse_06.png b/resources/activations/lego_coarse_06.png new file mode 100755 index 0000000..67b5802 Binary files /dev/null and b/resources/activations/lego_coarse_06.png differ diff --git a/resources/activations/lego_coarse_07.png b/resources/activations/lego_coarse_07.png new file mode 100755 index 0000000..cb68986 Binary files /dev/null and b/resources/activations/lego_coarse_07.png differ diff --git a/resources/activations/lego_fine_00.png b/resources/activations/lego_fine_00.png new file mode 100755 index 0000000..4c52d0d Binary files /dev/null and b/resources/activations/lego_fine_00.png differ diff --git a/resources/activations/lego_fine_01.png b/resources/activations/lego_fine_01.png new file mode 100755 index 0000000..ca9c4d2 Binary files /dev/null and b/resources/activations/lego_fine_01.png differ diff --git a/resources/activations/lego_fine_02.png b/resources/activations/lego_fine_02.png new file mode 100755 index 0000000..a7a4780 Binary files /dev/null and b/resources/activations/lego_fine_02.png differ diff --git a/resources/activations/lego_fine_03.png b/resources/activations/lego_fine_03.png new file mode 100755 index 0000000..5c4912a Binary files /dev/null and b/resources/activations/lego_fine_03.png differ diff --git a/resources/activations/lego_fine_04.png b/resources/activations/lego_fine_04.png new file mode 100755 index 0000000..8dada26 Binary files /dev/null and b/resources/activations/lego_fine_04.png differ diff --git a/resources/activations/lego_fine_05.png b/resources/activations/lego_fine_05.png new file mode 100755 index 0000000..0189eaa Binary files /dev/null and b/resources/activations/lego_fine_05.png differ diff --git a/resources/activations/lego_fine_06.png b/resources/activations/lego_fine_06.png new file mode 100755 index 0000000..42ce492 Binary files /dev/null and b/resources/activations/lego_fine_06.png differ diff --git a/resources/activations/lego_fine_07.png b/resources/activations/lego_fine_07.png new file mode 100755 index 0000000..8c108c2 Binary files /dev/null and b/resources/activations/lego_fine_07.png differ diff --git a/resources/activations/lego_target.png b/resources/activations/lego_target.png new file mode 100755 index 0000000..e69c4ff Binary files /dev/null and b/resources/activations/lego_target.png differ diff --git a/resources/arxiv-logo.png b/resources/arxiv-logo.png deleted file mode 100644 index ec67468..0000000 Binary files a/resources/arxiv-logo.png and /dev/null differ diff --git a/resources/bibtex.txt b/resources/bibtex.txt deleted file mode 100644 index a64f88e..0000000 --- a/resources/bibtex.txt +++ /dev/null @@ -1,6 +0,0 @@ -@inproceedings{author20XXtitle, - title={Please cite me}, - author={Author, First and Author, Second and Author, Third}, - booktitle={Conference}, - year={20XX} -} \ No newline at end of file diff --git a/resources/fern_mipnerf.png b/resources/fern_mipnerf.png new file mode 100644 index 0000000..39d193e Binary files /dev/null and b/resources/fern_mipnerf.png differ diff --git a/resources/fern_ours.png b/resources/fern_ours.png new file mode 100644 index 0000000..e38265a Binary files /dev/null and b/resources/fern_ours.png differ diff --git a/resources/fixed_teasr(1).png b/resources/fixed_teasr(1).png new file mode 100644 index 0000000..5423fac Binary files /dev/null and b/resources/fixed_teasr(1).png differ diff --git a/resources/github-mark.png b/resources/github-mark.png deleted file mode 100644 index 6cb3b70..0000000 Binary files a/resources/github-mark.png and /dev/null differ diff --git a/resources/image_comp_4.png b/resources/image_comp_4.png deleted file mode 100644 index d42f575..0000000 Binary files a/resources/image_comp_4.png and /dev/null differ diff --git a/resources/lego_nerf.png b/resources/lego_nerf.png new file mode 100755 index 0000000..539bdb6 Binary files /dev/null and b/resources/lego_nerf.png differ diff --git a/resources/lego_ours.png b/resources/lego_ours.png new file mode 100755 index 0000000..e9d550d Binary files /dev/null and b/resources/lego_ours.png differ diff --git a/resources/method_diagram.png b/resources/method_diagram.png deleted file mode 100644 index 80ce331..0000000 Binary files a/resources/method_diagram.png and /dev/null differ diff --git a/resources/mic_nerf.png b/resources/mic_nerf.png new file mode 100755 index 0000000..3788eba Binary files /dev/null and b/resources/mic_nerf.png differ diff --git a/resources/mic_ours.png b/resources/mic_ours.png new file mode 100755 index 0000000..5a62dc0 Binary files /dev/null and b/resources/mic_ours.png differ diff --git a/resources/nerfacto_kitchen.png b/resources/nerfacto_kitchen.png new file mode 100644 index 0000000..628bffa Binary files /dev/null and b/resources/nerfacto_kitchen.png differ diff --git a/resources/nerfstudio-logo.png b/resources/nerfstudio-logo.png deleted file mode 100644 index 52ba349..0000000 Binary files a/resources/nerfstudio-logo.png and /dev/null differ diff --git a/resources/ours_kitchen.png b/resources/ours_kitchen.png new file mode 100644 index 0000000..3fde958 Binary files /dev/null and b/resources/ours_kitchen.png differ diff --git a/resources/paper.png b/resources/paper.png deleted file mode 100644 index 28614cd..0000000 Binary files a/resources/paper.png and /dev/null differ diff --git a/resources/paper_screenshots/Screenshot from 2023-05-26 13-41-50.png b/resources/paper_screenshots/Screenshot from 2023-05-26 13-41-50.png deleted file mode 100644 index 20e95dd..0000000 Binary files a/resources/paper_screenshots/Screenshot from 2023-05-26 13-41-50.png and /dev/null differ diff --git a/resources/paper_screenshots/Screenshot from 2023-05-26 13-42-14.png b/resources/paper_screenshots/Screenshot from 2023-05-26 13-42-14.png deleted file mode 100644 index 28ffa27..0000000 Binary files a/resources/paper_screenshots/Screenshot from 2023-05-26 13-42-14.png and /dev/null differ diff --git a/resources/paper_screenshots/Screenshot from 2023-05-26 13-42-31.png b/resources/paper_screenshots/Screenshot from 2023-05-26 13-42-31.png deleted file mode 100644 index c63be72..0000000 Binary files a/resources/paper_screenshots/Screenshot from 2023-05-26 13-42-31.png and /dev/null differ diff --git a/resources/real-world-activations(2).png b/resources/real-world-activations(2).png new file mode 100644 index 0000000..03f1ace Binary files /dev/null and b/resources/real-world-activations(2).png differ diff --git a/resources/room_nerfacto.png b/resources/room_nerfacto.png new file mode 100644 index 0000000..46e2ae3 Binary files /dev/null and b/resources/room_nerfacto.png differ diff --git a/resources/room_ours.png b/resources/room_ours.png new file mode 100644 index 0000000..d5a049c Binary files /dev/null and b/resources/room_ours.png differ diff --git a/resources/supp_fig-2.png b/resources/supp_fig-2.png deleted file mode 100644 index a92a3dc..0000000 Binary files a/resources/supp_fig-2.png and /dev/null differ diff --git a/resources/teaser.png b/resources/teaser.png deleted file mode 100644 index 80ce331..0000000 Binary files a/resources/teaser.png and /dev/null differ diff --git a/resources/trex-mip.png b/resources/trex-mip.png new file mode 100644 index 0000000..e72ce6f Binary files /dev/null and b/resources/trex-mip.png differ diff --git a/resources/trex_ours.png b/resources/trex_ours.png new file mode 100644 index 0000000..7d2b780 Binary files /dev/null and b/resources/trex_ours.png differ diff --git a/test/dics.css b/test/dics.css new file mode 100644 index 0000000..81ab949 --- /dev/null +++ b/test/dics.css @@ -0,0 +1,229 @@ +.b-dics { + width : 100%; + max-width : 100%; + position : relative; + overflow : hidden; + display : -webkit-box; + display : -ms-flexbox; + display : flex; + opacity : 0; +} + +.b-dics__section { + height : 100%; +} + +.b-dics__slider:hover :before { + color : #FFFFFF; + border-color : #FFFFFF; +} + +.b-dics__text { + position : absolute; + top : 0; + left : 50%; + padding : 5px 25px; + -webkit-transform : translateX(-50%); + -ms-transform : translateX(-50%); + transform : translateX(-50%); + background : #FFFFFF; + z-index : 11; + font-family : Arial, serif; + color : #3d3d3d; + -webkit-user-select : none; + -moz-user-select : none; + -ms-user-select : none; + user-select : none; + font-size : 13px; + text-align : center; + margin : 16px 0; + white-space : nowrap; + opacity : .7; + pointer-events : none; +} + +.b-dics__image-container { + width : 100%; + height : 100%; + display : block; + overflow : hidden; + position : relative; +} + +.b-dics__image { + height : 100%; + position : absolute; + left : 0; + top : 50%; + -webkit-transform : translateY(-50%); + -ms-transform : translateY(-50%); + transform : translateY(-50%); + -webkit-user-select : none; + -moz-user-select : none; + -ms-user-select : none; + user-select : none; + max-width : none; +} + +.b-dics__slider { + color : #FFFFFF; + position : absolute; + left : 100%; + top : 0; + cursor : pointer; + -webkit-transform : translateX(-50%); + -ms-transform : translateX(-50%); + transform : translateX(-50%); + height : 100%; + width : 3px; + padding : 0 30px; + z-index : 1; + -ms-touch-action : none; + touch-action : none; + line-height : normal; + opacity : .7; +} + +.b-dics__slider:before { + content : ''; + -webkit-mask : url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTEyIDUxMjsiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+LnN0MHtmaWxsOiNGRkZGRkY7ZW5hYmxlLWJhY2tncm91bmQ6bmV3ICAgIDt9PC9zdHlsZT48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMTgwLjIsMTA4LjFsNjEuNy02Mi4yYzMuOC0zLjgsOC44LTUuOSwxNC4xLTUuOWM1LjMsMCwxMC40LDIuMSwxNC4xLDUuOWw2MS43LDYyLjJjMy45LDMuOSw5LjEsNS45LDE0LjIsNS45czEwLjItMS45LDE0LjEtNS44YzcuOC03LjgsNy45LTIwLjQsMC4xLTI4LjNsLTYxLjctNjIuMkMyODcuMiw2LjMsMjcyLjEsMCwyNTYsMHMtMzEuMiw2LjMtNDIuNSwxNy44TDE1MS44LDgwYy03LjgsNy44LTcuNywyMC41LDAuMSwyOC4zQzE1OS44LDExNiwxNzIuNCwxMTUuOSwxODAuMiwxMDguMXoiLz48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMzMxLjgsNDAzLjlsLTYxLjcsNjIuMmMtMy44LDMuOC04LjgsNS45LTE0LjEsNS45Yy01LjMsMC0xMC40LTIuMS0xNC4xLTUuOWwtNjEuNy02Mi4yYy03LjgtNy44LTIwLjQtNy45LTI4LjMtMC4xYy03LjgsNy44LTcuOSwyMC40LTAuMSwyOC4zbDYxLjcsNjIuMmMxMS40LDExLjQsMjYuNSwxNy44LDQyLjUsMTcuOHMzMS4yLTYuMyw0Mi41LTE3LjhsNjEuNy02Mi4yYzcuOC03LjgsNy43LTIwLjUtMC4xLTI4LjNDMzUyLjIsMzk2LDMzOS42LDM5Ni4xLDMzMS44LDQwMy45eiIvPjwvc3ZnPg==) no-repeat 100% 100%; + mask : url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTEyIDUxMjsiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+LnN0MHtmaWxsOiNGRkZGRkY7ZW5hYmxlLWJhY2tncm91bmQ6bmV3ICAgIDt9PC9zdHlsZT48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMTgwLjIsMTA4LjFsNjEuNy02Mi4yYzMuOC0zLjgsOC44LTUuOSwxNC4xLTUuOWM1LjMsMCwxMC40LDIuMSwxNC4xLDUuOWw2MS43LDYyLjJjMy45LDMuOSw5LjEsNS45LDE0LjIsNS45czEwLjItMS45LDE0LjEtNS44YzcuOC03LjgsNy45LTIwLjQsMC4xLTI4LjNsLTYxLjctNjIuMkMyODcuMiw2LjMsMjcyLjEsMCwyNTYsMHMtMzEuMiw2LjMtNDIuNSwxNy44TDE1MS44LDgwYy03LjgsNy44LTcuNywyMC41LDAuMSwyOC4zQzE1OS44LDExNiwxNzIuNCwxMTUuOSwxODAuMiwxMDguMXoiLz48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMzMxLjgsNDAzLjlsLTYxLjcsNjIuMmMtMy44LDMuOC04LjgsNS45LTE0LjEsNS45Yy01LjMsMC0xMC40LTIuMS0xNC4xLTUuOWwtNjEuNy02Mi4yYy03LjgtNy44LTIwLjQtNy45LTI4LjMtMC4xYy03LjgsNy44LTcuOSwyMC40LTAuMSwyOC4zbDYxLjcsNjIuMmMxMS40LDExLjQsMjYuNSwxNy44LDQyLjUsMTcuOHMzMS4yLTYuMyw0Mi41LTE3LjhsNjEuNy02Mi4yYzcuOC03LjgsNy43LTIwLjUtMC4xLTI4LjNDMzUyLjIsMzk2LDMzOS42LDM5Ni4xLDMzMS44LDQwMy45eiIvPjwvc3ZnPg==) no-repeat 100% 100%; + mask-size : cover; + -webkit-mask-size : cover; + width : 26px; + height : 26px; + padding : 0; + background-color : currentColor; + position : absolute; + top : 50%; + left : 50%; + -webkit-transform : translate(-50%, -50%) rotate(90deg); + -ms-transform : translate(-50%, -50%) rotate(90deg); + transform : translate(-50%, -50%) rotate(90deg); + z-index : 2; + font-size : 0; +} + +.b-dics__slider:after { + content : ''; + position : absolute; + left : 50%; + top : 0; + -webkit-transform : translateX(-50%); + -ms-transform : translateX(-50%); + transform : translateX(-50%); + height : 100%; + width : 3px; + background-color : currentColor; + z-index : 1; +} + +.b-dics__image-container:hover .b-dics__text { + opacity : 1; +} + +.b-dics__slider:hover { + opacity : 1; +} + +/* Text Position + ****************************************************************************/ + +.b-dics--tp-center .b-dics__text { + top : 50%; + -webkit-transform : translate(-50%, -50%); + -ms-transform : translate(-50%, -50%); + transform : translate(-50%, -50%); + margin : 0; +} + +.b-dics--tp-bottom .b-dics__text { + top : initial; + bottom : 0; + -webkit-transform : translate(-50%, -50%); + -ms-transform : translate(-50%, -50%); + transform : translate(-50%, -50%); +} + +.b-dics--tp-left .b-dics__text { + left : 0; + top : 50%; + -webkit-transform : translateY(-50%); + -ms-transform : translateY(-50%); + transform : translateY(-50%); + margin : 0 16px; +} + +.b-dics--tp-right .b-dics__text { + left : initial; + right : 0; + top : 50%; + -webkit-transform : translateY(-50%); + -ms-transform : translateY(-50%); + transform : translateY(-50%); + margin : 0 16px; +} + +/* Hide texts + ****************************************************************************/ + +.b-dics--hide-texts .b-dics__text { + background : #ffffff; + opacity : 0; +} + +.b-dics--hide-texts .b-dics__image-container:hover .b-dics__text { + opacity : 1; +} + +/* Vertical Sliders + ****************************************************************************/ + +.b-dics--vertical { + -webkit-box-orient : vertical; + -webkit-box-direction : normal; + -ms-flex-direction : column; + flex-direction : column; +} + +.b-dics--vertical .b-dics__section { + height : auto; + width : 100%; +} + +.b-dics--vertical .b-dics__image { + left : 50%; + -webkit-transform : translateX(-50%); + -ms-transform : translateX(-50%); + transform : translateX(-50%); + top : 0; + width : 100%; + height : auto; +} + +.b-dics--vertical .b-dics__slider { + top : 100%; + -webkit-transform : translateY(-50%); + -ms-transform : translateY(-50%); + transform : translateY(-50%); + width : 100%; + height : 3px; + padding : 30px 0; + left : 0; +} + +.b-dics--vertical .b-dics__slider:after { + top : 50%; + left : 0; + -webkit-transform : translateY(-50%); + -ms-transform : translateY(-50%); + transform : translateY(-50%); + width : 100%; + height : 3px; +} + +.b-dics--vertical .b-dics__slider:before { + -webkit-transform : translate(-50%, -50%); + -ms-transform : translate(-50%, -50%); + transform : translate(-50%, -50%); +} \ No newline at end of file diff --git a/test/dics.js b/test/dics.js new file mode 100644 index 0000000..a3e681c --- /dev/null +++ b/test/dics.js @@ -0,0 +1,621 @@ +"use strict"; + +/* + * Dics: Definitive image comparison slider. A multiple image vanilla comparison slider. + * + * By Abel Cabeza Román, a Codictados developer + * Src: https://github.com/abelcabezaroman/definitive-image-comparison-slider + * Example: http://codictados.com/portfolio/definitive-image-comparison-slider-demo/ + */ + +/** + * + */ + +/** + * + * @type {{container: null, filters: null, hideTexts: null, textPosition: string, linesOrientation: string, rotate: number, arrayBackgroundColorText: null, arrayColorText: null, linesColor: null}} + */ +let defaultOptions = { + container: null, + // **REQUIRED**: HTML container | `document.querySelector('.b-dics')` | + filters: null, + // Array of CSS string filters |`['blur(3px)', 'grayscale(1)', 'sepia(1)', 'saturate(3)']` | + hideTexts: null, + // Show text only when you hover the image container |`true`,`false`| + textPosition: "top", + // Set the prefer text position |`'center'`,`'top'`, `'right'`, `'bottom'`, `'left'` | + linesOrientation: "horizontal", + // Change the orientation of lines |`'horizontal'`,`'vertical'` | + rotate: 0, + // Rotate the image container (not too useful but it's a beatiful effect. String of rotate CSS rule) |`'45deg'`| + arrayBackgroundColorText: null, + // Change the bacground-color of sections texts with an array |`['#000000', '#FFFFFF']`| + arrayColorText: null, + // Change the color of texts with an array |`['#FFFFFF', '#000000']`| + linesColor: null // Change the lines and arrows color |`'rgb(0,0,0)'`| + +}; +/** + * + * @param options + * @constructor + */ + +let Dics = function (options) { + this.options = utils.extend({}, [defaultOptions, options], { + clearEmpty: true + }); + this.container = this.options.container; + + if (this.container == null) { + console.error("Container element not found!"); + } else { + this._setOrientation(this.options.linesOrientation, this.container); + + this.images = this._getImages(); + this.sliders = []; + this._activeSlider = null; + + this._load(this.images[0]); + } +}; +/** + * + * @private + */ + + +Dics.prototype._load = function (firstImage, maxCounter = 100000) { + if (firstImage.naturalWidth) { + this._buidAfterFirstImageLoad(firstImage); + + window.addEventListener("resize", () => { + this._setContainerWidth(firstImage); + + this._resetSizes(); + }); + } else { + if (maxCounter > 0) { + maxCounter--; + setTimeout(() => { + this._load(firstImage, maxCounter); + }, 100); + } else { + console.error("error loading images"); + } + } +}; +/** + * + * @private + */ + + +Dics.prototype._buidAfterFirstImageLoad = function (firstImage) { + this._setContainerWidth(firstImage); + + this._build(); + + this._setEvents(); +}; +/** + * + * @private + */ + + +Dics.prototype._setContainerWidth = function (firstImage) { + this.options.container.style.height = `${this._calcContainerHeight(firstImage)}px`; +}; +/** + * + * @private + */ + + +Dics.prototype._setOpacityContainerForLoading = function (opacity) { + this.options.container.style.opacity = opacity; +}; +/** + * Reset sizes on window size change + * @private + */ + + +Dics.prototype._resetSizes = function () { + let dics = this; + let imagesLength = dics.images.length; + let initialImagesContainerWidth = dics.container.getBoundingClientRect()[dics.config.sizeField] / imagesLength; + const sections$$ = dics.container.querySelectorAll("[data-function='b-dics__section']"); + + for (let i = 0; i < sections$$.length; i++) { + let section$$ = sections$$[i]; + section$$.style.flex = `0 0 ${initialImagesContainerWidth}px`; + section$$.querySelector(".b-dics__image").style[this.config.positionField] = `${i * -initialImagesContainerWidth}px`; + const slider$$ = section$$.querySelector(".b-dics__slider"); + + if (slider$$) { + slider$$.style[this.config.positionField] = `${initialImagesContainerWidth * (i + 1)}px`; + } + } +}; +/** + * Build HTML + * @private + */ + + +Dics.prototype._build = function () { + let dics = this; + + dics._applyGlobalClass(dics.options); + + let imagesLength = dics.images.length; + let initialImagesContainerWidth = dics.container.getBoundingClientRect()[dics.config.sizeField] / imagesLength; + + for (let i = 0; i < imagesLength; i++) { + let image = dics.images[i]; + + let section = dics._createElement("div", "b-dics__section"); + + let imageContainer = dics._createElement("div", "b-dics__image-container"); + + let slider = dics._createSlider(i, initialImagesContainerWidth); + + dics._createAltText(image, i, imageContainer); + + dics._applyFilter(image, i, dics.options.filters); + + dics._rotate(image, imageContainer); + + section.setAttribute("data-function", "b-dics__section"); + section.style.flex = `0 0 ${initialImagesContainerWidth}px`; + image.classList.add("b-dics__image"); + section.appendChild(imageContainer); + imageContainer.appendChild(image); + + if (i < imagesLength - 1) { + section.appendChild(slider); + } + + dics.container.appendChild(section); + image.style[this.config.positionField] = `${i * -initialImagesContainerWidth}px`; + } + + this.sections = this._getSections(); + + this._setOpacityContainerForLoading(1); +}; +/** + * + * @returns {NodeListOf | NodeListOf | NodeListOf} + * @private + */ + + +Dics.prototype._getImages = function () { + return this.container.querySelectorAll("img"); +}; +/** + * + * @returns {NodeListOf | NodeListOf | NodeListOf} + * @private + */ + + +Dics.prototype._getSections = function () { + return this.container.querySelectorAll("[data-function=\"b-dics__section\"]"); +}; +/** + * + * @param elementClass + * @param className + * @returns {HTMLElement | HTMLSelectElement | HTMLLegendElement | HTMLTableCaptionElement | HTMLTextAreaElement | HTMLModElement | HTMLHRElement | HTMLOutputElement | HTMLPreElement | HTMLEmbedElement | HTMLCanvasElement | HTMLFrameSetElement | HTMLMarqueeElement | HTMLScriptElement | HTMLInputElement | HTMLUnknownElement | HTMLMetaElement | HTMLStyleElement | HTMLObjectElement | HTMLTemplateElement | HTMLBRElement | HTMLAudioElement | HTMLIFrameElement | HTMLMapElement | HTMLTableElement | HTMLAnchorElement | HTMLMenuElement | HTMLPictureElement | HTMLParagraphElement | HTMLTableDataCellElement | HTMLTableSectionElement | HTMLQuoteElement | HTMLTableHeaderCellElement | HTMLProgressElement | HTMLLIElement | HTMLTableRowElement | HTMLFontElement | HTMLSpanElement | HTMLTableColElement | HTMLOptGroupElement | HTMLDataElement | HTMLDListElement | HTMLFieldSetElement | HTMLSourceElement | HTMLBodyElement | HTMLDirectoryElement | HTMLDivElement | HTMLUListElement | HTMLHtmlElement | HTMLAreaElement | HTMLMeterElement | HTMLAppletElement | HTMLFrameElement | HTMLOptionElement | HTMLImageElement | HTMLLinkElement | HTMLHeadingElement | HTMLSlotElement | HTMLVideoElement | HTMLBaseFontElement | HTMLTitleElement | HTMLButtonElement | HTMLHeadElement | HTMLParamElement | HTMLTrackElement | HTMLOListElement | HTMLDataListElement | HTMLLabelElement | HTMLFormElement | HTMLTimeElement | HTMLBaseElement} + * @private + */ + + +Dics.prototype._createElement = function (elementClass, className) { + let newElement = document.createElement(elementClass); + newElement.classList.add(className); + return newElement; +}; +/** + * Set need DOM events + * @private + */ + + +Dics.prototype._setEvents = function () { + let dics = this; + + dics._disableImageDrag(); + + dics._isGoingRight = null; + let oldx = 0; + + let listener = function (event) { + let xPageCoord = event.pageX ? event.pageX : event.touches[0].pageX; + + if (xPageCoord < oldx) { + dics._isGoingRight = false; + } else if (xPageCoord > oldx) { + dics._isGoingRight = true; + } + + oldx = xPageCoord; + + let position = dics._calcPosition(event); + + let beforeSectionsWidth = dics._beforeSectionsWidth(dics.sections, dics.images, dics._activeSlider); + + let calcMovePixels = position - beforeSectionsWidth; + dics.sliders[dics._activeSlider].style[dics.config.positionField] = `${position}px`; + + dics._pushSections(calcMovePixels, position); + }; + + dics.container.addEventListener("click", listener); + + for (let i = 0; i < dics.sliders.length; i++) { + let slider = dics.sliders[i]; + utils.setMultiEvents(slider, ["mousedown", "touchstart"], function (event) { + dics._activeSlider = i; + dics._clickPosition = dics._calcPosition(event); + slider.classList.add("b-dics__slider--active"); + utils.setMultiEvents(dics.container, ["mousemove", "touchmove"], listener); + }); + } + + let listener2 = function () { + let activeElements = dics.container.querySelectorAll(".b-dics__slider--active"); + + for (let activeElement of activeElements) { + activeElement.classList.remove("b-dics__slider--active"); + utils.removeMultiEvents(dics.container, ["mousemove", "touchmove"], listener); + } + }; + + utils.setMultiEvents(document.body, ["mouseup", "touchend"], listener2); +}; +/** + * + * @param sections + * @param images + * @param activeSlider + * @returns {number} + * @private + */ + + +Dics.prototype._beforeSectionsWidth = function (sections, images, activeSlider) { + let width = 0; + + for (let i = 0; i < sections.length; i++) { + let section = sections[i]; + + if (i !== activeSlider) { + width += section.getBoundingClientRect()[this.config.sizeField]; + } else { + return width; + } + } +}; +/** + * + * @returns {number} + * @private + */ + + +Dics.prototype._calcContainerHeight = function (firstImage) { + let imgHeight = firstImage.naturalHeight; + let imgWidth = firstImage.naturalWidth; + let containerWidth = this.options.container.getBoundingClientRect().width; + return containerWidth / imgWidth * imgHeight; +}; +/** + * + * @param sections + * @param images + * @private + */ + + +Dics.prototype._setLeftToImages = function (sections, images) { + let size = 0; + + for (let i = 0; i < images.length; i++) { + let image = images[i]; + image.style[this.config.positionField] = `-${size}px`; + size += sections[i].getBoundingClientRect()[this.config.sizeField]; + this.sliders[i].style[this.config.positionField] = `${size}px`; + } +}; +/** + * + * @private + */ + + +Dics.prototype._disableImageDrag = function () { + for (let i = 0; i < this.images.length; i++) { + this.sliders[i].addEventListener("dragstart", function (e) { + e.preventDefault(); + }); + this.images[i].addEventListener("dragstart", function (e) { + e.preventDefault(); + }); + } +}; +/** + * + * @param image + * @param index + * @param filters + * @private + */ + + +Dics.prototype._applyFilter = function (image, index, filters) { + if (filters) { + image.style.filter = filters[index]; + } +}; +/** + * + * @param options + * @private + */ + + +Dics.prototype._applyGlobalClass = function (options) { + let container = options.container; + + if (options.hideTexts) { + container.classList.add("b-dics--hide-texts"); + } + + if (options.linesOrientation === "vertical") { + container.classList.add("b-dics--vertical"); + } + + if (options.textPosition === "center") { + container.classList.add("b-dics--tp-center"); + } else if (options.textPosition === "bottom") { + container.classList.add("b-dics--tp-bottom"); + } else if (options.textPosition === "left") { + container.classList.add("b-dics--tp-left"); + } else if (options.textPosition === "right") { + container.classList.add("b-dics--tp-right"); + } +}; + +Dics.prototype._createSlider = function (i, initialImagesContainerWidth) { + let slider = this._createElement("div", "b-dics__slider"); + + if (this.options.linesColor) { + slider.style.color = this.options.linesColor; + } + + slider.style[this.config.positionField] = `${initialImagesContainerWidth * (i + 1)}px`; + this.sliders.push(slider); + return slider; +}; +/** + * + * @param image + * @param i + * @param imageContainer + * @private + */ + + +Dics.prototype._createAltText = function (image, i, imageContainer) { + let textContent = image.getAttribute("alt"); + + if (textContent) { + let text = this._createElement("p", "b-dics__text"); + + if (this.options.arrayBackgroundColorText) { + text.style.backgroundColor = this.options.arrayBackgroundColorText[i]; + } + + if (this.options.arrayColorText) { + text.style.color = this.options.arrayColorText[i]; + } + + text.appendChild(document.createTextNode(textContent)); + imageContainer.appendChild(text); + } +}; +/** + * + * @param image + * @param imageContainer + * @private + */ + + +Dics.prototype._rotate = function (image, imageContainer) { + image.style.rotate = `-${this.options.rotate}`; + imageContainer.style.rotate = this.options.rotate; +}; +/** + * + * @private + */ + + +Dics.prototype._removeActiveElements = function () { + let activeElements = Dics.container.querySelectorAll(".b-dics__slider--active"); + + for (let activeElement of activeElements) { + activeElement.classList.remove("b-dics__slider--active"); + utils.removeMultiEvents(Dics.container, ["mousemove", "touchmove"], Dics.prototype._removeActiveElements); + } +}; +/** + * + * @param linesOrientation + * @private + */ + + +Dics.prototype._setOrientation = function (linesOrientation) { + this.config = {}; + + if (linesOrientation === "vertical") { + this.config.offsetSizeField = "offsetHeight"; + this.config.offsetPositionField = "offsetTop"; + this.config.sizeField = "height"; + this.config.positionField = "top"; + this.config.clientField = "clientY"; + this.config.pageField = "pageY"; + } else { + this.config.offsetSizeField = "offsetWidth"; + this.config.offsetPositionField = "offsetLeft"; + this.config.sizeField = "width"; + this.config.positionField = "left"; + this.config.clientField = "clientX"; + this.config.pageField = "pageX"; + } +}; +/** + * + * @param event + * @returns {number} + * @private + */ + + +Dics.prototype._calcPosition = function (event) { + let containerCoords = this.container.getBoundingClientRect(); + let pixel = !isNaN(event[this.config.clientField]) ? event[this.config.clientField] : event.touches[0][this.config.clientField]; + return containerCoords[this.config.positionField] < pixel ? pixel - containerCoords[this.config.positionField] : 0; +}; +/** + * + * @private + */ + + +Dics.prototype._pushSections = function (calcMovePixels, position) { + // if (this._rePosUnderActualSections(position)) { + this._setFlex(position, this._isGoingRight); + + let section = this.sections[this._activeSlider]; + let postActualSection = this.sections[this._activeSlider + 1]; + + let sectionWidth = postActualSection.getBoundingClientRect()[this.config.sizeField] - (calcMovePixels - this.sections[this._activeSlider].getBoundingClientRect()[this.config.sizeField]); + + section.style.flex = this._isGoingRight === true ? `2 0 ${calcMovePixels}px` : `1 1 ${calcMovePixels}px`; + postActualSection.style.flex = this._isGoingRight === true ? ` ${sectionWidth}px` : `2 0 ${sectionWidth}px`; + + this._setLeftToImages(this.sections, this.images); // } + +}; +/** + * + * @private + */ + + +Dics.prototype._setFlex = function (position, isGoingRight) { + let beforeSumSectionsSize = 0; + + for (let i = 0; i < this.sections.length; i++) { + let section = this.sections[i]; + const sectionSize = section.getBoundingClientRect()[this.config.sizeField]; + beforeSumSectionsSize += sectionSize; + + if (isGoingRight && position > beforeSumSectionsSize - sectionSize && i > this._activeSlider || !isGoingRight && position < beforeSumSectionsSize && i < this._activeSlider) { + section.style.flex = `1 100 ${sectionSize}px`; + } else { + section.style.flex = `0 0 ${sectionSize}px`; + } + } +}; +/** + * + * @type {{extend: (function(*=, *, *): *), setMultiEvents: setMultiEvents, removeMultiEvents: removeMultiEvents, getConstructor: (function(*=): string)}} + */ + + +let utils = { + /** + * Native extend object + * @param target + * @param objects + * @param options + * @returns {*} + */ + extend: function (target, objects, options) { + for (let object in objects) { + if (objects.hasOwnProperty(object)) { + recursiveMerge(target, objects[object]); + } + } + + function recursiveMerge(target, object) { + for (let property in object) { + if (object.hasOwnProperty(property)) { + let current = object[property]; + + if (utils.getConstructor(current) === "Object") { + if (!target[property]) { + target[property] = {}; + } + + recursiveMerge(target[property], current); + } else { + // clearEmpty + if (options.clearEmpty) { + if (current == null) { + continue; + } + } + + target[property] = current; + } + } + } + } + + return target; + }, + + /** + * Set Multi addEventListener + * @param element + * @param events + * @param func + */ + setMultiEvents: function (element, events, func) { + for (let i = 0; i < events.length; i++) { + element.addEventListener(events[i], func); + } + }, + + /** + * + * @param element + * @param events + * @param func + */ + removeMultiEvents: function (element, events, func) { + for (let i = 0; i < events.length; i++) { + element.removeEventListener(events[i], func, false); + } + }, + + /** + * Get object constructor + * @param object + * @returns {string} + */ + getConstructor: function (object) { + return Object.prototype.toString.call(object).slice(8, -1); + } +}; diff --git a/test/min/dics.min.css b/test/min/dics.min.css new file mode 100644 index 0000000..97c3f90 --- /dev/null +++ b/test/min/dics.min.css @@ -0,0 +1 @@ +.b-dics{width:100%;max-width:100%;position:relative;overflow:hidden;display:-webkit-box;display:-ms-flexbox;display:flex;opacity:0}.b-dics__section{height:100%}.b-dics__slider:hover :before{color:#fff;border-color:#fff}.b-dics__text{position:absolute;top:0;left:50%;padding:5px 25px;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);background:#fff;z-index:11;font-family:Arial,serif;color:#3d3d3d;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:13px;text-align:center;margin:16px 0;white-space:nowrap;opacity:.7;pointer-events:none}.b-dics__image-container{width:100%;height:100%;display:block;overflow:hidden;position:relative}.b-dics__image{height:100%;position:absolute;left:0;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;max-width:none}.b-dics__slider{color:#fff;position:absolute;left:100%;top:0;cursor:pointer;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);height:100%;width:3px;padding:0 30px;z-index:1;-ms-touch-action:none;touch-action:none;line-height:normal;opacity:.7}.b-dics__slider:before{content:'';-webkit-mask:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTEyIDUxMjsiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+LnN0MHtmaWxsOiNGRkZGRkY7ZW5hYmxlLWJhY2tncm91bmQ6bmV3ICAgIDt9PC9zdHlsZT48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMTgwLjIsMTA4LjFsNjEuNy02Mi4yYzMuOC0zLjgsOC44LTUuOSwxNC4xLTUuOWM1LjMsMCwxMC40LDIuMSwxNC4xLDUuOWw2MS43LDYyLjJjMy45LDMuOSw5LjEsNS45LDE0LjIsNS45czEwLjItMS45LDE0LjEtNS44YzcuOC03LjgsNy45LTIwLjQsMC4xLTI4LjNsLTYxLjctNjIuMkMyODcuMiw2LjMsMjcyLjEsMCwyNTYsMHMtMzEuMiw2LjMtNDIuNSwxNy44TDE1MS44LDgwYy03LjgsNy44LTcuNywyMC41LDAuMSwyOC4zQzE1OS44LDExNiwxNzIuNCwxMTUuOSwxODAuMiwxMDguMXoiLz48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMzMxLjgsNDAzLjlsLTYxLjcsNjIuMmMtMy44LDMuOC04LjgsNS45LTE0LjEsNS45Yy01LjMsMC0xMC40LTIuMS0xNC4xLTUuOWwtNjEuNy02Mi4yYy03LjgtNy44LTIwLjQtNy45LTI4LjMtMC4xYy03LjgsNy44LTcuOSwyMC40LTAuMSwyOC4zbDYxLjcsNjIuMmMxMS40LDExLjQsMjYuNSwxNy44LDQyLjUsMTcuOHMzMS4yLTYuMyw0Mi41LTE3LjhsNjEuNy02Mi4yYzcuOC03LjgsNy43LTIwLjUtMC4xLTI4LjNDMzUyLjIsMzk2LDMzOS42LDM5Ni4xLDMzMS44LDQwMy45eiIvPjwvc3ZnPg==) no-repeat 100% 100%;mask:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTEyIDUxMjsiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+LnN0MHtmaWxsOiNGRkZGRkY7ZW5hYmxlLWJhY2tncm91bmQ6bmV3ICAgIDt9PC9zdHlsZT48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMTgwLjIsMTA4LjFsNjEuNy02Mi4yYzMuOC0zLjgsOC44LTUuOSwxNC4xLTUuOWM1LjMsMCwxMC40LDIuMSwxNC4xLDUuOWw2MS43LDYyLjJjMy45LDMuOSw5LjEsNS45LDE0LjIsNS45czEwLjItMS45LDE0LjEtNS44YzcuOC03LjgsNy45LTIwLjQsMC4xLTI4LjNsLTYxLjctNjIuMkMyODcuMiw2LjMsMjcyLjEsMCwyNTYsMHMtMzEuMiw2LjMtNDIuNSwxNy44TDE1MS44LDgwYy03LjgsNy44LTcuNywyMC41LDAuMSwyOC4zQzE1OS44LDExNiwxNzIuNCwxMTUuOSwxODAuMiwxMDguMXoiLz48cGF0aCBjbGFzcz0ic3QwIiBkPSJNMzMxLjgsNDAzLjlsLTYxLjcsNjIuMmMtMy44LDMuOC04LjgsNS45LTE0LjEsNS45Yy01LjMsMC0xMC40LTIuMS0xNC4xLTUuOWwtNjEuNy02Mi4yYy03LjgtNy44LTIwLjQtNy45LTI4LjMtMC4xYy03LjgsNy44LTcuOSwyMC40LTAuMSwyOC4zbDYxLjcsNjIuMmMxMS40LDExLjQsMjYuNSwxNy44LDQyLjUsMTcuOHMzMS4yLTYuMyw0Mi41LTE3LjhsNjEuNy02Mi4yYzcuOC03LjgsNy43LTIwLjUtMC4xLTI4LjNDMzUyLjIsMzk2LDMzOS42LDM5Ni4xLDMzMS44LDQwMy45eiIvPjwvc3ZnPg==) no-repeat 100% 100%;mask-size:cover;-webkit-mask-size:cover;width:26px;height:26px;padding:0;background-color:currentColor;position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%) rotate(90deg);-ms-transform:translate(-50%,-50%) rotate(90deg);transform:translate(-50%,-50%) rotate(90deg);z-index:2;font-size:0}.b-dics__slider:after{content:'';position:absolute;left:50%;top:0;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);height:100%;width:3px;background-color:currentColor;z-index:1}.b-dics__image-container:hover .b-dics__text{opacity:1}.b-dics__slider:hover{opacity:1}.b-dics--tp-center .b-dics__text{top:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);margin:0}.b-dics--tp-bottom .b-dics__text{top:initial;bottom:0;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.b-dics--tp-left .b-dics__text{left:0;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);margin:0 16px}.b-dics--tp-right .b-dics__text{left:initial;right:0;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);margin:0 16px}.b-dics--hide-texts .b-dics__text{background:#fff;opacity:0}.b-dics--hide-texts .b-dics__image-container:hover .b-dics__text{opacity:1}.b-dics--vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.b-dics--vertical .b-dics__section{height:auto;width:100%}.b-dics--vertical .b-dics__image{left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);top:0;width:100%;height:auto}.b-dics--vertical .b-dics__slider{top:100%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);width:100%;height:3px;padding:30px 0;left:0}.b-dics--vertical .b-dics__slider:after{top:50%;left:0;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);width:100%;height:3px}.b-dics--vertical .b-dics__slider:before{-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)} \ No newline at end of file diff --git a/test/min/dics.min.js b/test/min/dics.min.js new file mode 100644 index 0000000..a303863 --- /dev/null +++ b/test/min/dics.min.js @@ -0,0 +1 @@ +let defaultOptions={container:null,filters:null,hideTexts:null,textPosition:"top",linesOrientation:"horizontal",rotate:0,arrayBackgroundColorText:null,arrayColorText:null,linesColor:null},Dics=function(t){this.options=utils.extend({},[defaultOptions,t],{clearEmpty:!0}),this.container=this.options.container,null==this.container?console.error("Container element not found!"):(this._setOrientation(this.options.linesOrientation,this.container),this.images=this._getImages(),this.sliders=[],this._activeSlider=null,this._load(this.images[0]))};Dics.prototype._load=function(t,i=1e5){t.naturalWidth?(this._buidAfterFirstImageLoad(t),window.addEventListener("resize",()=>{this._setContainerWidth(t),this._resetSizes()})):i>0?(i--,setTimeout(()=>{this._load(t,i)},100)):console.error("error loading images")},Dics.prototype._buidAfterFirstImageLoad=function(t){this._setContainerWidth(t),this._build(),this._setEvents()},Dics.prototype._setContainerWidth=function(t){this.options.container.style.height=`${this._calcContainerHeight(t)}px`},Dics.prototype._setOpacityContainerForLoading=function(t){this.options.container.style.opacity=t},Dics.prototype._resetSizes=function(){let t=this.images.length,i=this.container.getBoundingClientRect()[this.config.sizeField]/t;const e=this.container.querySelectorAll("[data-function='b-dics__section']");for(let t=0;ti&&(t._isGoingRight=!0),i=s;let o=t._calcPosition(e),n=o-t._beforeSectionsWidth(t.sections,t.images,t._activeSlider);t.sliders[t._activeSlider].style[t.config.positionField]=`${o}px`,t._pushSections(n,o)};t.container.addEventListener("click",e);for(let i=0;ie-n&&s>this._activeSlider||!i&&t { + this._setContainerWidth(firstImage); + this._resetSizes(); + }); + + } else { + if (maxCounter > 0) { + maxCounter--; + setTimeout(() => { + this._load(firstImage, maxCounter); + }, 100); + } else { + console.error("error loading images"); + } + + } +}; + + +/** + * + * @private + */ +Dics.prototype._buidAfterFirstImageLoad = function(firstImage) { + this._setContainerWidth(firstImage); + + this._build(); + this._setEvents(); +}; + + +/** + * + * @private + */ +Dics.prototype._setContainerWidth = function(firstImage) { + this.options.container.style.height = `${this._calcContainerHeight(firstImage)}px`; +}; + + +/** + * + * @private + */ +Dics.prototype._setOpacityContainerForLoading = function(opacity) { + this.options.container.style.opacity = opacity; +}; + + +/** + * Reset sizes on window size change + * @private + */ +Dics.prototype._resetSizes = function() { + let dics = this; + let imagesLength = dics.images.length; + + let initialImagesContainerWidth = dics.container.getBoundingClientRect()[dics.config.sizeField] / imagesLength; + + const sections$$ = dics.container.querySelectorAll("[data-function='b-dics__section']"); + for (let i = 0; i < sections$$.length; i++) { + let section$$ = sections$$[i]; + + section$$.style.flex = `0 0 ${initialImagesContainerWidth}px`; + + section$$.querySelector(".b-dics__image").style[this.config.positionField] = `${i * -initialImagesContainerWidth}px`; + + const slider$$ = section$$.querySelector(".b-dics__slider"); + if (slider$$) { + slider$$.style[this.config.positionField] = `${initialImagesContainerWidth * (i + 1)}px`; + + } + + } + +}; + +/** + * Build HTML + * @private + */ +Dics.prototype._build = function() { + let dics = this; + + dics._applyGlobalClass(dics.options); + + let imagesLength = dics.images.length; + + + let initialImagesContainerWidth = dics.container.getBoundingClientRect()[dics.config.sizeField] / imagesLength; + + for (let i = 0; i < imagesLength; i++) { + let image = dics.images[i]; + let section = dics._createElement("div", "b-dics__section"); + let imageContainer = dics._createElement("div", "b-dics__image-container"); + let slider = dics._createSlider(i, initialImagesContainerWidth); + + dics._createAltText(image, i, imageContainer); + + dics._applyFilter(image, i, dics.options.filters); + dics._rotate(image, imageContainer); + + + section.setAttribute("data-function", "b-dics__section"); + section.style.flex = `0 0 ${initialImagesContainerWidth}px`; + + image.classList.add("b-dics__image"); + + section.appendChild(imageContainer); + imageContainer.appendChild(image); + + if (i < imagesLength - 1) { + section.appendChild(slider); + } + + dics.container.appendChild(section); + + image.style[this.config.positionField] = `${i * -initialImagesContainerWidth}px`; + + + } + + this.sections = this._getSections(); + this._setOpacityContainerForLoading(1); +}; + + +/** + * + * @returns {NodeListOf | NodeListOf | NodeListOf} + * @private + */ +Dics.prototype._getImages = function() { + return this.container.querySelectorAll("img"); +}; + + +/** + * + * @returns {NodeListOf | NodeListOf | NodeListOf} + * @private + */ +Dics.prototype._getSections = function() { + return this.container.querySelectorAll("[data-function=\"b-dics__section\"]"); +}; + +/** + * + * @param elementClass + * @param className + * @returns {HTMLElement | HTMLSelectElement | HTMLLegendElement | HTMLTableCaptionElement | HTMLTextAreaElement | HTMLModElement | HTMLHRElement | HTMLOutputElement | HTMLPreElement | HTMLEmbedElement | HTMLCanvasElement | HTMLFrameSetElement | HTMLMarqueeElement | HTMLScriptElement | HTMLInputElement | HTMLUnknownElement | HTMLMetaElement | HTMLStyleElement | HTMLObjectElement | HTMLTemplateElement | HTMLBRElement | HTMLAudioElement | HTMLIFrameElement | HTMLMapElement | HTMLTableElement | HTMLAnchorElement | HTMLMenuElement | HTMLPictureElement | HTMLParagraphElement | HTMLTableDataCellElement | HTMLTableSectionElement | HTMLQuoteElement | HTMLTableHeaderCellElement | HTMLProgressElement | HTMLLIElement | HTMLTableRowElement | HTMLFontElement | HTMLSpanElement | HTMLTableColElement | HTMLOptGroupElement | HTMLDataElement | HTMLDListElement | HTMLFieldSetElement | HTMLSourceElement | HTMLBodyElement | HTMLDirectoryElement | HTMLDivElement | HTMLUListElement | HTMLHtmlElement | HTMLAreaElement | HTMLMeterElement | HTMLAppletElement | HTMLFrameElement | HTMLOptionElement | HTMLImageElement | HTMLLinkElement | HTMLHeadingElement | HTMLSlotElement | HTMLVideoElement | HTMLBaseFontElement | HTMLTitleElement | HTMLButtonElement | HTMLHeadElement | HTMLParamElement | HTMLTrackElement | HTMLOListElement | HTMLDataListElement | HTMLLabelElement | HTMLFormElement | HTMLTimeElement | HTMLBaseElement} + * @private + */ +Dics.prototype._createElement = function(elementClass, className) { + let newElement = document.createElement(elementClass); + + newElement.classList.add(className); + + return newElement; +}; + +/** + * Set need DOM events + * @private + */ +Dics.prototype._setEvents = function() { + let dics = this; + + dics._disableImageDrag(); + + dics._isGoingRight = null; + + let oldx = 0; + + let listener = function(event) { + + let xPageCoord = event.pageX ? event.pageX : event.touches[0].pageX; + + if (xPageCoord < oldx) { + dics._isGoingRight = false; + } else if (xPageCoord > oldx) { + dics._isGoingRight = true; + } + + oldx = xPageCoord; + + let position = dics._calcPosition(event); + + let beforeSectionsWidth = dics._beforeSectionsWidth(dics.sections, dics.images, dics._activeSlider); + + let calcMovePixels = position - beforeSectionsWidth; + + dics.sliders[dics._activeSlider].style[dics.config.positionField] = `${position}px`; + + dics._pushSections(calcMovePixels, position); + }; + + dics.container.addEventListener("click", listener); + + for (let i = 0; i < dics.sliders.length; i++) { + let slider = dics.sliders[i]; + utils.setMultiEvents(slider, ["mousedown", "touchstart"], function(event) { + dics._activeSlider = i; + + dics._clickPosition = dics._calcPosition(event); + + slider.classList.add("b-dics__slider--active"); + + utils.setMultiEvents(dics.container, ["mousemove", "touchmove"], listener); + }); + } + + + let listener2 = function() { + let activeElements = dics.container.querySelectorAll(".b-dics__slider--active"); + + for (let activeElement of activeElements) { + activeElement.classList.remove("b-dics__slider--active"); + utils.removeMultiEvents(dics.container, ["mousemove", "touchmove"], listener); + } + }; + + utils.setMultiEvents(document.body, ["mouseup", "touchend"], listener2); + + +}; + +/** + * + * @param sections + * @param images + * @param activeSlider + * @returns {number} + * @private + */ +Dics.prototype._beforeSectionsWidth = function(sections, images, activeSlider) { + let width = 0; + for (let i = 0; i < sections.length; i++) { + let section = sections[i]; + if (i !== activeSlider) { + width += section.getBoundingClientRect()[this.config.sizeField]; + } else { + return width; + } + } +}; + +/** + * + * @returns {number} + * @private + */ +Dics.prototype._calcContainerHeight = function(firstImage) { + let imgHeight = firstImage.naturalHeight; + let imgWidth = firstImage.naturalWidth; + let containerWidth = this.options.container.getBoundingClientRect().width; + + return (containerWidth / imgWidth) * imgHeight; +}; + + +/** + * + * @param sections + * @param images + * @private + */ +Dics.prototype._setLeftToImages = function(sections, images) { + let size = 0; + for (let i = 0; i < images.length; i++) { + let image = images[i]; + + image.style[this.config.positionField] = `-${size}px`; + size += sections[i].getBoundingClientRect()[this.config.sizeField]; + + this.sliders[i].style[this.config.positionField] = `${size}px`; + + } +}; + + +/** + * + * @private + */ +Dics.prototype._disableImageDrag = function() { + for (let i = 0; i < this.images.length; i++) { + this.sliders[i].addEventListener("dragstart", function(e) { + e.preventDefault(); + }); + this.images[i].addEventListener("dragstart", function(e) { + e.preventDefault(); + }); + } +}; + +/** + * + * @param image + * @param index + * @param filters + * @private + */ +Dics.prototype._applyFilter = function(image, index, filters) { + if (filters) { + image.style.filter = filters[index]; + } +}; + +/** + * + * @param options + * @private + */ +Dics.prototype._applyGlobalClass = function(options) { + let container = options.container; + + + if (options.hideTexts) { + container.classList.add("b-dics--hide-texts"); + } + + if (options.linesOrientation === "vertical") { + container.classList.add("b-dics--vertical"); + } + + if (options.textPosition === "center") { + container.classList.add("b-dics--tp-center"); + } else if (options.textPosition === "bottom") { + container.classList.add("b-dics--tp-bottom"); + } else if (options.textPosition === "left") { + container.classList.add("b-dics--tp-left"); + } else if (options.textPosition === "right") { + container.classList.add("b-dics--tp-right"); + } +}; + + +Dics.prototype._createSlider = function(i, initialImagesContainerWidth) { + let slider = this._createElement("div", "b-dics__slider"); + + if (this.options.linesColor) { + slider.style.color = this.options.linesColor; + } + + slider.style[this.config.positionField] = `${initialImagesContainerWidth * (i + 1)}px`; + + this.sliders.push(slider); + + + return slider; +}; + + +/** + * + * @param image + * @param i + * @param imageContainer + * @private + */ +Dics.prototype._createAltText = function(image, i, imageContainer) { + let textContent = image.getAttribute("alt"); + if (textContent) { + let text = this._createElement("p", "b-dics__text"); + + if (this.options.arrayBackgroundColorText) { + text.style.backgroundColor = this.options.arrayBackgroundColorText[i]; + } + if (this.options.arrayColorText) { + text.style.color = this.options.arrayColorText[i]; + } + + text.appendChild(document.createTextNode(textContent)); + + imageContainer.appendChild(text); + } +}; + + +/** + * + * @param image + * @param imageContainer + * @private + */ +Dics.prototype._rotate = function(image, imageContainer) { + image.style.rotate = `-${this.options.rotate}`; + imageContainer.style.rotate = this.options.rotate; + +}; + + +/** + * + * @private + */ +Dics.prototype._removeActiveElements = function() { + let activeElements = Dics.container.querySelectorAll(".b-dics__slider--active"); + + for (let activeElement of activeElements) { + activeElement.classList.remove("b-dics__slider--active"); + utils.removeMultiEvents(Dics.container, ["mousemove", "touchmove"], Dics.prototype._removeActiveElements); + } +}; + + +/** + * + * @param linesOrientation + * @private + */ +Dics.prototype._setOrientation = function(linesOrientation) { + this.config = {}; + + if (linesOrientation === "vertical") { + this.config.offsetSizeField = "offsetHeight"; + this.config.offsetPositionField = "offsetTop"; + this.config.sizeField = "height"; + this.config.positionField = "top"; + this.config.clientField = "clientY"; + this.config.pageField = "pageY"; + } else { + this.config.offsetSizeField = "offsetWidth"; + this.config.offsetPositionField = "offsetLeft"; + this.config.sizeField = "width"; + this.config.positionField = "left"; + this.config.clientField = "clientX"; + this.config.pageField = "pageX"; + } + + +}; + + +/** + * + * @param event + * @returns {number} + * @private + */ +Dics.prototype._calcPosition = function(event) { + let containerCoords = this.container.getBoundingClientRect(); + let pixel = !isNaN(event[this.config.clientField]) ? event[this.config.clientField] : event.touches[0][this.config.clientField]; + + return containerCoords[this.config.positionField] < pixel ? pixel - containerCoords[this.config.positionField] : 0; +}; + + +/** + * + * @private + */ +Dics.prototype._pushSections = function(calcMovePixels, position) { + // if (this._rePosUnderActualSections(position)) { + this._setFlex(position, this._isGoingRight); + + let section = this.sections[this._activeSlider]; + let postActualSection = this.sections[this._activeSlider + 1]; + let sectionWidth = postActualSection.getBoundingClientRect()[this.config.sizeField] - (calcMovePixels - this.sections[this._activeSlider].getBoundingClientRect()[this.config.sizeField]); + + + section.style.flex = this._isGoingRight === true ? `2 0 ${calcMovePixels}px` : `1 1 ${calcMovePixels}px`; + postActualSection.style.flex = this._isGoingRight === true ? ` ${sectionWidth}px` : `2 0 ${sectionWidth}px`; + + this._setLeftToImages(this.sections, this.images); + + // } +}; + + +/** + * + * @private + */ +Dics.prototype._setFlex = function(position, isGoingRight) { + let beforeSumSectionsSize = 0; + + + for (let i = 0; i < this.sections.length; i++) { + let section = this.sections[i]; + const sectionSize = section.getBoundingClientRect()[this.config.sizeField]; + + beforeSumSectionsSize += sectionSize; + + if ((isGoingRight && position > (beforeSumSectionsSize - sectionSize) && i > this._activeSlider) || (!isGoingRight && position < beforeSumSectionsSize) && i < this._activeSlider) { + section.style.flex = `1 100 ${sectionSize}px`; + } else { + section.style.flex = `0 0 ${sectionSize}px`; + } + + } +}; + + +/** + * + * @type {{extend: (function(*=, *, *): *), setMultiEvents: setMultiEvents, removeMultiEvents: removeMultiEvents, getConstructor: (function(*=): string)}} + */ +let utils = { + + + /** + * Native extend object + * @param target + * @param objects + * @param options + * @returns {*} + */ + extend: function(target, objects, options) { + + for (let object in objects) { + if (objects.hasOwnProperty(object)) { + recursiveMerge(target, objects[object]); + } + } + + function recursiveMerge (target, object) { + for (let property in object) { + if (object.hasOwnProperty(property)) { + let current = object[property]; + if (utils.getConstructor(current) === "Object") { + if (!target[property]) { + target[property] = {}; + } + recursiveMerge(target[property], current); + } else { + // clearEmpty + if (options.clearEmpty) { + if (current == null) { + continue; + } + } + target[property] = current; + } + } + } + } + + return target; + }, + + + /** + * Set Multi addEventListener + * @param element + * @param events + * @param func + */ + setMultiEvents: function(element, events, func) { + for (let i = 0; i < events.length; i++) { + element.addEventListener(events[i], func); + } + }, + + + /** + * + * @param element + * @param events + * @param func + */ + removeMultiEvents: function(element, events, func) { + for (let i = 0; i < events.length; i++) { + element.removeEventListener(events[i], func, false); + } + }, + + + /** + * Get object constructor + * @param object + * @returns {string} + */ + getConstructor: function(object) { + return Object.prototype.toString.call(object).slice(8, -1); + } +}; +