8181.nav-logo-mark {
8282 width : 30px ;
8383 height : 30px ;
84- border-radius : 7px ;
85- background : linear-gradient (135deg , # 1a3a7a 0% , # 2d5fcc 50% , # 4f8fff 100% );
86- display : flex;
87- align-items : center;
88- justify-content : center;
89- font-family : var (--display );
90- font-size : 12px ;
91- font-weight : 700 ;
92- color : # fff ;
93- letter-spacing : -0.5px ;
9484 flex-shrink : 0 ;
85+ object-fit : contain;
9586}
9687
9788.nav-logo span {
206197.hero-sub {
207198 font-size : 16px ;
208199 color : var (--text2 );
209- max-width : 560 px ;
200+ max-width : 600 px ;
210201 line-height : 1.7 ;
211202 margin-bottom : 36px ;
212203 font-weight : 300 ;
222213 border-radius : 4px ;
223214}
224215
216+ .hero-sub b {
217+ color : var (--text );
218+ font-weight : 500 ;
219+ }
220+
225221.hero-actions {
226222 display : flex;
227223 gap : 12px ;
284280}
285281.hb-blue { background : rgba (79 , 143 , 255 , 0.1 ); color : var (--accent2 ); border : 1px solid rgba (79 , 143 , 255 , 0.2 ); }
286282.hb-green { background : rgba (62 , 207 , 142 , 0.08 ); color : var (--green2 ); border : 1px solid rgba (62 , 207 , 142 , 0.2 ); }
287- .hb-amber { background : rgba (245 , 166 , 35 , 0.08 ); color : # ffc55a ; border : 1px solid rgba (245 , 166 , 35 , 0.2 ); }
288283
289284/* ── SCREENSHOT STRIP ── */
290285.screenshot-wrap {
659654 border : 1px solid var (--border );
660655}
661656
662- /* ── QUICK START ── */
657+ /* ── QUICK START & VIDEOS ── */
663658.tutorial-steps {
664659 display : grid;
665660 grid-template-columns : repeat (auto-fill, minmax (320px , 1fr ));
703698.tutorial-card h3 { font-size : 15px ; font-weight : 600 ; color : var (--text ); margin-bottom : 10px ; }
704699.tutorial-card p { font-size : 13px ; color : var (--text2 ); line-height : 1.65 ; margin-bottom : 14px ; flex-grow : 1 ; }
705700
701+ .tut-vid-wrap {
702+ position : relative;
703+ margin-top : auto;
704+ width : 100% ;
705+ }
706706.tut-video {
707707 width : 100% ;
708708 border-radius : 6px ;
709709 border : 1px solid var (--border );
710710 background : # 000 ;
711711 display : block;
712- margin-top : auto;
712+ }
713+ .fullscreen-btn {
714+ position : absolute;
715+ top : 8px ;
716+ right : 8px ;
717+ background : rgba (0 , 0 , 0 , 0.6 );
718+ color : # fff ;
719+ border : 1px solid rgba (255 , 255 , 255 , 0.2 );
720+ border-radius : 4px ;
721+ width : 28px ;
722+ height : 28px ;
723+ display : flex;
724+ align-items : center;
725+ justify-content : center;
726+ cursor : pointer;
727+ font-size : 14px ;
728+ transition : background 0.2s , opacity 0.2s ;
729+ opacity : 0 ;
730+ z-index : 10 ;
731+ }
732+ .tut-vid-wrap : hover .fullscreen-btn {
733+ opacity : 1 ;
734+ }
735+ .fullscreen-btn : hover {
736+ background : rgba (0 , 0 , 0 , 0.9 );
713737}
714738
715739.tut-params {
765789.tree-body .t-py { color : var (--green2 ); }
766790.tree-body .t-cm { color : var (--text3 ); font-style : italic; }
767791.tree-body .t-accent { color : var (--amber ); }
768- .tree-body .t-num {
769- display : inline-block;
770- background : rgba (245 , 166 , 35 , 0.1 );
771- border : 1px solid rgba (245 , 166 , 35 , 0.2 );
772- color : var (--amber );
773- padding : 0 5px ;
774- border-radius : 3px ;
775- font-size : 10px ;
776- margin-left : 4px ;
777- }
778792
779793/* ── CITATION ── */
780794.citation-block {
806820.footer-left { display : flex; align-items : center; gap : 10px ; }
807821.footer-logo {
808822 width : 26px ; height : 26px ;
809- border-radius : 6px ;
810- background : linear-gradient (135deg , # 1a3a7a, # 4f8fff );
811- display : flex;
812- align-items : center;
813- justify-content : center;
814- font-family : var (--display );
815- font-size : 10px ;
816- font-weight : 700 ;
817- color : # fff ;
823+ object-fit : contain;
818824}
819825.footer-name { font-family : var (--display ); font-size : 12.5px ; color : var (--text2 ); font-weight : 700 ; }
820826
881887
882888< nav >
883889 < a href ="# " class ="nav-logo ">
884- < div class ="nav-logo-mark "> RV </ div >
890+ < img src =" icon.png " alt =" RasterViz " class ="nav-logo-mark ">
885891 < span > RasterViz</ span >
886892 </ a >
887893 < ul class ="nav-links ">
906912 < h1 > Publication-quality raster maps< br > directly inside < em > QGIS</ em > </ h1 >
907913
908914 < p class ="hero-sub ">
909- RasterViz renders figures styled after < code > rasterio.show()</ code > — with
910- pointed colorbars, geographic coordinate labels, custom palettes, and
911- multi-map layout grids — without a single line of Python.
915+ RasterViz menyediakan cara praktis untuk membuat visualisasi raster kelas publikasi ala < code > rasterio.show()</ code > . Dibangun sepenuhnya menggunakan < b > PyQGIS, PyQt5, NumPy,</ b > dan < b > Matplotlib</ b > agar Anda bisa mendesain peta dengan *colormap* kustom dan label koordinat tanpa harus menulis kode apa pun.
912916 </ p >
913917
914918 < div class ="hero-actions ">
@@ -927,7 +931,6 @@ <h1>Publication-quality raster maps<br>directly inside <em>QGIS</em></h1>
927931 < span class ="hero-badge hb-blue "> v 1.1.0</ span >
928932 < span class ="hero-badge hb-green "> GPL-2.0-or-later</ span >
929933 < span class ="hero-badge hb-blue "> QGIS ≥ 3.0</ span >
930- < span class ="hero-badge hb-amber "> 1,895 lines · 4 files</ span >
931934 < span class ="hero-badge hb-green "> No extra pip install</ span >
932935 </ div >
933936</ section >
@@ -1017,7 +1020,7 @@ <h4>No external dependencies</h4>
10171020< section class ="section " id ="features ">
10181021 < div class ="section-label "> Features</ div >
10191022 < div class ="section-title "> Every control a researcher needs</ div >
1020- < p class ="section-sub "> 1,895 lines across 4 Python files. No bloat — every control maps directly to a Matplotlib parameter.</ p >
1023+ < p class ="section-sub "> No bloat — every control maps directly to a Matplotlib parameter.</ p >
10211024
10221025 < div class ="features-grid reveal ">
10231026 < div class ="feat-card ">
@@ -1236,7 +1239,10 @@ <h3>Install from Source</h3>
12361239 < div class ="tut-step-label "> Step 01</ div >
12371240 < h3 > Open a Raster Layer</ h3 >
12381241 < p > Load a single-band GeoTIFF (e.g. NDVI from Sentinel-2) into QGIS. Launch RasterViz from < code > Raster → QRVIZ</ code > . Select the layer from the dropdown, set Band: 1, and click < strong > READ DATA & RENDER</ strong > .</ p >
1239- < video src ="https://github.com/user-attachments/assets/43229022-5ed2-4978-8b63-0e794f954e4b " autoplay loop muted playsinline class ="tut-video "> </ video >
1242+ < div class ="tut-vid-wrap ">
1243+ < video src ="https://github.com/user-attachments/assets/43229022-5ed2-4978-8b63-0e794f954e4b " autoplay loop muted playsinline class ="tut-video "> </ video >
1244+ < button class ="fullscreen-btn " title ="Fullscreen " onclick ="toggleFullscreen(this.previousElementSibling) "> ⛶</ button >
1245+ </ div >
12401246 </ div >
12411247
12421248 < div class ="tutorial-card ">
@@ -1256,31 +1262,43 @@ <h3>Configure Stretch</h3>
12561262 < div class ="tut-step-label "> Step 03</ div >
12571263 < h3 > Choose a Colormap</ h3 >
12581264 < p > Use the ◀ ▶ arrows to cycle through palettes. A colour ramp preview is shown inline. Enable < strong > Reverse</ strong > to invert any palette.</ p >
1259- < video src ="https://github.com/user-attachments/assets/9c410ae5-5bf6-426d-8e4b-c6c43d1b9ed4 " autoplay loop muted playsinline class ="tut-video "> </ video >
1265+ < div class ="tut-vid-wrap ">
1266+ < video src ="https://github.com/user-attachments/assets/9c410ae5-5bf6-426d-8e4b-c6c43d1b9ed4 " autoplay loop muted playsinline class ="tut-video "> </ video >
1267+ < button class ="fullscreen-btn " title ="Fullscreen " onclick ="toggleFullscreen(this.previousElementSibling) "> ⛶</ button >
1268+ </ div >
12601269 </ div >
12611270
12621271 < div class ="tutorial-card ">
12631272 < div class ="tut-num "> 4</ div >
12641273 < div class ="tut-step-label "> Step 04</ div >
12651274 < h3 > Tune Coordinate Labels</ h3 >
12661275 < p > In Group 6, set coordinate format, decimal places, tick count, and rotation for X and Y axes independently.</ p >
1267- < video src ="https://github.com/user-attachments/assets/22b17462-122c-447a-a239-de7761c4976c " autoplay loop muted playsinline class ="tut-video "> </ video >
1276+ < div class ="tut-vid-wrap ">
1277+ < video src ="https://github.com/user-attachments/assets/22b17462-122c-447a-a239-de7761c4976c " autoplay loop muted playsinline class ="tut-video "> </ video >
1278+ < button class ="fullscreen-btn " title ="Fullscreen " onclick ="toggleFullscreen(this.previousElementSibling) "> ⛶</ button >
1279+ </ div >
12681280 </ div >
12691281
12701282 < div class ="tutorial-card ">
12711283 < div class ="tut-num "> 5</ div >
12721284 < div class ="tut-step-label "> Step 05</ div >
12731285 < h3 > Style the Colorbar</ h3 >
12741286 < p > In Group 7, choose orientation, end style, label, and tick settings. < strong > Both Pointed</ strong > replicates the rasterio aesthetic.</ p >
1275- < video src ="https://github.com/user-attachments/assets/649f535d-ab7b-485d-859e-70d888b7b099 " autoplay loop muted playsinline class ="tut-video "> </ video >
1287+ < div class ="tut-vid-wrap ">
1288+ < video src ="https://github.com/user-attachments/assets/649f535d-ab7b-485d-859e-70d888b7b099 " autoplay loop muted playsinline class ="tut-video "> </ video >
1289+ < button class ="fullscreen-btn " title ="Fullscreen " onclick ="toggleFullscreen(this.previousElementSibling) "> ⛶</ button >
1290+ </ div >
12761291 </ div >
12771292
12781293 < div class ="tutorial-card ">
12791294 < div class ="tut-num "> 6</ div >
12801295 < div class ="tut-step-label "> Step 06</ div >
12811296 < h3 > Export</ h3 >
12821297 < p > Click < strong > EXPORT IMAGE</ strong > in Group 3. Choose PNG for journal submission at 300 DPI, PDF/SVG for posters and slides.</ p >
1283- < video src ="https://github.com/user-attachments/assets/c7030b7b-450f-4e09-81d7-db49638dab80 " autoplay loop muted playsinline class ="tut-video "> </ video >
1298+ < div class ="tut-vid-wrap ">
1299+ < video src ="https://github.com/user-attachments/assets/c7030b7b-450f-4e09-81d7-db49638dab80 " autoplay loop muted playsinline class ="tut-video "> </ video >
1300+ < button class ="fullscreen-btn " title ="Fullscreen " onclick ="toggleFullscreen(this.previousElementSibling) "> ⛶</ button >
1301+ </ div >
12841302 </ div >
12851303 </ div >
12861304</ section >
@@ -1289,7 +1307,7 @@ <h3>Export</h3>
12891307
12901308< section class ="section " id ="codebase ">
12911309 < div class ="section-label "> Codebase</ div >
1292- < div class ="section-title "> 1,895 lines · 4 Python files </ div >
1310+ < div class ="section-title "> Clean & Lightweight Architecture </ div >
12931311 < p class ="section-sub "> Clean single-module architecture. No generated UI files, no binary blobs, no compiled resources.</ p >
12941312
12951313 < div class ="tree-block reveal ">
@@ -1300,9 +1318,9 @@ <h3>Export</h3>
13001318 </ div >
13011319 < div class ="tree-body ">
13021320< span class ="t-dir "> qrviz/</ span > < br >
1303- ├── < span class ="t-py "> __init__.py</ span > < span class ="t-cm "> # classFactory — QGIS plugin entry point</ span > < span class =" t-num " > 8 lines </ span > < br >
1304- ├── < span class ="t-py "> qrviz.py</ span > < span class ="t-cm "> # QRVIZPlugin — initGui, unload, run</ span > < span class =" t-num " > 42 lines </ span > < br >
1305- ├── < span class ="t-py "> dialog.py</ span > < span class ="t-cm "> # Main dialog</ span > < span class =" t-num " > 1,693 lines </ span > < br >
1321+ ├── < span class ="t-py "> __init__.py</ span > < span class ="t-cm "> # classFactory — QGIS plugin entry point</ span > < br >
1322+ ├── < span class ="t-py "> qrviz.py</ span > < span class ="t-cm "> # QRVIZPlugin — initGui, unload, run</ span > < br >
1323+ ├── < span class ="t-py "> dialog.py</ span > < span class ="t-cm "> # Main dialog</ span > < br >
13061324│ ├── < span class ="t-accent "> DiscreteClassRow</ span > < span class ="t-cm "> # Per-class colour/label/decimal widget</ span > < br >
13071325│ ├── < span class ="t-accent "> LayoutSlotWidget</ span > < span class ="t-cm "> # Per-slot config for layout series</ span > < br >
13081326│ └── < span class ="t-accent "> QRVIZDialog</ span > < br >
@@ -1315,7 +1333,7 @@ <h3>Export</h3>
13151333│ ├── _style_axes() < span class ="t-cm "> # Rotation, tick count, formatters</ span > < br >
13161334│ ├── _make_lon_formatter() < span class ="t-cm "> # DMS/DM/DD/UTM closures</ span > < br >
13171335│ └── export_figure() / _export_layout()< br >
1318- ├── < span class ="t-py "> colormaps.py</ span > < span class ="t-cm "> # Custom palette registry</ span > < span class =" t-num " > 152 lines </ span > < br >
1336+ ├── < span class ="t-py "> colormaps.py</ span > < span class ="t-cm "> # Custom palette registry</ span > < br >
13191337│ ├── CUSTOM_PALETTES < span class ="t-cm "> # 24 domain-specific colormaps</ span > < br >
13201338│ └── COLORMAPS < span class ="t-cm "> # Master list ~60 entries</ span > < br >
13211339├── < span class ="t-accent "> metadata.txt</ span > < span class ="t-cm "> # QGIS plugin metadata</ span > < br >
@@ -1341,7 +1359,7 @@ <h3>Export</h3>
13411359
13421360< footer >
13431361 < div class ="footer-left ">
1344- < div class ="footer-logo "> RV </ div >
1362+ < img src =" icon.png " alt =" RV " class ="footer-logo ">
13451363 < span class ="footer-name "> RasterViz</ span >
13461364 < span style ="font-size:12px;color:var(--text3);margin-left:4px "> v1.1.0</ span >
13471365 </ div >
@@ -1356,6 +1374,17 @@ <h3>Export</h3>
13561374</ footer >
13571375
13581376< script >
1377+ /* ── Fullscreen Video Toggle ── */
1378+ function toggleFullscreen ( elem ) {
1379+ if ( elem . requestFullscreen ) {
1380+ elem . requestFullscreen ( ) ;
1381+ } else if ( elem . webkitRequestFullscreen ) { /* Safari */
1382+ elem . webkitRequestFullscreen ( ) ;
1383+ } else if ( elem . msRequestFullscreen ) { /* IE11 */
1384+ elem . msRequestFullscreen ( ) ;
1385+ }
1386+ }
1387+
13591388function lerp ( a , b , t ) { return a + ( b - a ) * t }
13601389function hexToRgb ( h ) { return [ parseInt ( h . slice ( 1 , 3 ) , 16 ) , parseInt ( h . slice ( 3 , 5 ) , 16 ) , parseInt ( h . slice ( 5 , 7 ) , 16 ) ] }
13611390function interpColor ( stops , t ) {
0 commit comments