@massimo-cassandro/minimo 1.13.0 → 1.14.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/index.js +1 -0
- package/package.json +1 -1
- package/snippets/unsplash-browser-app/README.md +1 -0
- package/snippets/unsplash-browser-app/unsplash-get-imgs.js +404 -0
- package/snippets/unsplash-browser-app/unsplash-get-imgs.module.css +178 -0
- package/snippets/unsplash-browser-app/unsplash-imgs-display.js +195 -0
- package/snippets/unsplash-browser-app/unsplash-imgs-display.module.css +119 -0
- package/snippets/unsplash-browser-app/unsplash-utilities.js +344 -0
- package/src/components/modal-popup/modal-popup.js +3 -0
- package/src/utilities/build-picture-tag.js +228 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { domBuilder, classnames } from '@massimo-cassandro/minimo';
|
|
2
|
+
import { unsplashParams, unsplashPictureTag } from './unsplash-utilities.js';
|
|
3
|
+
import { unsplashGetImgs } from './unsplash-get-imgs.js';
|
|
4
|
+
import * as styles from './unsplash-imgs-display.module.css';
|
|
5
|
+
import imageIcon from '../icons/image.svg?inline';
|
|
6
|
+
|
|
7
|
+
let displayContainer;
|
|
8
|
+
|
|
9
|
+
// elemento .imgDisplayWrapper attualmente trascinato (drag and drop riordinamento)
|
|
10
|
+
let draggedItem = null;
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
// abilita il trascinamento di wrapperEl tramite la maniglia handleEl
|
|
14
|
+
function initSortHandle(handleEl, wrapperEl){
|
|
15
|
+
handleEl.addEventListener('mousedown', () => {
|
|
16
|
+
wrapperEl.draggable = true;
|
|
17
|
+
});
|
|
18
|
+
handleEl.addEventListener('mouseup', () => {
|
|
19
|
+
wrapperEl.draggable = false;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
wrapperEl.addEventListener('dragstart', e => {
|
|
23
|
+
draggedItem = wrapperEl;
|
|
24
|
+
e.dataTransfer.effectAllowed = 'move';
|
|
25
|
+
e.dataTransfer.setData('text/plain', wrapperEl.dataset.imgId);
|
|
26
|
+
wrapperEl.classList.add(styles.dragging);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
wrapperEl.addEventListener('dragend', () => {
|
|
30
|
+
wrapperEl.draggable = false;
|
|
31
|
+
wrapperEl.classList.remove(styles.dragging);
|
|
32
|
+
draggedItem = null;
|
|
33
|
+
updateHiddenFieldOrder();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// aggiorna il value del campo hidden in base al nuovo ordine (DOM) degli .imgDisplayWrapper
|
|
38
|
+
function updateHiddenFieldOrder(){
|
|
39
|
+
const data = JSON.parse(unsplashParams.hiddenField.value || '[]');
|
|
40
|
+
const order = [...displayContainer.querySelectorAll(`.${styles.imgDisplayWrapper}`)]
|
|
41
|
+
.map(el => el.dataset.imgId);
|
|
42
|
+
|
|
43
|
+
data.sort((a, b) => order.indexOf(a.id) - order.indexOf(b.id));
|
|
44
|
+
unsplashParams.hiddenField.value = JSON.stringify(data);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
// markup placeholder
|
|
49
|
+
const placeHolderObjEl = {
|
|
50
|
+
className: styles.placeholder,
|
|
51
|
+
content: imageIcon
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
export function unsplashImgsDisplayInit(){
|
|
56
|
+
|
|
57
|
+
domBuilder([
|
|
58
|
+
|
|
59
|
+
'p.my-0.small Utilizzare il pulsante “Seleziona immagine” per inserire un termine di ricerca e quindi selezionare ' +
|
|
60
|
+
`almeno un’immagine <strong>(massimo ${unsplashParams.maxImgs})</strong>.`,
|
|
61
|
+
'p-my-0.small Se vuoi sostituire una foto, prima rimuovila dall’elenco delle immagini selezionate (qui sotto) ' +
|
|
62
|
+
'e quindi selezionane una nuova.',
|
|
63
|
+
'p.my-0.small Per pubblicare un gruppo, è necessario che sia presente almeno un’immagine; '+
|
|
64
|
+
'<strong>la prima sarà utilizzata come copertina</strong> (puoi variare l’ordinamento, se necessario, trascinando l’icona in fondo ad ogni card immagine).',
|
|
65
|
+
|
|
66
|
+
{
|
|
67
|
+
className: styles.displayContainer,
|
|
68
|
+
callback: el => displayContainer = el
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
className: 'mt-lg text-right',
|
|
72
|
+
children: [
|
|
73
|
+
{
|
|
74
|
+
tag: 'button',
|
|
75
|
+
attrs: {
|
|
76
|
+
class: 'btn btn-outline-secondary',
|
|
77
|
+
type: 'button'
|
|
78
|
+
},
|
|
79
|
+
content: 'Seleziona immagini',
|
|
80
|
+
callback: el => {
|
|
81
|
+
el.addEventListener('click', () => {
|
|
82
|
+
unsplashGetImgs();
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
], unsplashParams.hiddenField, {insertMode: 'before'});
|
|
90
|
+
|
|
91
|
+
// aggiunta displayContainer ad unsplashParams perché utilizzato anche dall'applicazione principale
|
|
92
|
+
unsplashParams.displayContainer = displayContainer;
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
// =>> listener rimozione foto
|
|
96
|
+
displayContainer.addEventListener('click', e => {
|
|
97
|
+
if(e.target.classList.contains(styles.closeBtn)) {
|
|
98
|
+
const imgId = e.target.imgId;
|
|
99
|
+
|
|
100
|
+
e.target.closest(`.${styles.imgDisplayWrapper}`).remove();
|
|
101
|
+
|
|
102
|
+
// aggiornamento value hidden
|
|
103
|
+
let data = JSON.parse(unsplashParams.hiddenField.value || '[]');
|
|
104
|
+
data = data.filter(row => row.id !== imgId);
|
|
105
|
+
unsplashParams.hiddenField.value = JSON.stringify(data);
|
|
106
|
+
|
|
107
|
+
displayContainer.insertAdjacentElement('beforeend', domBuilder([placeHolderObjEl]));
|
|
108
|
+
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// riordinamento via drag and drop (maniglia: styles.sortArea > div)
|
|
113
|
+
// le card sono disposte in griglia su un'unica riga (grid-template-columns: repeat(maxImgs, 1fr)),
|
|
114
|
+
// quindi l'inserimento prima/dopo si basa sulla posizione orizzontale del cursore
|
|
115
|
+
displayContainer.addEventListener('dragover', e => {
|
|
116
|
+
if(!draggedItem) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
e.preventDefault();
|
|
120
|
+
|
|
121
|
+
const targetWrapper = e.target.closest(`.${styles.imgDisplayWrapper}`);
|
|
122
|
+
if(!targetWrapper || targetWrapper === draggedItem) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const rect = targetWrapper.getBoundingClientRect();
|
|
127
|
+
const insertBefore = (e.clientX - rect.left) < rect.width / 2;
|
|
128
|
+
|
|
129
|
+
targetWrapper.parentNode.insertBefore(
|
|
130
|
+
draggedItem,
|
|
131
|
+
insertBefore? targetWrapper : targetWrapper.nextSibling
|
|
132
|
+
);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function unsplashImgsDisplay(data = null){
|
|
137
|
+
|
|
138
|
+
if(data == null) {
|
|
139
|
+
data = JSON.parse(unsplashParams.hiddenField.value || '[]');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
domBuilder([
|
|
144
|
+
...data.map( row => (
|
|
145
|
+
{
|
|
146
|
+
className: styles.imgDisplayWrapper,
|
|
147
|
+
attrs: { 'data-img-id': row.id },
|
|
148
|
+
// inizializzazione trascinamento: a questo punto l'intero sotto-albero
|
|
149
|
+
// (incluso styles.sortArea) è già collegato al wrapper
|
|
150
|
+
// l'intera area sortArea (non solo l'icona al suo interno) fa da maniglia
|
|
151
|
+
callback: el => initSortHandle(el.querySelector(`.${styles.sortArea}`), el),
|
|
152
|
+
children: [
|
|
153
|
+
...unsplashPictureTag(row, {
|
|
154
|
+
width: 300,
|
|
155
|
+
addPopover: true,
|
|
156
|
+
popoverImgWidth: 800,
|
|
157
|
+
imgExtraClass: styles.img,
|
|
158
|
+
imgExtraAttrs: {draggable: 'false'}
|
|
159
|
+
}),
|
|
160
|
+
|
|
161
|
+
{
|
|
162
|
+
className: styles.imgDisplayInfo,
|
|
163
|
+
children: [
|
|
164
|
+
{
|
|
165
|
+
tag: 'ul',
|
|
166
|
+
children: [
|
|
167
|
+
`li ${row.description}`,
|
|
168
|
+
{
|
|
169
|
+
tag: 'li',
|
|
170
|
+
children: [
|
|
171
|
+
row.author_tag
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
tag: 'button',
|
|
178
|
+
className: classnames('btn-close', styles.closeBtn),
|
|
179
|
+
callback: el => el.imgId = row.id
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
{
|
|
185
|
+
className: styles.sortArea,
|
|
186
|
+
children: [
|
|
187
|
+
'div'
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
]
|
|
191
|
+
}
|
|
192
|
+
)),
|
|
193
|
+
...(Array.from({length: unsplashParams.maxImgs - data.length}, () => placeHolderObjEl ))
|
|
194
|
+
], displayContainer, {emptyParent: true});
|
|
195
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
.displayContainer {
|
|
2
|
+
|
|
3
|
+
display: grid;
|
|
4
|
+
grid-template-rows: auto auto auto;
|
|
5
|
+
grid-template-columns: repeat(4, 1fr);
|
|
6
|
+
/* grid-auto-rows: 1fr; */ /* al posto di grid-template-rows */
|
|
7
|
+
/* grid-template: row / col; */
|
|
8
|
+
grid-auto-flow: row;
|
|
9
|
+
gap: 1.5rem;
|
|
10
|
+
/* align-items: center; */
|
|
11
|
+
/* justify-items: start; */
|
|
12
|
+
min-height: 0;
|
|
13
|
+
padding: .3rem;
|
|
14
|
+
|
|
15
|
+
margin-block: 1.5rem;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.imgDisplayWrapper, .placeholder {
|
|
19
|
+
grid-row: span 3;
|
|
20
|
+
border-radius: var(--ada-border-radius);
|
|
21
|
+
}
|
|
22
|
+
.placeholder {
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
min-height: 10rem;
|
|
27
|
+
background-color: var(--ada-grigio-1);
|
|
28
|
+
border: 1px solid var(--ada-grigio-3);
|
|
29
|
+
opacity: .7;
|
|
30
|
+
svg {
|
|
31
|
+
width: 3rem;
|
|
32
|
+
fill: var(--ada-grigio-3);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.imgDisplayWrapper {
|
|
37
|
+
position: relative;
|
|
38
|
+
display: grid;
|
|
39
|
+
grid-template-rows: subgrid;
|
|
40
|
+
gap: .3rem;
|
|
41
|
+
padding: 0;
|
|
42
|
+
overflow: hidden;
|
|
43
|
+
background-color: var(--ada-body-bg);
|
|
44
|
+
border: 1px solid var(--ada-grigio-2);
|
|
45
|
+
box-shadow: var(--ada-box-shadow);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.img {
|
|
49
|
+
display: block;
|
|
50
|
+
width: 100%;
|
|
51
|
+
height: 200px;
|
|
52
|
+
/* padding: .3rem; */
|
|
53
|
+
object-fit: cover;
|
|
54
|
+
object-position: center;
|
|
55
|
+
}
|
|
56
|
+
.imgDisplayInfo {
|
|
57
|
+
padding: .5rem;
|
|
58
|
+
|
|
59
|
+
ul {
|
|
60
|
+
padding: 0;
|
|
61
|
+
margin: 0;
|
|
62
|
+
list-style: none;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
.closeBtn {
|
|
66
|
+
position: absolute;
|
|
67
|
+
top: .5rem;
|
|
68
|
+
right: .5rem;
|
|
69
|
+
padding: .4rem;
|
|
70
|
+
background-color: var(--ada-body-bg);
|
|
71
|
+
border: 1px solid var(--ada-grigio-4);
|
|
72
|
+
border-radius: 50%;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.sortArea {
|
|
76
|
+
display: flex;
|
|
77
|
+
align-items: center;
|
|
78
|
+
justify-content: center;
|
|
79
|
+
padding: .4rem;
|
|
80
|
+
margin: .2rem;
|
|
81
|
+
cursor: grab;
|
|
82
|
+
border-radius: var(--ada-border-radius);
|
|
83
|
+
|
|
84
|
+
@media (hover: hover) {
|
|
85
|
+
&:hover {
|
|
86
|
+
background-color: var(--ada-grigio-1);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
&:active {
|
|
91
|
+
cursor: grabbing;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
> div {
|
|
95
|
+
position: relative;
|
|
96
|
+
|
|
97
|
+
&, &::after, &::before {
|
|
98
|
+
width: 2px;
|
|
99
|
+
height: 20px;
|
|
100
|
+
background-color: var(--ada-grigio-4);
|
|
101
|
+
}
|
|
102
|
+
&::after, &::before {
|
|
103
|
+
position: absolute;
|
|
104
|
+
top: 0;
|
|
105
|
+
content: '';
|
|
106
|
+
}
|
|
107
|
+
&::before {
|
|
108
|
+
left: -6px;
|
|
109
|
+
}
|
|
110
|
+
&::after {
|
|
111
|
+
right: -6px;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.dragging {
|
|
117
|
+
cursor: grabbing;
|
|
118
|
+
opacity: .4;
|
|
119
|
+
}
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
// estrae da un oggetto result di una singola riga, le informazioni necessarie
|
|
2
|
+
// all'applicazione e dove necessario esegue piccole post-eleborazioni
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
raw data:
|
|
6
|
+
|
|
7
|
+
{
|
|
8
|
+
"id": "uNvgvo2cs7k",
|
|
9
|
+
"alternative_slugs": {...},
|
|
10
|
+
"created_at": "2018-04-10T13:00:44Z",
|
|
11
|
+
"updated_at": "2026-07-06T07:30:35Z",
|
|
12
|
+
"promoted_at": "2018-04-11T07:34:53Z",
|
|
13
|
+
"width": 3840,
|
|
14
|
+
"height": 2565,
|
|
15
|
+
"color": "#26260c",
|
|
16
|
+
"blur_hash": "LoGuj:IVaKWX~XIqWBf6x]NeWDo0",
|
|
17
|
+
"description": null,
|
|
18
|
+
"breadcrumbs": [],
|
|
19
|
+
"urls": {
|
|
20
|
+
"raw" : "https://images.unsplash.com/photo-1523365154888-8a758819b722?ixid=M3w5OTA3Mjh8MHwxfHNlYXJjaHwxfHxTaWNpbGlhfGl0fDF8MHx8fDE3ODMzMzA5NTN8MA&ixlib=rb-4.1.0",
|
|
21
|
+
"full" : "...",
|
|
22
|
+
"regular" : "...",
|
|
23
|
+
"small" : "...",
|
|
24
|
+
"thumb" : "...",
|
|
25
|
+
"small_s3" : "..."
|
|
26
|
+
},
|
|
27
|
+
"likes": 1001,
|
|
28
|
+
"liked_by_user": false,
|
|
29
|
+
"bookmarked": false,
|
|
30
|
+
"current_user_collections": [],
|
|
31
|
+
"sponsorship": null,
|
|
32
|
+
"topic_submissions": {...},
|
|
33
|
+
"asset_type": "photo",
|
|
34
|
+
"slug": "photo-of-house-near-cliff-and-body-of-water-uNvgvo2cs7k",
|
|
35
|
+
"alt_description": "photo of house near cliff and body of water",
|
|
36
|
+
"links": {
|
|
37
|
+
"html": "https://unsplash.com/photos/photo-of-house-near-cliff-and-body-of-water-uNvgvo2cs7k",
|
|
38
|
+
"self": "...",
|
|
39
|
+
"download": "...",
|
|
40
|
+
"download_location": "..."
|
|
41
|
+
},
|
|
42
|
+
"user": {
|
|
43
|
+
...
|
|
44
|
+
"links": {
|
|
45
|
+
"html": "https://unsplash.com/@samferrara"
|
|
46
|
+
"self": "...",
|
|
47
|
+
"photos": "...",
|
|
48
|
+
"likes": "...",
|
|
49
|
+
},
|
|
50
|
+
"profile_image": {..},
|
|
51
|
+
...
|
|
52
|
+
"social": {...}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
import { getAppData } from '@src/index.js';
|
|
59
|
+
import { randomId, classnames } from '@massimo-cassandro/minimo';
|
|
60
|
+
|
|
61
|
+
import * as styles from './unsplash-get-imgs.module.css';
|
|
62
|
+
|
|
63
|
+
export const unsplashParams = {
|
|
64
|
+
maxImgs: 4, // numero massimo di immagini totali
|
|
65
|
+
hiddenField : document.getElementById('infoImmagini')
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
// Default query parameters for the Unsplash /search/photos endpoint.
|
|
71
|
+
// All params are optional except `query` (passed at call time).
|
|
72
|
+
const defaultUnsplashParams = {
|
|
73
|
+
per_page: 18, // results per page — max: 30
|
|
74
|
+
// order_by: 'relevant', // "relevant" | "latest"
|
|
75
|
+
content_filter: 'high', // "low" | "high" — filters explicit content
|
|
76
|
+
orientation: 'landscape', // "landscape" | "portrait" | "squarish"
|
|
77
|
+
lang: 'it',
|
|
78
|
+
|
|
79
|
+
// Other available params (not set by default):
|
|
80
|
+
// page : (int) — page number, default 1
|
|
81
|
+
// color : (string) — "black_and_white" | "black" | "white" | "yellow" |
|
|
82
|
+
// "orange" | "red" | "purple" | "magenta" |
|
|
83
|
+
// "green" | "teal" | "blue"
|
|
84
|
+
// collections : (string) — comma-separated collection IDs to narrow results
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
,app_data = getAppData()
|
|
88
|
+
,SEARCH_API = app_data.apps + '/unsplash-browser'
|
|
89
|
+
;
|
|
90
|
+
|
|
91
|
+
export function setRequestUrl(query, page = null) {
|
|
92
|
+
const searchParams = new URLSearchParams({
|
|
93
|
+
query,
|
|
94
|
+
...defaultUnsplashParams,
|
|
95
|
+
...(page? {page} : {})
|
|
96
|
+
});
|
|
97
|
+
return `${SEARCH_API}?${searchParams}`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
export function parseUnsplashResult(data){
|
|
102
|
+
|
|
103
|
+
const img_data = {
|
|
104
|
+
id : data.id,
|
|
105
|
+
color : data.color,
|
|
106
|
+
width : data.width,
|
|
107
|
+
height : data.height,
|
|
108
|
+
// description : data.description,
|
|
109
|
+
// location : data.location.name,
|
|
110
|
+
alt_description : data.alt_description,
|
|
111
|
+
// created_at : data.created_at,
|
|
112
|
+
raw_url : data.urls?.raw,
|
|
113
|
+
unsplash_url : data.links.html,
|
|
114
|
+
author : data.user?.name?? data.user?.username,
|
|
115
|
+
author_profile_url : data.user?.links?.html,
|
|
116
|
+
blur_hash : data.blur_hash,
|
|
117
|
+
description : (() => {
|
|
118
|
+
let location = data.location?.name?? data.location?.city,
|
|
119
|
+
description = data.description?? data.alt_description;
|
|
120
|
+
if(data.description && location) {
|
|
121
|
+
location = (new RegExp(location, 'i')).test(description)? null : location;
|
|
122
|
+
}
|
|
123
|
+
return [description, location]
|
|
124
|
+
.filter(i => i != null).join (' / ');
|
|
125
|
+
})()
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const author_profile_url = new URL(img_data.author_profile_url);
|
|
129
|
+
author_profile_url.search = new URLSearchParams({ utm_source: 'xxxxxx', utm_medium: 'referral' });
|
|
130
|
+
img_data.author_profile_full_url = author_profile_url.toString();
|
|
131
|
+
|
|
132
|
+
img_data.author_tag = {
|
|
133
|
+
tag: 'a',
|
|
134
|
+
attrs: {
|
|
135
|
+
href: img_data.author_profile_full_url,
|
|
136
|
+
target: '_blank',
|
|
137
|
+
rel: 'noopener noreferrer'
|
|
138
|
+
},
|
|
139
|
+
content: `${img_data.author} / Unsplash`,
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
return img_data;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
// restituisce l'array domBuilder per la costruizione di un tag picture da un'immagine unsplah
|
|
148
|
+
// NB con dati preelaborati da parseUnsplashResult
|
|
149
|
+
// https://unsplash.com/documentation#supported-parameters
|
|
150
|
+
// https://docs.imgix.com/apis/rendering/size/w
|
|
151
|
+
// https://docs.imgix.com/apis/rendering/size/h
|
|
152
|
+
// https://docs.imgix.com/apis/rendering/size/ar
|
|
153
|
+
// https://docs.imgix.com/apis/rendering/size/fit
|
|
154
|
+
// https://docs.imgix.com/apis/rendering/size/crop
|
|
155
|
+
// https://docs.imgix.com/apis/rendering/format/q
|
|
156
|
+
// https://docs.imgix.com/en-US/apis/rendering/device-pixel-ratio
|
|
157
|
+
|
|
158
|
+
export function unsplashPictureTag(img_data, options = {}){
|
|
159
|
+
|
|
160
|
+
options = {
|
|
161
|
+
fixedRatio: true, // utilizza l'aspect ratio originale della foto
|
|
162
|
+
width: 300,
|
|
163
|
+
pictureExtraClass: null,
|
|
164
|
+
pictureExtraAttrs: {},
|
|
165
|
+
imgExtraClass: null,
|
|
166
|
+
imgExtraAttrs: null,
|
|
167
|
+
addPopover: true,
|
|
168
|
+
popoverImgWidth: 600,
|
|
169
|
+
|
|
170
|
+
...options
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const formats = ['avif', 'webp', 'pjpg'] // `fmt` parameter, in order of use
|
|
174
|
+
,base_url = new URL(img_data.raw_url)
|
|
175
|
+
,searchParams = new URLSearchParams(base_url.search)
|
|
176
|
+
,img_params = [['q', '60']]
|
|
177
|
+
;
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
if(options.fixedRatio) {
|
|
181
|
+
img_params.push(
|
|
182
|
+
['w', options.width],
|
|
183
|
+
// ['fit', 'crop'],
|
|
184
|
+
// ['crop', 'faces,entropy,edges']
|
|
185
|
+
);
|
|
186
|
+
img_params.forEach(param => searchParams.set(...param));
|
|
187
|
+
|
|
188
|
+
// nome univoco per l'associazione anchor (Anchor Positioning API) tra thumb e popover di ingrandimento
|
|
189
|
+
const zoomAnchorName = `--unsplash-zoom-${randomId()}`;
|
|
190
|
+
|
|
191
|
+
// riferimento al popover di ingrandimento, valorizzato dalla sua callback domBuilder
|
|
192
|
+
// (usato nel listener click della thumb, eseguito solo dopo che l'intera figure è stata costruita)
|
|
193
|
+
let zoomPopoverEl;
|
|
194
|
+
|
|
195
|
+
return [
|
|
196
|
+
{
|
|
197
|
+
tag: 'picture',
|
|
198
|
+
className: options.pictureExtraClass,
|
|
199
|
+
attrs: {
|
|
200
|
+
style: options.addPopover? `anchor-name: ${zoomAnchorName};` : null,
|
|
201
|
+
...options.pictureExtraAttrs
|
|
202
|
+
},
|
|
203
|
+
children: formats.map(fmt => {
|
|
204
|
+
const is_default_fmt = fmt === formats.at(-1);
|
|
205
|
+
const srcsetArray= [];
|
|
206
|
+
|
|
207
|
+
searchParams.set('fm', fmt);
|
|
208
|
+
|
|
209
|
+
[1,2,3].forEach(dpr => {
|
|
210
|
+
searchParams.set('dpr', dpr);
|
|
211
|
+
base_url.search = searchParams.toString();
|
|
212
|
+
srcsetArray.push(base_url.toString() +` ${dpr}x`);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
if(is_default_fmt) {
|
|
216
|
+
|
|
217
|
+
return {
|
|
218
|
+
tag: 'img',
|
|
219
|
+
className: classnames(options.imgExtraClass, options.addPopover && styles.hasPopover),
|
|
220
|
+
attrs: {
|
|
221
|
+
alt: img_data.alt_description?? `${img_data.author} / Unsplash`,
|
|
222
|
+
src: srcsetArray[0],
|
|
223
|
+
srcset: srcsetArray.join(','),
|
|
224
|
+
width: options.width,
|
|
225
|
+
// height:
|
|
226
|
+
...options.imgExtraAttrs
|
|
227
|
+
},
|
|
228
|
+
callback: options.addPopover
|
|
229
|
+
? el => el.addEventListener('click', () => zoomPopoverEl.togglePopover())
|
|
230
|
+
: null
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
} else {
|
|
234
|
+
return {
|
|
235
|
+
tag: 'source',
|
|
236
|
+
attrs: {
|
|
237
|
+
srcset: srcsetArray.join(','),
|
|
238
|
+
type: `image/${fmt}`,
|
|
239
|
+
// width:
|
|
240
|
+
// height:
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
})
|
|
246
|
+
},
|
|
247
|
+
// popover di ingrandimento (Popover API + Anchor Positioning API)
|
|
248
|
+
...(options.addPopover
|
|
249
|
+
? [{
|
|
250
|
+
tag: 'div',
|
|
251
|
+
className: styles.zoomPopover,
|
|
252
|
+
attrs: {
|
|
253
|
+
popover: 'auto',
|
|
254
|
+
style: `position-anchor: ${zoomAnchorName};`
|
|
255
|
+
},
|
|
256
|
+
callback: el => zoomPopoverEl = el,
|
|
257
|
+
children: unsplashPictureTag(img_data, {width: options.popoverImgWidth, imgExtraClass: styles.popoverImg, addPopover: false})
|
|
258
|
+
}]
|
|
259
|
+
: []
|
|
260
|
+
)
|
|
261
|
+
];
|
|
262
|
+
|
|
263
|
+
} else {
|
|
264
|
+
|
|
265
|
+
// img_params.push(
|
|
266
|
+
// ['fit', 'crop'],
|
|
267
|
+
// ['crop', 'faces,entropy,edges'], // top, bottom, left, right, faces, focalpoint, edges, and entropy
|
|
268
|
+
// );
|
|
269
|
+
// const sizes = [
|
|
270
|
+
// {w: 2560, ratio: 16/9},
|
|
271
|
+
// {w: 1920, ratio: 16/9},
|
|
272
|
+
// {w: 1400, ratio: 16/9},
|
|
273
|
+
// {w: 1280, ratio: 16/9},
|
|
274
|
+
// {w: 1024, ratio: 4/3},
|
|
275
|
+
// {w: 760, ratio: 4/3},
|
|
276
|
+
// {w: 400, ratio: 9/21},
|
|
277
|
+
// ].map(size => ({...size, h: Math.ceil(size.w / size.ratio)}) );
|
|
278
|
+
|
|
279
|
+
// console.log(sizes);
|
|
280
|
+
|
|
281
|
+
// const sizesAttr = sizes.map(s => `(width <= ${s.w}px and min-aspect-ratio: ${s.ratio.toFixed(3)}) ${s.w}px`).join(',');
|
|
282
|
+
// img_params.forEach(param => searchParams.set(...param));
|
|
283
|
+
|
|
284
|
+
// return [
|
|
285
|
+
// {
|
|
286
|
+
// tag: 'picture',
|
|
287
|
+
// children: formats.map(fmt => {
|
|
288
|
+
// const is_default_fmt = fmt === formats.at(-1);
|
|
289
|
+
|
|
290
|
+
// const srcsetArray = [];
|
|
291
|
+
// searchParams.set('fmt', fmt);
|
|
292
|
+
|
|
293
|
+
// sizes.forEach(size => {
|
|
294
|
+
// searchParams.set('w', size.w);
|
|
295
|
+
// searchParams.set('h', size.h);
|
|
296
|
+
// base_url.search = searchParams.toString();
|
|
297
|
+
// srcsetArray.push({url: base_url.toString(), size: size.w});
|
|
298
|
+
// });
|
|
299
|
+
|
|
300
|
+
// const srcsetAttr = srcsetArray.map(item => `${item.url} ${item.size}w`).join(',');
|
|
301
|
+
|
|
302
|
+
// if(is_default_fmt) {
|
|
303
|
+
|
|
304
|
+
// return {
|
|
305
|
+
// tag: 'img',
|
|
306
|
+
// className: 'up-img',
|
|
307
|
+
// attrs: {
|
|
308
|
+
// srcset: srcsetAttr,
|
|
309
|
+
// sizes: sizesAttr,
|
|
310
|
+
// alt: img_data.alt_description?? `${img_data.author} / Unsplash`,
|
|
311
|
+
// src: srcsetArray[Math.floor(srcsetArray.length / 2)].url,
|
|
312
|
+
|
|
313
|
+
// // width e height non necessari (e scorretti visto le differenti proporzioni delle varie foto)
|
|
314
|
+
// // le dimesnioni sono gestite nel css
|
|
315
|
+
// // width:
|
|
316
|
+
// // height:
|
|
317
|
+
// }
|
|
318
|
+
// };
|
|
319
|
+
|
|
320
|
+
// } else {
|
|
321
|
+
// return {
|
|
322
|
+
// tag: 'source',
|
|
323
|
+
// attrs: {
|
|
324
|
+
// srcset: srcsetAttr,
|
|
325
|
+
// sizes: sizesAttr,
|
|
326
|
+
// type: `image/${fmt}`,
|
|
327
|
+
// // width:
|
|
328
|
+
// // height:
|
|
329
|
+
// }
|
|
330
|
+
// };
|
|
331
|
+
// }
|
|
332
|
+
|
|
333
|
+
// })
|
|
334
|
+
// }
|
|
335
|
+
// ];
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
// helper testo pulsante aggiuni/rimuovi img
|
|
342
|
+
export function setImgBtnText(imgIsSelected) {
|
|
343
|
+
return imgIsSelected? 'Rimuovi' : 'Seleziona';
|
|
344
|
+
}
|
|
@@ -52,6 +52,9 @@ function closeDialog(el) {
|
|
|
52
52
|
* @param {string | any[] | null} [params.footerContent=null] - Footer content: plain text, HTML, or a domBuilder array.
|
|
53
53
|
* @returns {HTMLDialogElement} The dialog element.
|
|
54
54
|
*/
|
|
55
|
+
|
|
56
|
+
// TODO attributi arua anche sul triggerm vedi ada-frontend/src/modal-dialog/modal-dialog.js
|
|
57
|
+
|
|
55
58
|
export function modalPopup({
|
|
56
59
|
|
|
57
60
|
/** dialog extra class */
|