| |
| handleiding_nieuw:sub_kengetallenbeelden [2025/10/28 14:26] – support | handleiding_nieuw:sub_kengetallenbeelden [2026/02/12 15:36] (current) – external edit 127.0.0.1 |
|---|
| flex: 1; | flex: 1; |
| } | } |
| .overzicht { | |
| | |
| | .overzicht { |
| background-color: #f8f8f8; | background-color: #f8f8f8; |
| border: 1px solid #ccc; | border: 1px solid #ccc; |
| margin: 2em 0; | margin: 2em 0; |
| } | } |
| | |
| | /* 3-koloms lijst */ |
| .overzicht ul { | .overzicht ul { |
| padding-left: 1em; | |
| list-style: none; | list-style: none; |
| | padding-left: 0; |
| | margin: 0.6em 0 0; |
| | display: grid; |
| | grid-template-columns: repeat(3, minmax(0, 1fr)); |
| | gap: 0.35em 1.4em; |
| } | } |
| | |
| .overzicht li { | .overzicht li { |
| display: flex; | margin: 0; |
| align-items: center; | padding: 0; |
| gap: 10px; | |
| margin-bottom: 0.5em; | |
| } | } |
| .overzicht li img { | |
| width: 50px; | .overzicht a { |
| height: auto; | display: inline-block; |
| border-radius: 4px; | text-decoration: none; |
| border: 1px solid #ccc; | |
| } | } |
| | |
| | .overzicht a:hover { |
| | text-decoration: underline; |
| | } |
| | |
| | /* Responsive: 2 kolommen / 1 kolom */ |
| | @media (max-width: 900px) { |
| | .overzicht ul { grid-template-columns: repeat(2, minmax(0, 1fr)); } |
| | } |
| | @media (max-width: 600px) { |
| | .overzicht ul { grid-template-columns: repeat(1, minmax(0, 1fr)); } |
| | } |
| | |
| | |
| .projectblok { | .projectblok { |
| display: none; | display: none; |
| .project-dot:hover { | .project-dot:hover { |
| background-color: #0022aa; | background-color: #0022aa; |
| | } |
| | |
| | .project-dot.highlight { |
| | transform: translate(-50%, -50%) scale(1.3); |
| | box-shadow: 0 0 0 2px rgba(0,85,255,0.18); |
| | background-color: #2f6df6; |
| | z-index: 50; |
| | } |
| | |
| | /* COLLAGE */ |
| | |
| | .collagebox{ |
| | background:#fafafa; |
| | border:1px solid #ddd; |
| | padding:12px; |
| | margin: 1.2em 0 1.8em; |
| | } |
| | .collage-controls{ |
| | display:flex; |
| | align-items:center; |
| | flex-wrap:wrap; |
| | gap:8px; |
| | margin-bottom:10px; |
| | } |
| | .collage-grid{ |
| | display:grid; |
| | grid-template-columns: repeat(6, minmax(0, 1fr)); |
| | gap:10px; |
| | } |
| | .collage-card{ |
| | border:1px solid #ddd; |
| | border-radius:8px; |
| | overflow:hidden; |
| | background:white; |
| | cursor:pointer; |
| | transition: transform 0.08s ease; |
| | height: 210px; /* ⬅️ vaste tegelhoogte */ |
| | display: flex; |
| | flex-direction: column; |
| | } |
| | .collage-card:hover{ transform: translateY(-1px); } |
| | .collage-card img{ |
| | width:100%; |
| | height:150px; |
| | object-fit:cover; |
| | flex-shrink: 0; /* ⬅️ beeld krimpt niet */ |
| | display:block; |
| | } |
| | .collage-meta{ |
| | padding:4px 6px; |
| | font-size:10px; |
| | line-height:1.15; |
| | height:60px; /* ⬅️ vaste teksthoogte */ |
| | overflow:hidden; /* ⬅️ niets duwt de tegel groter */ |
| | } |
| | .collage-meta .title{ |
| | font-weight:600; |
| | font-size:10.5px; |
| | margin-bottom:2px; |
| | display:block; |
| | white-space: nowrap; |
| | overflow: hidden; |
| | text-overflow: ellipsis; |
| | } |
| | .collage-meta .kpi{ |
| | color:#444; |
| | font-family: sans-serif; |
| | } |
| | |
| | @media (max-width:1100px){ .collage-grid{ grid-template-columns: repeat(4, minmax(0,1fr)); } } |
| | @media (max-width:800px){ .collage-grid{ grid-template-columns: repeat(3, minmax(0,1fr)); } } |
| | @media (max-width:520px){ .collage-grid{ grid-template-columns: repeat(2, minmax(0,1fr)); } } |
| | |
| | /* Export header (alleen zichtbaar bij export) */ |
| | #collageExportArea{ |
| | background: #fff; /* export graag wit */ |
| | padding: 0; /* header regelt padding */ |
| | } |
| | |
| | .collage-export-header{ |
| | border: 1px solid #ddd; |
| | border-radius: 10px; |
| | padding: 10px 12px; |
| | margin-bottom: 10px; |
| | background: #ffffff; |
| | font-family: sans-serif; |
| | } |
| | |
| | .collage-export-title{ |
| | font-size: 14px; |
| | font-weight: 700; |
| | margin: 0 0 4px 0; |
| | } |
| | |
| | .collage-export-sub{ |
| | font-size: 11px; |
| | color: #333; |
| | margin: 0; |
| | line-height: 1.3; |
| | } |
| | |
| | .collage-export-sub .muted{ |
| | color: #666; |
| | } |
| | |
| | button.generate-collage { |
| | background-color: #1f6fd6; /* Sumsonite-blauw */ |
| | color: #0b2a55 !important; |
| | border: 1px solid #1f6fd6; |
| | border-radius: 6px; |
| | padding: 0.45em 1.2em; |
| | font-weight: 600; |
| | cursor: pointer; |
| | transition: background-color 0.15s ease, box-shadow 0.15s ease; |
| | } |
| | |
| | button.generate-collage:hover { |
| | background-color: #155bb3; |
| | color: #0b2a55 !important; |
| | box-shadow: 0 2px 6px rgba(0,0,0,0.15); |
| | } |
| | |
| | button.generate-collage:active { |
| | background-color: #0f4a99; |
| } | } |
| |
| Beeldenbank Stedelijke Dichtheden | Beeldenbank Stedelijke Dichtheden |
| </h2> | </h2> |
| | |
| | <!-- RESPONSIVE VOOR MOBIELE TELEFOONS --> |
| | <div class="mobile-hint"> |
| | <strong>Let op (mobiele weergave)</strong><br> |
| | Deze pagina bevat interactieve grafieken en tabellen die zijn ontworpen voor gebruik op een groter scherm. |
| | Voor een beter overzicht kun je je telefoon liggend houden of deze pagina openen op een tablet of laptop. |
| | </div> |
| | |
| <div class="filter-buttons"> | <div class="filter-buttons"> |
| <button onclick="resetFilters()">Reset filters</button> | <button onclick="resetFilters()">Reset filters</button> |
| </div> | </div> |
| </div> | </div> |
| | |
| |
| <div class="overzicht"> | <div class="overzicht"> |
| |
| |
| | <div class="collagebox"> |
| | <div class="collage-controls"> |
| | <strong>Fotocollage (snel vergelijken)</strong> |
| |
| | <label style="margin-left:12px;"> |
| | Sorteer op: |
| | <select id="collageSort"> |
| | <option value="fsi">FSI (laag → hoog)</option> |
| | <option value="gsi">GSI (laag → hoog)</option> |
| | <option value="osr">OSR (laag → hoog)</option> |
| | </select> |
| | </label> |
| |
| <!--------------- PROJECTEN -----------------> | <label style="margin-left:12px;"> |
| | Richting: |
| | <select id="collageDir"> |
| | <option value="asc">oplopend</option> |
| | <option value="desc">aflopend</option> |
| | </select> |
| | </label> |
| |
| | <label style="margin-left:12px;"> |
| | Max: |
| | <select id="collageLimit"> |
| | <option value="12">12</option> |
| | <option value="24" selected>24</option> |
| | <option value="36">36</option> |
| | <option value="60">60</option> |
| | <option value="999">alles</option> |
| | </select> |
| | </label> |
| |
| | <button type="button" class="generate-collage" onclick="renderCollage()" style="margin-left:12px;"> |
| | Genereer collage |
| | </button> |
| | |
| | <button type="button" onclick="downloadCollagePNG()" style="margin-left:8px;"> |
| | Download PNG |
| | </button> |
| | |
| | <button type="button" onclick="downloadCollagePDF()" style="margin-left:6px;"> |
| | Download PDF (A4 liggend) |
| | </button> |
| | |
| | <span id="exportStatus" style="margin-left:12px;color:#666;font-size:12px;"></span> |
| | |
| | </div> |
| | |
| | <div id="collageExportArea"> |
| | <div id="collageExportHeader" class="collage-export-header" style="display:none;"></div> |
| | <div id="collageGrid" class="collage-grid" style="display:none;"></div> |
| | </div> |
| | </div> |
| | |
| | <h2 style="margin-top:3em;border-bottom:2px solid #ccc;padding-bottom:0.3em;"> |
| | REFERENTIEPROJECTEN |
| | </h2> |
| | |
| | <!-- PROJECT_INSERT_START --> |
| <!--------------- BATTERSEA -----------------> | <!--------------- BATTERSEA -----------------> |
| |
| </div> | </div> |
| <!-----------------Einde project ------------------> | <!-----------------Einde project ------------------> |
| |
| |
| |
| |
| </div> | </div> |
| <!-----------------Einde project ------------------> | <!-----------------Einde project ------------------> |
| |
| |
| |
| |
| </div> | </div> |
| <!-----------------Einde project ------------------> | <!-----------------Einde project ------------------> |
| |
| |
| |
| </div> | </div> |
| <!-----------------Einde project ------------------> | <!-----------------Einde project ------------------> |
| |
| |
| |
| </div> | </div> |
| <!-----------------Einde project ------------------> | <!-----------------Einde project ------------------> |
| |
| |
| |
| |
| </div> | </div> |
| <!-----------------Einde project------------------> | <!-----------------Einde project------------------> |
| <!-----------------Einde project ------------------> | |
| |
| |
| <!--------------- Waterpark Heemstede -----------------> | <!--------------- Waterpark Heemstede -----------------> |
| <div class="projectblok" data-fsi="0.80" data-gsi="0.20" data-osr="5.00" id="waterpark_heemstede"> | <div class="projectblok" data-fsi="0.80" data-gsi="0.20" data-osr="5.00" id="waterpark_heemstede"> |
| <h2> | <h2> |
| Waterpark Heemstede | Waterpark Heemstede |
| <a href="#" onclick="scrollToTop()" title="Terug naar boven" style="float:right;font-size:2.4em;text-decoration:none;">⬆</a> | <a href="#" onclick="scrollToTop()" title="Terug naar boven" style="float:right;font-size:2.4em;text-decoration:none;">⬆</a> |
| </h2> | </h2> |
| <div class="projectgrid"> | <div class="projectgrid"> |
| <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:114207_waterparkhee_overzicht.jpg" alt="Waterpark Heemstede overzicht" /> | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:waterpark_heemstede_overzicht.jpg" alt="Waterpark Heemstede overzicht" /> |
| <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:114207_waterparkhee_straat1.jpg" alt="Waterpark Heemstede straat 1" /> | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:waterpark_heemstede_straat1.jpg" alt="Waterpark Heemstede straat 1" /> |
| <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:114207_waterparkhee_straat2.jpg" alt="Waterpark Heemstede straat 2" /> | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:waterpark_heemstede_straat2.jpg" alt="Waterpark Heemstede straat 2" /> |
| <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:114207_waterparkhee_straat3.jpg" alt="Waterpark Heemstede straat 3" /> | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:waterpark_heemstede_straat3.jpg" alt="Waterpark Heemstede straat 3" /> |
| </div> | </div> |
| <div class="kengetallen"> | <div class="kengetallen"> |
| <table> | <table> |
| <tr><td>FSI</td><td>0.80</td></tr> | <tr><td>FSI</td><td>0.80</td></tr> |
| <tr><td>GSI</td><td>0.20</td></tr> | <tr><td>GSI</td><td>0.20</td></tr> |
| <tr><td>Gem. aantal lagen</td><td>5.0</td></tr> | <tr><td>Gem. aantal lagen</td><td>5.0</td></tr> |
| <tr><td>OSR</td><td>5.00</td></tr> | <tr><td>OSR</td><td>5.00</td></tr> |
| <tr><td>Bijzonderheden</td><td>Het Watertorengebied in Heemstede, ook wel Waterpark genoemd, omvat een transformatiegebied van circa 2,5 hectare. Het bruto vloeroppervlak bedraagt 21.973 m², met een FSI van 1,28 en een GSI van 0,26. De gemiddelde bouwhoogte ligt op 4,9 lagen, wat duidt op een stedelijk woonmilieu met enige verticaliteit. De OSR komt uit op 0,58 – een relatief ruime verhouding tussen open ruimte en bebouwing. Van het totaal BVO is 21.973 m² bestemd voor wonen. Bij een gemiddelde van 90 m² BVO per woning resulteert dit in een indicatief programma van 244 woningen.<br /> | <tr><td>Bijzonderheden</td><td>Het Watertorengebied in Heemstede, ook wel Waterpark genoemd, omvat een transformatiegebied van circa 2,5 hectare. Het bruto vloeroppervlak bedraagt 21.973 m², met een FSI van 1,28 en een GSI van 0,26. De gemiddelde bouwhoogte ligt op 4,9 lagen, wat duidt op een stedelijk woonmilieu met enige verticaliteit. De OSR komt uit op 0,58 – een relatief ruime verhouding tussen open ruimte en bebouwing. Van het totaal BVO is 21.973 m² bestemd voor wonen. Bij een gemiddelde van 90 m² BVO per woning resulteert dit in een indicatief programma van 244 woningen.<br /> |
| <br /> | <br /> |
| Het gebied is ontwikkeld op de voormalige gemeentewerf van Heemstede, aan de voet van de karakteristieke watertoren. De stedenbouwkundige opzet bestaat uit middelhoge, gestapelde bouw rondom een mix van parkachtige verblijfsruimten, speelzones en wandelroutes. De bebouwing vormt gesloten en halfopen bouwblokken met aandacht voor doorzichten, entreeruimtes en groen-overgangen tussen privé en publiek domein.<br /> | Het gebied is ontwikkeld op de voormalige gemeentewerf van Heemstede, aan de voet van de karakteristieke watertoren. De stedenbouwkundige opzet bestaat uit middelhoge, gestapelde bouw rondom een mix van parkachtige verblijfsruimten, speelzones en wandelroutes. De bebouwing vormt gesloten en halfopen bouwblokken met aandacht voor doorzichten, entreeruimtes en groen-overgangen tussen privé en publiek domein.<br /> |
| <br /> | <br /> |
| De architectuur is eigentijds, met variatie in metselwerk, balkonuitkragingen en grote gevelopeningen. Door de ligging aan de rand van het centrum en de nabijheid van voorzieningen, vormt het Waterpark een belangrijke verdichtingslocatie binnen Heemstede. Het project illustreert hoe compacte woningbouw op een relatief klein terrein kan bijdragen aan de woningvoorraad zonder aan ruimtelijke kwaliteit in te boeten.</td></tr> | De architectuur is eigentijds, met variatie in metselwerk, balkonuitkragingen en grote gevelopeningen. Door de ligging aan de rand van het centrum en de nabijheid van voorzieningen, vormt het Waterpark een belangrijke verdichtingslocatie binnen Heemstede. Het project illustreert hoe compacte woningbouw op een relatief klein terrein kan bijdragen aan de woningvoorraad zonder aan ruimtelijke kwaliteit in te boeten.</td></tr> |
| </table> | </table> |
| <p style="font-size:0.9em;color:#777;">Ingezonden door pascal op 28-10-2025</p> | <p style="font-size:0.9em;color:#777;">Ingezonden door pascal op 12-02-2026</p> |
| | </div> |
| </div> | </div> |
| | <!-----------------Einde project ------------------> |
| | |
| | <!--------------- Architectenbuurt, Heemstede -----------------> |
| | <div class="projectblok" data-fsi="0.90" data-gsi="0.31" data-osr="0.63" id="architectenbuurt_heemstede"> |
| | <h2> |
| | Architectenbuurt, Heemstede |
| | <a href="#" onclick="scrollToTop()" title="Terug naar boven" style="float:right;font-size:2.4em;text-decoration:none;">⬆</a> |
| | </h2> |
| | <div class="projectgrid"> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:architectenbuurt_heemstede_overzicht.jpg" alt="Architectenbuurt overzicht" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:architectenbuurt_heemstede_straat1.jpg" alt="Architectenbuurt straat 1" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:architectenbuurt_heemstede_straat2.jpg" alt="Architectenbuurt straat 2" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:architectenbuurt_heemstede_straat3.jpg" alt="Architectenbuurt straat 3" /> |
| | </div> |
| | <div class="kengetallen"> |
| | <table> |
| | <tr><td>FSI</td><td>0.90</td></tr> |
| | <tr><td>GSI</td><td>0.31</td></tr> |
| | <tr><td>Gem. aantal lagen</td><td>3.5</td></tr> |
| | <tr><td>OSR</td><td>0.63</td></tr> |
| | <tr><td>Bijzonderheden</td><td>De Architectenbuurt in Heemstede beslaat een gebied van circa 10,5 hectare en telt een bruto vloeroppervlak van 94.026 m². Het vloerindexcijfer (FSI) bedraagt 1,10 en de gebiedsdekking (GSI) komt uit op 0,31. Met een gemiddelde bouwhoogte van 3,5 lagen en een OSR van 0,63 is sprake van een wijk met een evenwichtige verhouding tussen bebouwing en open ruimte. Het volledige programma betreft wonen, met een indicatief aantal van 1.044 woningen bij een gemiddelde van 90 m² BVO per woning.<br /> |
| | <br /> |
| | De buurt is opgebouwd in de typische jaren 30-verkavelingslogica met korte rijtjes eengezinswoningen, vrijstaande en twee-onder-een-kapwoningen. De ruim opgezette straten, voortuinen en groene erfafscheidingen dragen bij aan de ruimtelijke beleving. In het straatbeeld domineren metselwerkgevels met sierdetails, hoge kappen, erkers en zorgvuldig vormgegeven voordeurpartijen.<br /> |
| | <br /> |
| | De stedenbouwkundige structuur bestaat uit een fijnmazig raster van woonstraten, langzaam verkeer en haakse verkavelingen. Er is een duidelijke hiërarchie in straatprofielen, met bredere lanen en smallere tussenstraten. De Architectenbuurt vormt een goed bewaard voorbeeld van de vooroorlogse suburbane woonwijk, met een uitgesproken identiteit en sterke samenhang tussen architectuur en openbare ruimte.</td></tr> |
| | </table> |
| | <p style="font-size:0.9em;color:#777;">Ingezonden door pascal op 12-02-2026</p> |
| | </div> |
| </div> | </div> |
| <!-----------------Einde project------------------> | |
| <!-----------------Einde project ------------------> | <!-----------------Einde project ------------------> |
| |
| | <!--------------- Wickevoort Haarlemmermeer -----------------> |
| | <div class="projectblok" data-fsi="0.38" data-gsi="0.12" data-osr="2.32" id="wickevoort_haarlemmermeer"> |
| | <h2> |
| | Wickevoort Haarlemmermeer |
| | <a href="#" onclick="scrollToTop()" title="Terug naar boven" style="float:right;font-size:2.4em;text-decoration:none;">⬆</a> |
| | </h2> |
| | <div class="projectgrid"> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:wickevoort_haarlemmermeer_overzicht.jpg" alt="Wickevoort Haarlemmermeer overzicht" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:wickevoort_haarlemmermeer_straat1.jpg" alt="Wickevoort Haarlemmermeer straat 1" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:wickevoort_haarlemmermeer_straat2.jpg" alt="Wickevoort Haarlemmermeer straat 2" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:wickevoort_haarlemmermeer_straat3.jpg" alt="Wickevoort Haarlemmermeer straat 3" /> |
| | </div> |
| | <div class="kengetallen"> |
| | <table> |
| | <tr><td>FSI</td><td>0.38</td></tr> |
| | <tr><td>GSI</td><td>0.12</td></tr> |
| | <tr><td>Gem. aantal lagen</td><td>3.3</td></tr> |
| | <tr><td>OSR</td><td>2.32</td></tr> |
| | <tr><td>Bijzonderheden</td><td>Wickevoort in Haarlemmermeer beslaat een gebied van circa 18 hectare met een bruto vloeroppervlak van 68.670 m². De FSI bedraagt 0,38 en de GSI 0,12, met een gemiddelde bouwhoogte van 3,3 lagen. Daarmee is sprake van een lage dichtheid en een zeer open verkavelingsstructuur. De verhouding tussen open ruimte en programma (OSR) bedraagt 2,32 — een uitzonderlijk hoge waarde die duidt op een sterke dominantie van groen, water, wadi’s en parkzones. Met 67.426 m² wonen en 1.244 m² niet-wonen telt het gebied indicatief circa 613 woningen bij een gemiddelde van 110 m² BVO per woning.<br /> |
| | <br /> |
| | De wijk is opgezet als een eigentijds landgoed en combineert duurzame woningbouw met een groen raamwerk dat visueel én functioneel de beleving van ruimte bepaalt. Centraal in de stedenbouw staat de relatie tussen natuur, collectief gebruik en individualiteit. Brede kavels, doorwaadbare padenstructuren en informele erfafscheidingen versterken dit beeld. De bebouwing volgt een organisch patroon met onderbroken rooilijnen, lage goothoogtes en natuurlijke materiaalkeuzes.<br /> |
| | <br /> |
| | Oonderzoek naar stedenbouwkundige beleving laat zien dat wijken zoals Wickevoort — met lage GSI, hoge OSR en een gelaagde overgang van privaat naar publiek domein — consistent hoger scoren op waargenomen rust, comfort en ‘visual coherence’. Wickevoort laat zien dat dichtheid niet alleen getalsmatig, maar ook landschappelijk en sociaal beleefd wordt. Juist in een context van woningnood en klimaatdruk is dit een waardevolle ontwerpstrategie.</td></tr> |
| | </table> |
| | <p style="font-size:0.9em;color:#777;">Ingezonden door pascal op 12-02-2026</p> |
| | </div> |
| | </div> |
| | <!-----------------Einde project ------------------> |
| |
| | <!--------------- Kop van Zuid, Rotterdam -----------------> |
| | <div class="projectblok" data-fsi="4.0" data-gsi="0.29" data-osr="0.17" id="kop_van_zuid_rotterdam"> |
| | |
| <!--------------- Architectenbuurt Heemstede, Heemstede -----------------> | |
| <div class="projectblok" data-fsi="0.90" data-gsi="0.29" data-osr="0.63" id="architectenbuurt_heemstede_heemstede"> | |
| <h2> | <h2> |
| Architectenbuurt Heemstede, Heemstede | Kop van Zuid, Rotterdam |
| <a href="#" onclick="scrollToTop()" title="Terug naar boven" style="float:right;font-size:2.4em;text-decoration:none;">⬆</a> | <a href="#" onclick="scrollToTop()" title="Terug naar boven" style="float:right;font-size:2.4em;text-decoration:none;">⬆</a> |
| </h2> | </h2> |
| <div class="projectgrid"> | <div class="projectgrid"> |
| <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:120330_architectenb_overzicht.jpg" alt="Architectenbuurt Heemstede overzicht" /> | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:102236_kopvanzuidro_overzicht.jpg" alt="Kop van Zuid overzicht" /> |
| <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:120330_architectenb_straat1.jpg" alt="Architectenbuurt Heemstede straat 1" /> | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:102236_kopvanzuidro_straat1.jpg" alt="Kop van Zuid straat 1" /> |
| <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:120330_architectenb_straat2.jpg" alt="Architectenbuurt Heemstede straat 2" /> | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:102236_kopvanzuidro_straat2.jpg" alt="Kop van Zuid straat 2" /> |
| <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:120330_architectenb_straat3.jpg" alt="Architectenbuurt Heemstede straat 3" /> | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:102236_kopvanzuidro_straat3.jpg" alt="Kop van Zuid straat 3" /> |
| </div> | </div> |
| <div class="kengetallen"> | <div class="kengetallen"> |
| <table> | <table> |
| <tr><td>FSI</td><td>0.90</td></tr> | <tr><td>FSI</td><td>4.21</td></tr> |
| <tr><td>GSI</td><td>0.29</td></tr> | <tr><td>GSI</td><td>0.29</td></tr> |
| <tr><td>Gem. aantal lagen</td><td>3.5</td></tr> | <tr><td>Gem. aantal lagen</td><td>14.3</td></tr> |
| <tr><td>OSR</td><td>0.63</td></tr> | <tr><td>OSR</td><td>0.17</td></tr> |
| <tr><td>Bijzonderheden</td><td>De Architectenbuurt in Heemstede beslaat een gebied van circa 10,5 hectare en telt een bruto vloeroppervlak van 94.026 m². Het vloerindexcijfer (FSI) bedraagt 1,10 en de gebiedsdekking (GSI) komt uit op 0,29. Met een gemiddelde bouwhoogte van 3,5 lagen en een OSR van 0,63 is sprake van een wijk met een evenwichtige verhouding tussen bebouwing en open ruimte. Het volledige programma betreft wonen, met een indicatief aantal van 1.044 woningen bij een gemiddelde van 90 m² BVO per woning.<br /> | <tr><td>Bijzonderheden</td><td>Kop van Zuid betreft een hoogstedelijke ontwikkeling en is geanalyseerd op basis van OpenStreetMap-gegevens en een handgetekende projectbegrenzing. De GSI bedraagt 0,29, wat duidt op een gemiddelde bebouwingsgraad binnen een compacte stedelijke structuur. Met een FSI van 4,21 en een gemiddelde bouwhoogte van circa 14,3 lagen is sprake van een zeer intensief ruimtegebruik.<br /> |
| <br /> | <br /> |
| De buurt is opgebouwd in de typische jaren 30-verkavelingslogica met korte rijtjes eengezinswoningen, vrijstaande en twee-onder-een-kapwoningen. De ruim opgezette straten, voortuinen en groene erfafscheidingen dragen bij aan de ruimtelijke beleving. In het straatbeeld domineren metselwerkgevels met sierdetails, hoge kappen, erkers en zorgvuldig vormgegeven voordeurpartijen.<br /> | De OSR ligt op 0,17, wat wijst op een beperkte hoeveelheid publieke en semipublieke ruimte binnen het gebied. Het stedenbouwkundig patroon bestaat uit gesloten bouwblokken en hoogbouwaccenten, waarbij plinten een belangrijke rol spelen in de relatie tussen gebouw en straat en binnengebieden voornamelijk collectief van karakter zijn. Het programma is hoofdzakelijk residentieel en omvat circa 2.359 woningen, wat neerkomt op circa 138 woningen per hectare bij een gemiddelde woninggrootte van 100 m² BVO.<br /> |
| <br /> | <br /> |
| De stedenbouwkundige structuur bestaat uit een fijnmazig raster van woonstraten, langzaam verkeer en haakse verkavelingen. Er is een duidelijke hiërarchie in straatprofielen, met bredere lanen en smallere tussenstraten. De Architectenbuurt vormt een goed bewaard voorbeeld van de vooroorlogse suburbane woonwijk, met een uitgesproken identiteit en sterke samenhang tussen architectuur en openbare ruimte.</td></tr> | De analyse is gebaseerd op reproduceerbare uitgangspunten. Projectcontour, OSM-bronnen en aannames ten aanzien van lagen en functieverdeling zijn vastgelegd in het projectbestand, waardoor de berekeningen controleerbaar en consistent zijn.</td></tr> |
| </table> | </table> |
| <p style="font-size:0.9em;color:#777;">Ingezonden door pascal op 28-10-2025</p> | <p style="font-size:0.9em;color:#777;">Ingezonden door emma op 29-01-2026</p> |
| </div> | </div> |
| </div> | </div> |
| <!-----------------Einde project------------------> | <!-----------------Einde project------------------> |
| | |
| | <!--------------- Little C, Rotterdam -----------------> |
| | <div class="projectblok" data-fsi="2.42" data-gsi="0.24" data-osr="0.31" id="little_c_rotterdam"> |
| | <h2> |
| | Little C, Rotterdam |
| | <a href="#" onclick="scrollToTop()" title="Terug naar boven" style="float:right;font-size:2.4em;text-decoration:none;">⬆</a> |
| | </h2> |
| | <div class="projectgrid"> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:little_c_rotterdam_overzicht.jpg" alt="Little C overzicht" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:little_c_rotterdam_straat1.jpg" alt="Little C straat 1" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:little_c_rotterdam_straat2.jpg" alt="Little C straat 2" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:little_c_rotterdam_straat3.jpg" alt="Little C straat 3" /> |
| | </div> |
| | <div class="kengetallen"> |
| | <table> |
| | <tr><td>FSI</td><td>2.42</td></tr> |
| | <tr><td>GSI</td><td>0.24</td></tr> |
| | <tr><td>Gem. aantal lagen</td><td>10.0</td></tr> |
| | <tr><td>OSR</td><td>0.31</td></tr> |
| | <tr><td>Bijzonderheden</td><td>Little C in Rotterdam is een uitgesproken voorbeeld van compacte, hoogstedelijke gebiedsontwikkeling, waarin intensief ruimtegebruik wordt gecombineerd met een zorgvuldig vormgegeven openbare ruimte. Het gebied heeft een gebiedsdekking (GSI) van 0,24, wat betekent dat slechts een beperkt deel van het maaiveld wordt bebouwd. Deze openheid wordt gecompenseerd door een hoog vloerindexcijfer (FSI) van 2,42 en een gemiddelde bouwhoogte van circa 10 lagen. De verhouding tussen open ruimte en programma (OSR) bedraagt 0,31 en wijst op een functionele balans tussen bebouwing en collectieve buitenruimte binnen een sterk verdichte stedelijke setting. Uitgaande van een gemiddelde woninggrootte van 100 m² BVO omvat het gebied indicatief circa 360 woningen, wat neerkomt op een dichtheid van ongeveer 168 woningen per hectare.<br /> |
| | <br /> |
| | Stedenbouwkundig manifesteert Little C zich als een samenhangend ensemble van stevige bouwblokken, waarin de bebouwing duidelijke randen en stedelijke wanden vormt. De hoogteopbouw en de compacte verkaveling creëren een uitgesproken stedelijk profiel, terwijl op maaiveldniveau ruimte wordt vrijgespeeld voor pleinen, doorsteken en informele verblijfsplekken. Deze gelaagdheid — met intensief gebruik boven maaiveld en collectiviteit op straatniveau — sluit aan bij hedendaagse opvattingen over binnenstedelijk wonen, waarin verdichting hand in hand gaat met leefkwaliteit.<br /> |
| | <br /> |
| | De kwantitatieve analyse van het gebied is gebaseerd op een handmatig vastgelegde projectbegrenzing, gecombineerd met gegevens uit OpenStreetMap. Aannames over bouwlagen en functies zijn expliciet opgenomen en maken de berekeningen transparant en reproduceerbaar. Daarmee laat Little C niet alleen zien hoe hoogstedelijke woningbouw ruimtelijk kan worden vormgegeven, maar ook hoe open databronnen effectief kunnen worden ingezet voor stedenbouwkundige analyse.</td></tr> |
| | </table> |
| | <p style="font-size:0.9em;color:#777;">Ingezonden door emma op 12-02-2026</p> |
| | </div> |
| | </div> |
| <!-----------------Einde project ------------------> | <!-----------------Einde project ------------------> |
| |
| <!--------------- EINDE_PROJECTEN -----------------> | |
| |
| | <!--------------- Duin Almere -----------------> |
| | <div class="projectblok" data-fsi="0.68" data-gsi="0.11" data-osr="1.31" id="duin_almere"> |
| | <h2> |
| | Duin Almere |
| | <a href="#" onclick="scrollToTop()" title="Terug naar boven" style="float:right;font-size:2.4em;text-decoration:none;">⬆</a> |
| | </h2> |
| | <div class="projectgrid"> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:duin_almere_overzicht.jpg" alt="Duin Almere overzicht" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:duin_almere_straat1.jpg" alt="Duin Almere straat 1" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:duin_almere_straat2.jpg" alt="Duin Almere straat 2" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:duin_almere_straat3.jpg" alt="Duin Almere straat 3" /> |
| | </div> |
| | <div class="kengetallen"> |
| | <table> |
| | <tr><td>FSI</td><td>0.68</td></tr> |
| | <tr><td>GSI</td><td>0.11</td></tr> |
| | <tr><td>Gem. aantal lagen</td><td>6.0</td></tr> |
| | <tr><td>OSR</td><td>1.31</td></tr> |
| | <tr><td>Bijzonderheden</td><td>Duin in Almere beslaat een gebied van circa 64 hectare met een bruto vloeroppervlak van 342.393 m². De FSI bedraagt 0,68 en de GSI 0,11, met een gemiddelde bouwhoogte van circa 6 lagen. De verhouding tussen open ruimte en programma (OSR) komt uit op 1,31, wat duidt op een zeer ruime inrichting met veel onbebouwd oppervlak. Van het totaal BVO is 342.393 m² bestemd voor wonen, wat neerkomt op een indicatief woningprogramma van circa 3.604 woningen bij een gemiddelde van 95 m² BVO per woning.<br /> |
| | <br /> |
| | Duin is een van de meest onconventionele gebiedsontwikkelingen in Nederland. De wijk is gebouwd op een kunstmatig duinlandschap dat letterlijk is opgeworpen bovenop een voormalige zandwinput aan het IJmeer. Door grootschalige zandophoging is een glooiend maaiveld ontstaan dat niet alleen de beleving van hoogteverschillen introduceert, maar ook fungeert als klimaatadaptieve maatregel tegen wateroverlast en hittestress. De stedenbouwkundige opzet combineert organisch verloop met een landschappelijk grid: meanderende woonstraten, hoogteverschillen en zichtlijnen op het water vormen de dragers van het plan.<br /> |
| | <br /> |
| | De bebouwing varieert sterk in typologie en schaal — van geschakelde laagbouw tot woontorens aan het strand — maar is altijd ingepast in het duinprofiel. Openbare ruimte is opgezet als een sequentie van informele paden, zandige taluds, natuurlijke speelplekken en ruig groen. Duin is daarmee niet alleen een antwoord op het tekort aan woningbouwlocaties, maar ook een voorbeeld van ‘natuurinclusieve dichtheid’: bouwen binnen een sterke landschappelijke setting zónder dat het landschap verloren gaat.</td></tr> |
| | </table> |
| | <p style="font-size:0.9em;color:#777;">Ingezonden door pascal op 12-02-2026</p> |
| | </div> |
| | </div> |
| | <!-----------------Einde project ------------------> |
| | |
| | |
| | <!--------------- Cosunpark, Breda -----------------> |
| | <div class="projectblok" data-fsi="0.92" data-gsi="0.17" data-osr="0.90" id="cosunpark_breda"> |
| | <h2> |
| | Cosunpark, Breda |
| | <a href="#" onclick="scrollToTop()" title="Terug naar boven" style="float:right;font-size:2.4em;text-decoration:none;">⬆</a> |
| | </h2> |
| | <div class="projectgrid"> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:cosunpark_breda_overzicht.jpg" alt="Cosunpark overzicht" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:cosunpark_breda_straat1.jpg" alt="Cosunpark straat 1" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:cosunpark_breda_straat2.jpg" alt="Cosunpark straat 2" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:cosunpark_breda_straat3.jpg" alt="Cosunpark straat 3" /> |
| | </div> |
| | <div class="kengetallen"> |
| | <table> |
| | <tr><td>FSI</td><td>0.92</td></tr> |
| | <tr><td>GSI</td><td>0.17</td></tr> |
| | <tr><td>Gem. aantal lagen</td><td>5.3</td></tr> |
| | <tr><td>OSR</td><td>0.90</td></tr> |
| | <tr><td>Bijzonderheden</td><td>Cosunpark in Breda is een woongebied met een uitgesproken open en groen karakter, waarin de bebouwing duidelijk ondergeschikt is aan de openbare ruimte. De gebiedsdekking (GSI) bedraagt 0,17, wat wijst op een beperkte footprint van de bebouwing en een ruime mate van onbebouwde ruimte op maaiveldniveau. Met een vloerindexcijfer (FSI) van 0,92 en een gemiddelde bouwhoogte van circa 5,3 lagen is sprake van een middelhoge, ontspannen dichtheid die ruimte laat voor licht, lucht en doorzichten. De verhouding tussen open ruimte en programma (OSR) komt uit op 0,9 en onderstreept het parkachtige karakter van het gebied, met een royale aanwezigheid van publieke en semipublieke verblijfsruimten. Uitgaande van een gemiddelde woninggrootte van 100 m² BVO resulteert dit in een indicatief woonprogramma van circa 261 woningen, wat neerkomt op een dichtheid van ongeveer 86 woningen per hectare.<br /> |
| | <br /> |
| | Stedenbouwkundig wordt Cosunpark gekenmerkt door een losse verkavelingsstructuur waarin middelhoge woonvolumes zijn ingebed in een samenhangend groen raamwerk. In plaats van gesloten bouwblokken ontstaat een netwerk van open ruimten, paden en verblijfsplekken, waarbij het landschap fungeert als dragend element van het plan. De relatief bescheiden bouwhoogtes en de ruime onderlinge afstanden versterken de leesbaarheid van het gebied en dragen bij aan een rustige, collectieve woonomgeving.<br /> |
| | <br /> |
| | De kwantitatieve analyse van Cosunpark is gebaseerd op een handmatig vastgelegde projectcontour in combinatie met gegevens uit OpenStreetMap. Aannames over bouwlagen en functies zijn expliciet vastgelegd en maken de berekeningen transparant en reproduceerbaar. Daarmee vormt het gebied niet alleen een voorbeeld van groen-stedelijk wonen, maar ook van de inzet van open databronnen als instrument voor stedenbouwkundige analyse.</td></tr> |
| | </table> |
| | <p style="font-size:0.9em;color:#777;">Ingezonden door emma op 12-02-2026</p> |
| | </div> |
| | </div> |
| | <!-----------------Einde project ------------------> |
| | |
| | |
| | <!--------------- Zuidkade, Den Haag -----------------> |
| | <div class="projectblok" data-fsi="1.51" data-gsi="0.29" data-osr="0.47" id="zuidkade_den_haag"> |
| | <h2> |
| | Zuidkade, Den Haag |
| | <a href="#" onclick="scrollToTop()" title="Terug naar boven" style="float:right;font-size:2.4em;text-decoration:none;">⬆</a> |
| | </h2> |
| | <div class="projectgrid"> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:zuidkade_den_haag_overzicht.jpg" alt="Zuidkade overzicht" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:zuidkade_den_haag_straat1.jpg" alt="Zuidkade straat 1" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:zuidkade_den_haag_straat2.jpg" alt="Zuidkade straat 2" /> |
| | <img src="/wiki/lib/exe/fetch.php?media=handleiding_nieuw:spacematrix:zuidkade_den_haag_straat3.jpg" alt="Zuidkade straat 3" /> |
| | </div> |
| | <div class="kengetallen"> |
| | <table> |
| | <tr><td>FSI</td><td>1.51</td></tr> |
| | <tr><td>GSI</td><td>0.29</td></tr> |
| | <tr><td>Gem. aantal lagen</td><td>5.2</td></tr> |
| | <tr><td>OSR</td><td>0.47</td></tr> |
| | <tr><td>Bijzonderheden</td><td>Zuidkade in Den Haag is een uitgesproken stedelijk woongebied waar compact bouwen wordt gecombineerd met ruimte voor verblijf en ontmoeting. Met een gebiedsdekking (GSI) van 0,29 heeft de bebouwing een duidelijke aanwezigheid, zonder het maaiveld volledig te domineren. Het vloerindexcijfer (FSI) bedraagt 1,51 en gaat samen met een gemiddelde bouwhoogte van circa 5,2 lagen, wat resulteert in een stedelijke dichtheid die voelbaar is, maar niet massief. De verhouding tussen open ruimte en programma (OSR) komt uit op 0,47 en wijst op een betekenisvolle rol voor publieke en semipublieke buitenruimten binnen het stedelijk weefsel. Bij een gemiddelde woninggrootte van 105 m² BVO omvat het gebied indicatief circa 731 woningen, wat neerkomt op ongeveer 134 woningen per hectare.<br /> |
| | <br /> |
| | Stedenbouwkundig ontvouwt Zuidkade zich als een samenhangend ensemble van middelhoge bouwblokken die de openbare ruimte scherp omlijsten. Langs straten en kades ontstaan stedelijke wanden, terwijl binnenhoven, pleinen en groene tussenruimten zorgen voor lucht en doorwaadbaarheid. Deze afwisseling tussen geslotenheid en openheid geeft het gebied een dynamisch karakter en ondersteunt een levendige woonomgeving met een duidelijke stedelijke identiteit.<br /> |
| | <br /> |
| | De analyse van het gebied is gebaseerd op een handmatig vastgelegde projectcontour, gecombineerd met gegevens uit OpenStreetMap. Aannames over bouwlagen en functies zijn expliciet meegenomen, waardoor de berekeningen transparant en reproduceerbaar zijn. Zuidkade laat daarmee zien hoe middelhoge verdichting niet alleen efficiënt, maar ook ruimtelijk rijk kan zijn — en hoe open databronnen een waardevol instrument vormen in stedenbouwkundige analyse.</td></tr> |
| | </table> |
| | <p style="font-size:0.9em;color:#777;">Ingezonden door emma op 12-02-2026</p> |
| | </div> |
| | </div> |
| | <!-----------------Einde project ------------------> |
| | |
| | |
| | |
| | |
| | |
| | <!-- PROJECT_INSERT_END --> |
| |
| |
| </div> | </div> |
| |
| | <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script> |
| | <script src="https://cdn.jsdelivr.net/npm/jspdf@2.5.1/dist/jspdf.umd.min.js"></script> |
| |
| <script> | <script> |
| document.getElementById('gsi_max_val').textContent = gsiMin.value; | document.getElementById('gsi_max_val').textContent = gsiMin.value; |
| } | } |
| | } |
| | |
| | function getProjectTitle(blok) { |
| | const h2 = blok.querySelector('h2'); |
| | if (!h2) return blok.id; |
| | |
| | // h2 bevat ook de "⬆" link; die strippen we eruit |
| | return (h2.textContent || '') |
| | .replace('⬆', '') |
| | .replace(/\s+/g, ' ') |
| | .trim(); |
| } | } |
| |
| const gsiMax = parseFloat(document.getElementById('gsi_max').value); | const gsiMax = parseFloat(document.getElementById('gsi_max').value); |
| |
| const projectBlokken = document.querySelectorAll('.projectblok'); | const projectBlokken = Array.from(document.querySelectorAll('.projectblok')); |
| const lijst = document.getElementById('projectlist'); | const lijst = document.getElementById('projectlist'); |
| lijst.innerHTML = ''; | lijst.innerHTML = ''; |
| |
| const dotsLayer = document.getElementById('project-dots'); | const dotsLayer = document.getElementById('project-dots'); |
| dotsLayer.innerHTML = ''; // leeg alle vorige stipjes | dotsLayer.innerHTML = ''; |
| |
| | // 1) bepaal zichtbaarheid + toon/verberg blokken |
| | const visible = []; |
| projectBlokken.forEach(blok => { | projectBlokken.forEach(blok => { |
| const fsi = parseFloat(blok.dataset.fsi); | const fsi = parseFloat(blok.dataset.fsi); |
| const gsi = parseFloat(blok.dataset.gsi); | const gsi = parseFloat(blok.dataset.gsi); |
| |
| const zichtbaar = | const zichtbaar = |
| fsi >= fsiMin && fsi <= fsiMax && | fsi >= fsiMin && fsi <= fsiMax && |
| gsi >= gsiMin && gsi <= gsiMax; | gsi >= gsiMin && gsi <= gsiMax; |
| |
| blok.style.display = zichtbaar ? 'block' : 'none'; | blok.style.display = zichtbaar ? 'block' : 'none'; |
| | if (zichtbaar) visible.push(blok); |
| | }); |
| | |
| | // 2) sorteer zichtbaar op titel (handig als het aantal projecten groeit) |
| | visible.sort((a, b) => getProjectTitle(a).localeCompare(getProjectTitle(b), 'nl', { sensitivity: 'base' })); |
| | |
| | // 3) voeg dots + links toe |
| | visible.forEach(blok => { |
| | const fsi = parseFloat(blok.dataset.fsi); |
| | const gsi = parseFloat(blok.dataset.gsi); |
| | const title = getProjectTitle(blok); |
| |
| if (zichtbaar) { | // ➤ stipje op de matrix |
| // ➤ Stipje toevoegen | |
| const dot = document.createElement('div'); | const dot = document.createElement('div'); |
| dot.className = 'project-dot'; | dot.className = 'project-dot'; |
| | dot.dataset.pid = blok.id; |
| |
| const baseLeft = 60; | const baseLeft = 60; |
| const baseTop = 40; // gebruik jouw waarde! | const baseTop = 40; |
| const graphWidth = 680; | const graphWidth = 680; |
| const graphHeight = 400; | const graphHeight = 400; |
| dot.style.left = x + 'px'; | dot.style.left = x + 'px'; |
| dot.style.top = y + 'px'; | dot.style.top = y + 'px'; |
| dot.title = blok.querySelector('h2').textContent; | dot.title = title; |
| |
| dot.onclick = () => { | dot.onclick = () => { |
| dotsLayer.appendChild(dot); | dotsLayer.appendChild(dot); |
| |
| // ➤ Projectlink in lijst (zoals je nu al doet) | // ➤ link in lijst (zonder thumbnail) |
| const li = document.createElement('li'); | const li = document.createElement('li'); |
| const link = document.createElement('a'); | const link = document.createElement('a'); |
| const img = blok.querySelector('img'); | |
| link.href = '#' + blok.id; | link.href = '#' + blok.id; |
| link.textContent = blok.querySelector('h2').textContent; | link.textContent = title; |
| if (img) { | link.dataset.pid = blok.id; |
| const mini = document.createElement('img'); | |
| mini.src = img.src; | link.addEventListener('mouseenter', () => { |
| li.appendChild(mini); | const d = dotsLayer.querySelector(`.project-dot[data-pid="${blok.id}"]`); |
| } | if (d) d.classList.add('highlight'); |
| | }); |
| | |
| | link.addEventListener('mouseleave', () => { |
| | const d = dotsLayer.querySelector(`.project-dot[data-pid="${blok.id}"]`); |
| | if (d) d.classList.remove('highlight'); |
| | }); |
| | |
| li.appendChild(link); | li.appendChild(link); |
| lijst.appendChild(li); | lijst.appendChild(li); |
| } | |
| }); | }); |
| } | } |
| enableImageLightbox(); | enableImageLightbox(); |
| }); | }); |
| | |
| | |
| | /* function getProjectTitle(blok) { |
| | const h2 = blok.querySelector('h2'); |
| | if (!h2) return blok.id; |
| | return (h2.textContent || '').replace('⬆','').replace(/\s+/g,' ').trim(); |
| | } */ |
| | |
| | function getCoverImageSrc(blok) { |
| | const imgs = blok.querySelectorAll('.projectgrid img'); |
| | |
| | // voorkeur: 2e foto (index 1) |
| | if (imgs.length >= 2) { |
| | return imgs[1].getAttribute('src'); |
| | } |
| | |
| | // fallback: 1e foto als er maar één is |
| | if (imgs.length === 1) { |
| | return imgs[0].getAttribute('src'); |
| | } |
| | |
| | return null; |
| | } |
| | |
| | function renderCollage() { |
| | const grid = document.getElementById('collageGrid'); |
| | if (!grid) return; |
| | |
| | const sortKey = document.getElementById('collageSort').value; |
| | const dir = document.getElementById('collageDir').value; |
| | const limit = parseInt(document.getElementById('collageLimit').value, 10); |
| | |
| | const blocks = Array.from(document.querySelectorAll('.projectblok')) |
| | .filter(b => b.style.display !== 'none'); |
| | |
| | const items = blocks.map(blok => { |
| | const title = getProjectTitle(blok); |
| | const img = getCoverImageSrc(blok); |
| | const fsi = parseFloat(blok.dataset.fsi); |
| | const gsi = parseFloat(blok.dataset.gsi); |
| | const osr = parseFloat(blok.dataset.osr); |
| | return { id: blok.id, title, img, fsi, gsi, osr }; |
| | }).filter(x => x.img); |
| | |
| | items.sort((a,b) => { |
| | const av = a[sortKey], bv = b[sortKey]; |
| | if (av === bv) return a.title.localeCompare(b.title, 'nl', {sensitivity:'base'}); |
| | return av - bv; |
| | }); |
| | if (dir === 'desc') items.reverse(); |
| | |
| | const sliced = (limit >= 999) ? items : items.slice(0, limit); |
| | |
| | grid.innerHTML = ''; |
| | sliced.forEach(p => { |
| | const card = document.createElement('div'); |
| | card.className = 'collage-card'; |
| | card.onclick = () => location.href = '#' + p.id; |
| | |
| | const img = document.createElement('img'); |
| | img.src = p.img; |
| | img.loading = 'lazy'; |
| | img.alt = p.title; |
| | |
| | const meta = document.createElement('div'); |
| | meta.className = 'collage-meta'; |
| | meta.innerHTML = ` |
| | <span class="title">${p.title}</span> |
| | <span class="kpi">FSI ${p.fsi} · GSI ${p.gsi} · OSR ${p.osr}</span> |
| | `; |
| | |
| | card.appendChild(img); |
| | card.appendChild(meta); |
| | grid.appendChild(card); |
| | }); |
| | |
| | grid.style.display = 'grid'; |
| | updateExportHeader(); // blijft bestaan, maar staat nu buiten renderCollage() |
| | } |
| | |
| | |
| | function fmt2(x) { |
| | // nette afronding (zoals 0.6 of 0.62) |
| | const n = Number(x); |
| | if (Number.isNaN(n)) return ''; |
| | return (Math.round(n * 100) / 100).toString(); |
| | } |
| | |
| | function currentDateNL() { |
| | const d = new Date(); |
| | const dd = String(d.getDate()).padStart(2,'0'); |
| | const mm = String(d.getMonth()+1).padStart(2,'0'); |
| | const yyyy = d.getFullYear(); |
| | const hh = String(d.getHours()).padStart(2,'0'); |
| | const mi = String(d.getMinutes()).padStart(2,'0'); |
| | return `${dd}-${mm}-${yyyy} ${hh}:${mi}`; |
| | } |
| | |
| | function updateExportHeader() { |
| | const header = document.getElementById('collageExportHeader'); |
| | if (!header) return; |
| | |
| | const sortKey = document.getElementById('collageSort')?.value || 'fsi'; |
| | const dir = document.getElementById('collageDir')?.value || 'asc'; |
| | const limit = document.getElementById('collageLimit')?.value || ''; |
| | |
| | const fsiMin = fmt2(document.getElementById('fsi_min')?.value); |
| | const fsiMax = fmt2(document.getElementById('fsi_max')?.value); |
| | const gsiMin = fmt2(document.getElementById('gsi_min')?.value); |
| | const gsiMax = fmt2(document.getElementById('gsi_max')?.value); |
| | |
| | const grid = document.getElementById('collageGrid'); |
| | const nTiles = grid ? grid.children.length : 0; |
| | |
| | const sortLabelMap = { fsi: 'FSI', gsi: 'GSI', osr: 'OSR' }; |
| | const sortLabel = sortLabelMap[sortKey] || sortKey; |
| | const dirLabel = (dir === 'desc') ? 'aflopend' : 'oplopend'; |
| | |
| | header.innerHTML = ` |
| | <div class="collage-export-title">Sumsonite Beeldenbank – Fotocollage (sorteer: ${sortLabel} ${dirLabel})</div> |
| | <p class="collage-export-sub"> |
| | <strong>Filters:</strong> FSI ${fsiMin}–${fsiMax} · GSI ${gsiMin}–${gsiMax} |
| | <span class="muted"> | Max: ${limit} | Getoond: ${nTiles} | Datum: ${currentDateNL()} | www.sumsonite.nl</span> |
| | </p> |
| | `; |
| | } |
| | |
| | function getCollageExportNode() { |
| | const node = document.getElementById('collageExportArea'); |
| | if (!node) throw new Error('collageExportArea niet gevonden.'); |
| | return node; |
| | } |
| | |
| | function makeFilenameBase() { |
| | const sortKey = document.getElementById('collageSort')?.value || 'collage'; |
| | const dir = document.getElementById('collageDir')?.value || 'asc'; |
| | const limit = document.getElementById('collageLimit')?.value || 'n'; |
| | const ts = new Date().toISOString().slice(0,19).replace(/[:T]/g,'-'); |
| | return `Sumsonite-collage_${sortKey}-${dir}_max${limit}_${ts}`; |
| | } |
| | |
| | async function renderNodeToCanvas(node) { |
| | // header vullen + tijdelijk zichtbaar maken |
| | updateExportHeader(); |
| | const header = document.getElementById('collageExportHeader'); |
| | const prevHeaderDisplay = header ? header.style.display : ''; |
| | if (header) header.style.display = 'block'; |
| | |
| | // Zorg dat export area zichtbaar is (collageGrid zelf is al zichtbaar na renderCollage) |
| | const canvas = await html2canvas(node, { |
| | backgroundColor: '#ffffff', |
| | scale: 2, |
| | useCORS: true, |
| | allowTaint: false, |
| | logging: false |
| | }); |
| | |
| | // header weer verbergen |
| | if (header) header.style.display = prevHeaderDisplay; |
| | |
| | return canvas; |
| | } |
| | |
| | async function downloadCollagePNG() { |
| | const grid = document.getElementById('collageGrid'); |
| | if (!grid || grid.style.display === 'none' || grid.children.length === 0) { |
| | alert('Genereer eerst de collage.'); |
| | return; |
| | } |
| | |
| | document.getElementById('exportStatus').textContent = |
| | 'Bezig met genereren… even geduld.'; |
| | |
| | const node = getCollageExportNode(); |
| | const canvas = await renderNodeToCanvas(node); |
| | |
| | const a = document.createElement('a'); |
| | a.href = canvas.toDataURL('image/png'); |
| | a.download = makeFilenameBase() + '.png'; |
| | a.click(); |
| | |
| | document.getElementById('exportStatus').textContent = ''; |
| | } |
| | |
| | async function downloadCollagePDF() { |
| | const grid = document.getElementById('collageGrid'); |
| | if (!grid || grid.style.display === 'none' || grid.children.length === 0) { |
| | alert('Genereer eerst de collage.'); |
| | return; |
| | } |
| | |
| | document.getElementById('exportStatus').textContent = |
| | 'Bezig met genereren… even geduld.'; |
| | |
| | // 1) Zorg dat header tekst klopt + header even tonen (voor rendering) |
| | updateExportHeader(); |
| | const headerEl = document.getElementById('collageExportHeader'); |
| | const prevHeaderDisplay = headerEl ? headerEl.style.display : ''; |
| | if (headerEl) headerEl.style.display = 'block'; |
| | |
| | const exportNode = document.getElementById('collageExportArea'); |
| | |
| | // 2) Render volledige export area (header + grid) naar canvas |
| | const fullCanvas = await html2canvas(exportNode, { |
| | backgroundColor: '#ffffff', |
| | scale: 2, |
| | useCORS: true, |
| | allowTaint: false, |
| | logging: false |
| | }); |
| | |
| | // 3) Render header apart (voor herhalen per pagina) |
| | const headerCanvas = await html2canvas(headerEl, { |
| | backgroundColor: '#ffffff', |
| | scale: 2, |
| | useCORS: true, |
| | allowTaint: false, |
| | logging: false |
| | }); |
| | |
| | // header weer terug naar oude staat |
| | if (headerEl) headerEl.style.display = prevHeaderDisplay; |
| | |
| | const { jsPDF } = window.jspdf; |
| | const pdf = new jsPDF({ orientation: 'landscape', unit: 'pt', format: 'a4' }); |
| | |
| | const pageWidth = pdf.internal.pageSize.getWidth(); |
| | const pageHeight = pdf.internal.pageSize.getHeight(); |
| | |
| | const margin = 24; |
| | const usableWidth = pageWidth - 2 * margin; |
| | const usableHeight = pageHeight - 2 * margin; |
| | |
| | // Schaal op breedte (zelfde schaal voor alles) |
| | const scale = usableWidth / fullCanvas.width; |
| | |
| | // Header (PDF-hoogte) |
| | const headerGapPt = 10; // ruimte tussen header en grid op PDF |
| | const headerHeightPt = headerCanvas.height * scale; |
| | |
| | // Beschikbare hoogte voor grid op PDF |
| | const gridUsableHeightPt = usableHeight - headerHeightPt - headerGapPt; |
| | if (gridUsableHeightPt <= 50) { |
| | alert('Header is te hoog voor A4 liggend. Verklein header of marges.'); |
| | return; |
| | } |
| | |
| | // 4) Bepaal "rijhoogte" in canvas pixels op basis van echte DOM-waarden |
| | // (Robuuster dan hard-coded 210/10) |
| | const cardEl = document.querySelector('.collage-card'); |
| | const gridEl = document.getElementById('collageGrid'); |
| | const rowGapPx = parseFloat(getComputedStyle(gridEl).rowGap || '0') || 0; |
| | const cardHpx = cardEl ? cardEl.getBoundingClientRect().height : 210; |
| | const rowHpx = Math.round((cardHpx + rowGapPx) * 2); |
| | // *2 omdat html2canvas(scale:2) canvas pixels verdubbelt |
| | |
| | // Startpositie van grid binnen de fullCanvas: |
| | // We nemen headerCanvas hoogte + (margin-bottom van header in CSS) ~ 10px. |
| | // In jouw CSS heeft header margin-bottom:10px; die zit in de fullCanvas. |
| | const headerBlockPx = headerCanvas.height + Math.round(10 * 2); |
| | |
| | // Hoeveel rijen passen per pagina? |
| | const gridPagePixelHeightRaw = gridUsableHeightPt / scale; // terug naar canvas-pixels |
| | const rowsPerPage = Math.max(1, Math.floor(gridPagePixelHeightRaw / rowHpx)); |
| | const sliceHeightPx = rowsPerPage * rowHpx; |
| | |
| | // 5) Slicing: alleen het gridgedeelte (onder header), netjes op rijen |
| | let yOffset = headerBlockPx; |
| | const gridBottom = fullCanvas.height; |
| | |
| | const sliceCanvas = document.createElement('canvas'); |
| | const sliceCtx = sliceCanvas.getContext('2d'); |
| | sliceCanvas.width = fullCanvas.width; |
| | |
| | let pageIndex = 0; |
| | while (yOffset < gridBottom) { |
| | if (pageIndex > 0) pdf.addPage('a4', 'landscape'); |
| | |
| | // 5a) Header op elke pagina |
| | const headerImg = headerCanvas.toDataURL('image/png'); |
| | pdf.addImage(headerImg, 'PNG', margin, margin, usableWidth, headerHeightPt); |
| | |
| | // 5b) Grid-slice voor deze pagina |
| | const remaining = gridBottom - yOffset; |
| | |
| | // Normaal: volle pagina op rijen |
| | let h = Math.min(sliceHeightPx, remaining); |
| | |
| | // Als we bij het einde zijn en er resteert minder dan één rij: |
| | // pak die rest alsnog (anders valt er content af). |
| | if (remaining < rowHpx) { |
| | h = remaining; |
| | } |
| | |
| | sliceCanvas.height = h; |
| | sliceCtx.clearRect(0, 0, sliceCanvas.width, h); |
| | sliceCtx.drawImage(fullCanvas, 0, yOffset, fullCanvas.width, h, 0, 0, fullCanvas.width, h); |
| | |
| | const sliceImg = sliceCanvas.toDataURL('image/png'); |
| | const sliceHeightPt = h * scale; |
| | |
| | pdf.addImage( |
| | sliceImg, |
| | 'PNG', |
| | margin, |
| | margin + headerHeightPt + headerGapPt, |
| | usableWidth, |
| | sliceHeightPt |
| | ); |
| | |
| | yOffset += h; |
| | pageIndex++; |
| | } |
| | |
| | pdf.save(makeFilenameBase() + '.pdf'); |
| | |
| | document.getElementById('exportStatus').textContent = ''; |
| | } |
| | |
| |
| </script> | </script> |
| </html> | </html> |