您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
use openstreetmap to navigate the world faster, and press insert above your preferred coordinates to visit them on wplace!
// ==UserScript== // @name wplace - simple map browser // @namespace http://pawing.cv // @version v1.1 // @description use openstreetmap to navigate the world faster, and press insert above your preferred coordinates to visit them on wplace! // @author cv // @match https://wplace.live/* // @grant none // ==/UserScript== (function() { 'use strict'; function openmap() { let popupcode = `<!DOCTYPE html> <html lang="en"> <head> <title>OpenStreetMap</title> <meta charset="utf-8"> <style> @import url("https://fonts.googleapis.com/css2?family=Geist:[email protected]&display=swap"); html, body, .map { height: 100%; line-height: 1; margin: 0; padding: 0; font-family: "Geist", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !important; } a, span, p, li, input, ul { font-family: Geist, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !important; user-select: none; } .coords, .small {user-select: all !important} .info { display: flex; flex-direction: row; position: fixed; justify-content: center; align-items: center; top: 1em; left: 50%; transform: translateX(-50%); background: #f2f7fe; padding: 10px; border-radius: 32px; font-size: 13.5px; font-weight: 700; z-index: 1000; box-shadow: 0 5px 16px 0 rgba(0,0,0,0.1); color: #394e6a; pointer-events: none; user-select: none; } .info svg { padding-left: 3px; padding-right: 2px; width: 15px; } .coords { display: flex; flex-direction: column; position: fixed; width: 300px; bottom: 1em; left: 50%; transform: translateX(-50%); background: #f2f7fe; display: none; padding: 20px; border-radius: 32px; font-size: 18px; z-index: 1000; font-weight: 500; box-shadow: 0 5px 16px 0 rgba(0,0,0,0.1); color: #394e6a; } .small { font-size: 13px; color: #394e6a; opacity: 0.5; } div.leaflet-control-container > div.leaflet-top.leaflet-left > div { border: none; } div.leaflet-control-container > div.leaflet-top.leaflet-left > div > a { display: flex; flex-direction: column; background: #f2f7fe; border-radius: 32px; margin-bottom: 3px; font-size: 13px; box-shadow: 0 5px 16px 0 rgba(0,0,0,0.1); color: #394e6a; } div.leaflet-top.leaflet-right * { border: none; } div.leaflet-top.leaflet-right > div > button, div.leaflet-top.leaflet-right > div { display: flex; flex-direction: column; background: #f2f7fe; border-radius: 32px; margin-bottom: 3px; color: #394e6a; } div.leaflet-top.leaflet-right > div > button { display: none; } div.leaflet-top.leaflet-right > div > div.leaflet-control-geocoder-form { display: inline-block; width: 200px; padding: 10px; box-shadow: 0 5px 16px 0 rgba(0,0,0,0.1); } div.leaflet-top.leaflet-right > div > .leaflet-control-geocoder-alternatives { border-radius: 1px; padding: 10px; } div.leaflet-top.leaflet-right > div:has(.leaflet-control-geocoder-alternatives:not([style*="display: none"])) > .leaflet-control-geocoder-form { box-shadow: none !important; } body > div.map.leaflet-container.leaflet-touch.leaflet-fade-anim.leaflet-grab.leaflet-touch-drag.leaflet-touch-zoom > div.leaflet-control-container > div.leaflet-bottom.leaflet-right { display: none !important; } .leaflet-control-geocoder-form-no-error { text-align: center; color: rgb(179, 97, 97) !important; padding-bottom: 10px; } </style> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css" /> <link rel="stylesheet" href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css" /> </head> <body> <div class="info">Choose a location with <svg alt="Right Click" fill="#394e6a" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52"><path d="M38 0h4v6h-4V0Zm9 1 4 2c-2 4-2 4-7 5 1-5 1-5 3-7ZM36 5c8 6 9 12 9 22v6c-2 10-5 14-14 19-10 1-16 1-23-6-4-7-5-11-5-19v-6C5 4 21-3 36 5ZM9 17l-1 9h14V7c-7 0-10 5-13 10ZM8 30c2 9 3 13 11 17 11 0 14-1 20-10l1-7H8Zm38-20h6v4h-6v-4Z"/></svg>!</div> <div class="coords"></div> <div class="map" style="width:100%;height:100%;"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.js"></script> <script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.js"></script> <script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.Photon.js"></script> <script> document.addEventListener("contextmenu", function(e) {e.preventDefault()}); var map = L.map(document.querySelector(".map"), { worldCopyJump: false, continuousWorld: false }).setView([0, 0], 1); map.setMaxBounds([[-85.05112878, -180], [85.05112878, 180]]); L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {noWrap: true}).addTo(map); map.on('drag', function() { if (!map.getBounds().intersects(map.options.maxBounds)) { map.panInsideBounds(map.options.maxBounds, { animate: false }); } }); L.Control.geocoder({ geocoder: new L.Control.Geocoder.Photon() }).addTo(map); var lastlatlng = null; map.on("mousemove", function(e) { lastlatlng = e.latlng; var lat = e.latlng.lat; var lng = e.latlng.lng; var zoom = map.getZoom(); var tile_count = 2048; var tile_size = 1000; var pixel_count = tile_count * tile_size; var x = (lng + 180) / 360; var sinlat = Math.sin(lat * Math.PI / 180); var y = 0.5 - Math.log((1 + sinlat) / (1 - sinlat)) / (4 * Math.PI); x = Math.min(1, Math.max(0, x)); y = Math.min(1, Math.max(0, y)); var px = x * (pixel_count - 1); var py = y * (pixel_count - 1); var t_x = Math.floor(px / tile_size); var t_y = Math.floor(py / tile_size); var p_x = Math.floor(px % tile_size); var p_y = Math.floor(py % tile_size); document.querySelector(".coords").innerHTML = lat.toFixed(6) + ", " + lng.toFixed(6) + " [x" + zoom + "] " + "<br><span class='small'>" + t_x + ", " + t_y + " // " + p_x + ", " + p_y + "</span>"; var coords = document.querySelector(".coords"); if (coords.innerHTML.trim() !== "") {coords.style.display = "flex"} else {coords.style.display = "none"} }); document.querySelector(".map").addEventListener("contextmenu", function(ev) { ev.preventDefault(); if (lastlatlng) { var osmzoom = map.getZoom(); var wplacezoom = Math.max(1, Math.min(19, osmzoom)); window.opener.postMessage({ lat: lastlatlng.lat, lng: lastlatlng.lng, zoom: wplacezoom, source: "wplace-map-popup" }, "*"); window.close(); } }); </script> </body> </html>`; const left = (window.screen.width - 800) / 2; const top = (window.screen.height - 600) / 2; const popup = window.open( '', 'wplace_map_popup', `width=800,height=600,left=${left},top=${top},resizable=yes,scrollbars=no,status=no,location=no,toolbar=no,menubar=no` ); if (popup) { const writepopup = () => { if (popup.document && popup.document.readyState === "complete") { popup.document.open(); popup.document.write(popupcode); popup.document.close(); } else {setTimeout(writepopup, 10)} }; writepopup(); } else {alert("Popup failed to open! (do you have popups disabled?)")} } function cleanlink() { const cleanlink = new URL(window.location.href); cleanlink.searchParams.delete('lat'); cleanlink.searchParams.delete('lng'); cleanlink.searchParams.delete('zoom'); window.history.replaceState({}, '', cleanlink.pathname + cleanlink.search + cleanlink.hash); } window.addEventListener('message', function(event) { if (event.data && event.data.source === 'wplace-map-popup' && typeof event.data.lat === 'number' && typeof event.data.lng === 'number') { const currentlink = new URL(window.location.href); currentlink.searchParams.set('lat', event.data.lat); currentlink.searchParams.set('lng', event.data.lng); if (typeof event.data.zoom === 'number') { currentlink.searchParams.set('zoom', event.data.zoom); } window.location.replace(currentlink.toString()); window.addEventListener('pageshow', cleanlink); } }); window.addEventListener('DOMContentLoaded', function() { const url = new URL(window.location.href); if (url.searchParams.has('lat') || url.searchParams.has('lng') || url.searchParams.has('zoom')) { cleanlink(); } }); document.addEventListener('keydown', function(e) { if (e.key === 'M' || e.key === 'm') {openmap()} }); })();