pro unlimited code gps

Table of Contents

 


<html lang="id">

<head>

<meta charset="UTF-8"></meta>

<meta content="width=device-width, initial-scale=1.0" name="viewport"></meta>

<title>Orange Geotag Pro</title>


<style>

*{

    margin:0;

    padding:0;

    box-sizing:border-box;

}


body{

    background:#f1f1f1;

    font-family:'Segoe UI',sans-serif;

    padding:20px;

}


.wrapper{

    max-width:1400px;

    margin:auto;

    display:grid;

    grid-template-columns:350px 1fr;

    gap:20px;

}


.panel{

    background:#fff;

    border-radius:25px;

    padding:25px;

    box-shadow:0 10px 30px rgba(0,0,0,0.08);

}


.logo{

    display:flex;

    align-items:center;

    gap:12px;

    margin-bottom:25px;

}


.logo h1{

    font-size:32px;

    color:#ff7b00;

}


.logo p{

    color:#666;

}


.upload-btn,

button{

    width:100%;

    border:none;

    background:#ff7b00;

    color:white;

    padding:18px;

    border-radius:15px;

    font-size:18px;

    font-weight:bold;

    cursor:pointer;

}


.card{

    margin-top:20px;

    background:#fafafa;

    border-radius:20px;

    padding:20px;

    border:1px solid #eee;

}


.card h3{

    margin-bottom:15px;

    color:#333;

}


label{

    display:block;

    margin-bottom:8px;

    color:#444;

    font-weight:600;

}


textarea,

input,

select{

    width:100%;

    padding:14px;

    border-radius:12px;

    border:1px solid #ddd;

    margin-bottom:15px;

    font-size:15px;

}


.grid{

    display:grid;

    grid-template-columns:1fr 1fr;

    gap:12px;

}


.preview{

    background:#fff;

    border-radius:25px;

    padding:20px;

    box-shadow:0 10px 30px rgba(0,0,0,0.08);

}


canvas{

    width:100%;

    border-radius:20px;

    background:#ddd;

}


.actions{

    display:flex;

    justify-content:space-between;

    gap:15px;

    margin-top:20px;

}


.download{

    flex:1;

    text-align:center;

    background:#2ebd59;

    color:white;

    text-decoration:none;

    padding:18px;

    border-radius:15px;

    font-weight:bold;

    display:none;

}


.status{

    margin-top:15px;

    padding:14px;

    border-radius:12px;

    background:#f3fff5;

    color:#1c7f38;

}


@media(max-width:900px){

    .wrapper{

        grid-template-columns:1fr;

    }

}

</style>

</head>

<body>


<div class="wrapper">


    <div class="panel">


        <div class="logo">

            <div style="font-size: 45px;">📍</div>

            <div>

                <h1>Orange</h1>

                <p>Geotag Pro Ultimate</p>

            </div>

        </div>


        <label class="upload-btn">

            📸 Upload / Ambil Foto

            <input accept="image/*" capture="environment" hidden="" id="upload" type="file" />

        </label>


        <div class="card">


            <h3>📌 Informasi Lokasi</h3>


            <label>Alamat</label>

            <textarea id="address" rows="3"></textarea>


            <div class="grid">


                <div>

                    <label>Latitude</label>

                    <input id="lat" type="text" />

                </div>


                <div>

                    <label>Longitude</label>

                    <input id="lon" type="text" />

                </div>


            </div>


        </div>


        <div class="card">


            <h3>⚙ Pengaturan Watermark</h3>


            <label>Ukuran Peta</label>

            <select id="mapSize">

                <option value="small">Kecil</option>

                <option selected="" value="medium">Sedang</option>

                <option value="large">Besar</option>

            </select>


            <label>Posisi Peta</label>

            <select id="mapPosition">

                <option value="bottom-right">Kanan Bawah</option>

                <option value="bottom-left">Kiri Bawah</option>

                <option value="top-right">Kanan Atas</option>

                <option value="top-left">Kiri Atas</option>

            </select>


            <label>Transparansi Peta</label>

            <input id="opacity" max="100" min="20" type="range" value="75" />


            <button id="processBtn">

                🚀 Proses Geotag Foto

            </button>


        </div>


        <div class="status" id="status">

            Menunggu upload foto...

        </div>


    </div>


    <div class="preview">


        <canvas id="canvas"></canvas>


        <div class="actions">

            <button onclick="location.reload()">

                🔄 Reset

            </button>


            <a class="download" id="downloadBtn">

                ⬇ Download Foto

            </a>

        </div>


    </div>


</div>


<script>


const upload = document.getElementById('upload');

const canvas = document.getElementById('canvas');

const ctx = canvas.getContext('2d');


const processBtn = document.getElementById('processBtn');

const downloadBtn = document.getElementById('downloadBtn');

const status = document.getElementById('status');


let originalImage = null;


upload.addEventListener('change', function(e){

    const file = e.target.files[0];

    if(!file) return;


    status.innerHTML = '⏳ Memuat foto...';

    const reader = new FileReader();


    reader.onload = function(event){

        const img = new Image();

        img.onload = function(){

            originalImage = img;

            drawBaseImage();

            getLocation();

            status.innerHTML = '✅ Foto berhasil dimuat. Mengambil lokasi GPS...';

        }

        img.src = event.target.result;

    }

    reader.readAsDataURL(file);

});


function drawBaseImage(){

    const maxWidth = 1400;

    let width = originalImage.width;

    let height = originalImage.height;


    if(width > maxWidth){

        height *= maxWidth / width;

        width = maxWidth;

    }


    canvas.width = width;

    canvas.height = height;


    ctx.drawImage(originalImage, 0, 0, width, height);

}


function getLocation(){

    if (!navigator.geolocation) {

        status.innerHTML = '❌ Geolocation tidak didukung browser ini.';

        return;

    }


    navigator.geolocation.getCurrentPosition(

        async function(position){

            const lat = position.coords.latitude.toFixed(6);

            const lon = position.coords.longitude.toFixed(6);


            document.getElementById('lat').value = lat;

            document.getElementById('lon').value = lon;


            try{

                status.innerHTML = '⏳ Menghubungkan ke OpenStreetMap...';

                const response = await fetch(

                    `https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lon}`

                );

                const data = await response.json();

                document.getElementById('address').value = data.display_name || 'Alamat tidak ditemukan';

                status.innerHTML = '✅ GPS dan Alamat siap diproses!';

            }catch(err){

                console.log(err);

                status.innerHTML = '⚠️ Gagal mengambil alamat, silakan isi manual.';

            }

        },

        function(error) {

            status.innerHTML = '⚠️ Akses GPS ditolak. Silakan isi manual.';

        }

    );

}


processBtn.addEventListener('click', function(){

    if(!originalImage) {

        alert('Silakan upload foto terlebih dahulu!');

        return;

    }


    status.innerHTML = '⏳ Memproses Geotag...';

    drawBaseImage();


    const lat = document.getElementById('lat').value || '0.000000';

    const lon = document.getElementById('lon').value || '0.000000';

    const address = document.getElementById('address').value || '-';


    const opacity = document.getElementById('opacity').value / 100;

    const mapSize = document.getElementById('mapSize').value;

    const mapPosition = document.getElementById('mapPosition').value;


    let mapWidth = 260;

    let mapHeight = 160;


    if(mapSize === 'small'){

        mapWidth = 220;

        mapHeight = 130;

    }

    if(mapSize === 'large'){

        mapWidth = 340;

        mapHeight = 200;

    }


    const mapImage = new Image();

    mapImage.crossOrigin = 'anonymous'; 

    

    // INTEGRASI YANDEX STATIC MAPS API

    // Format Yandex: ll=longitude,latitude & pt=longitude,latitude,style_marker

    mapImage.src = `https://static-maps.yandex.ru/1.x/?ll=${lon},${lat}&z=16&l=map&size=450,300&pt=${lon},${lat},pm2orl`;


    mapImage.onload = function(){

        let mapX = 25;

        let mapY = 25;


        if(mapPosition === 'top-right'){

            mapX = canvas.width - mapWidth - 25;

            mapY = 25;

        }

        if(mapPosition === 'bottom-right'){

            mapX = canvas.width - mapWidth - 25;

            mapY = canvas.height - mapHeight - 195; // Jarak aman agar box teks hitam di bawah tidak tertimpa

        }

        if(mapPosition === 'bottom-left'){

            mapX = 25;

            mapY = canvas.height - mapHeight - 195; // Jarak aman agar box teks hitam di bawah tidak tertimpa

        }

        if(mapPosition === 'top-left'){

            mapX = 25;

            mapY = 25;

        }


        // 1. Gambar Peta Mini dengan Sudut Melengkung (Borders)

        ctx.save();

        ctx.globalAlpha = opacity;

        roundRect(mapX, mapY, mapWidth, mapHeight, 18);

        ctx.clip();

        ctx.drawImage(mapImage, mapX, mapY, mapWidth, mapHeight);

        ctx.restore();


        // 2. Gambar Bingkai Putih di Sekeliling Peta

        ctx.save();

        ctx.lineWidth = 4;

        ctx.strokeStyle = 'rgba(255,255,255,0.9)';

        roundRect(mapX, mapY, mapWidth, mapHeight, 18);

        ctx.stroke();

        ctx.restore();


        // 3. Tulis Informasi Data Geotag (Teks)

        drawText(address, lat, lon);


        // 4. Ekspor ke Tombol Download

        exportImage();

    };


    mapImage.onerror = function() {

        // Fallback jika terjadi gangguan koneksi ke server Yandex

        drawText(address, lat, lon);

        exportImage();

        status.innerHTML = '⚠️ Selesai tanpa Peta Mini (Gagal memuat server Yandex)';

    };

});


function drawText(address, lat, lon){

    const overlayHeight = 170;


    // Latar belakang box hitam transparan di bawah foto

    ctx.fillStyle = 'rgba(0,0,0,0.55)';

    ctx.fillRect(0, canvas.height - overlayHeight, canvas.width, overlayHeight);


    ctx.fillStyle = '#fff';

    ctx.font = 'bold 22px "Segoe UI", sans-serif';


    const now = new Date();

    const tanggal = now.toLocaleDateString('id-ID', { day: 'numeric', month: 'long', year: 'numeric' });

    const jam = now.toLocaleTimeString('id-ID') + ' WIB';


    let y = canvas.height - 125;


    // Bungkus teks alamat agar otomatis turun baris jika kepanjangan

    const maxTextWidth = canvas.width - 60;

    const addressLines = wrapText(ctx, '📍 ' + address, maxTextWidth);


    addressLines.forEach(line => {

        ctx.fillText(line, 30, y);

        y += 30;

    });


    ctx.fillText('🌍 Latitude : ' + lat, 30, y);

    y += 30;

    ctx.fillText('🧭 Longitude : ' + lon, 30, y);

    y += 30;

    ctx.fillText('📅 ' + tanggal + ' | ⏰ ' + jam, 30, y);

}


function wrapText(context, text, maxWidth) {

    const words = text.split(' ');

    const lines = [];

    let currentLine = words[0];


    for (let i = 1; i < words.length; i++) {

        const word = words[i];

        const width = context.measureText(currentLine + " " + word).width;

        if (width < maxWidth) {

            currentLine += " " + word;

        } else {

            lines.push(currentLine);

            currentLine = word;

        }

    }

    lines.push(currentLine);

    return lines.slice(0, 2); // Maksimal ambil 2 baris alamat agar rapi

}


function exportImage(){

    try {

        const finalImage = canvas.toDataURL('image/jpeg', 0.95);

        downloadBtn.href = finalImage;

        downloadBtn.download = 'orange-geotag-pro-' + Date.now() + '.jpg';

        downloadBtn.style.display = 'block';

        status.innerHTML = '✅ Watermark mini map berhasil dibuat!';

    } catch(err) {

        console.error(err);

        status.innerHTML = '❌ Gagal ekspor gambar karena masalah keamanan browser (CORS).';

    }

}


function roundRect(x,y,w,h,r){

    ctx.beginPath();

    ctx.moveTo(x+r,y);

    ctx.lineTo(x+w-r,y);

    ctx.quadraticCurveTo(x+w,y,x+w,y+r);

    ctx.lineTo(x+w,y+h-r);

    ctx.quadraticCurveTo(x+w,y+h,x+w-r,y+h);

    ctx.lineTo(x+r,y+h);

    ctx.quadraticCurveTo(x,y+h,x,y+h-r);

    ctx.lineTo(x,y+r);

    ctx.quadraticCurveTo(x,y,x+r,y);

    ctx.closePath();

}


</script>


</body>

</html>

Posting Komentar