Shifting to dynamically created PNGs.
45
css/countrysel.css
Normal file
@@ -0,0 +1,45 @@
|
||||
.autocomplete {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#autocomplete-list {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.autocomplete-items {
|
||||
position: absolute;
|
||||
border: 1px solid #d4d4d4;
|
||||
border-bottom: none;
|
||||
border-top: none;
|
||||
z-index: 99;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.autocomplete-items div {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #d4d4d4;
|
||||
}
|
||||
|
||||
.autocomplete-items div:hover {
|
||||
background-color: #e9e9e9;
|
||||
}
|
||||
|
||||
.autocomplete-active {
|
||||
background-color: #1E90FF !important;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.autocomplete-active {
|
||||
background-color: #1E90FF !important;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.download-PNG {
|
||||
font-family: sans-serif;
|
||||
}
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 139 KiB |
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 164 KiB |
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 174 KiB After Width: | Height: | Size: 174 KiB |
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 178 KiB |
Before Width: | Height: | Size: 183 KiB After Width: | Height: | Size: 183 KiB |
Before Width: | Height: | Size: 167 KiB After Width: | Height: | Size: 167 KiB |
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 145 KiB |
Before Width: | Height: | Size: 209 KiB After Width: | Height: | Size: 209 KiB |
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 109 KiB |
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 134 KiB |
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 131 KiB |
Before Width: | Height: | Size: 184 KiB After Width: | Height: | Size: 184 KiB |
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 168 KiB |
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 164 KiB |
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 172 KiB |
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 197 KiB |
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 129 KiB |
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 155 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 152 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 144 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 99 KiB |
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 147 KiB |
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 108 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
@@ -22,53 +22,6 @@ fetch('https://robbieandrew.github.io/data/countryData.json')
|
||||
})
|
||||
.catch(error => console.error('Error loading country data:', error));
|
||||
|
||||
function downloadSVGasPNG(svgObject) {
|
||||
try {
|
||||
const svg = svgObject.contentDocument.querySelector('svg');
|
||||
|
||||
// Create a canvas element
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// Set canvas dimensions, maintaining aspect ratio
|
||||
const svgRect = svg.getBoundingClientRect();
|
||||
canvas.width = 1024;
|
||||
canvas.height = svgRect.height/svgRect.width*canvas.width;
|
||||
|
||||
// Convert SVG to a data URL
|
||||
const svgData = new XMLSerializer().serializeToString(svg);
|
||||
const svgBlob = new Blob([svgData], {type: 'image/svg+xml;charset=utf-8'});
|
||||
const DOMURL = window.URL || window.webkitURL || window;
|
||||
const svgUrl = DOMURL.createObjectURL(svgBlob);
|
||||
|
||||
// Create an image from the SVG
|
||||
const img = new Image();
|
||||
img.onload = function() {
|
||||
// First draw a white background
|
||||
ctx.fillStyle = 'white';
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
// Then draw the image on the canvas
|
||||
ctx.drawImage(img, 0, 0);
|
||||
DOMURL.revokeObjectURL(svgUrl);
|
||||
|
||||
// Convert canvas to PNG and initiate download
|
||||
canvas.toBlob(function(blob) {
|
||||
const url = DOMURL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `${svgObject.getAttribute('data').split('/').pop().replace('.svg', '')}.png`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
DOMURL.revokeObjectURL(url);
|
||||
}, 'image/png');
|
||||
};
|
||||
img.src = svgUrl;
|
||||
} catch (error) {
|
||||
console.warn("Unable to access SVG content! (Are you running locally?",error);
|
||||
}
|
||||
}
|
||||
|
||||
function addDownloadLink(svgObject) {
|
||||
const container = svgObject.parentNode;
|
||||
// Create the link
|
||||
|
@@ -6,21 +6,18 @@ function downloadSVGasPNG(svgObject) {
|
||||
// Make a copy (clone) of the SVG object so we can manipulate it
|
||||
const clonedSvg = svg.cloneNode(true);
|
||||
|
||||
// Remove foreignObject elements from the clone. These are seen by the browser as cross-origin, and cause conversion to fail.
|
||||
// Remove any foreignObject elements from the clone. These are seen by the browser as cross-origin, and cause conversion (toBlob) to fail.
|
||||
const foreignObjects = clonedSvg.querySelectorAll('foreignObject');
|
||||
foreignObjects.forEach(fo => fo.remove());
|
||||
|
||||
// Create a canvas element (raster)
|
||||
// Create a canvas element (bitmap)
|
||||
const canvas = document.createElement('canvas');
|
||||
|
||||
// Set canvas dimensions, maintaining aspect ratio
|
||||
const svgRect = svg.getBoundingClientRect();
|
||||
const width = Math.round(svgRect.width);
|
||||
const height = Math.round(svgRect.height);
|
||||
|
||||
// To improve antialiasing in the final render, first convert to raster at double the desired resolution before later scaling down again
|
||||
const scale = 2;
|
||||
canvas.width = 1852 * scale;
|
||||
// Maintain aspect ratio
|
||||
const svgRect = svg.getBoundingClientRect();
|
||||
canvas.height = Math.round(svgRect.height/svgRect.width*canvas.width);
|
||||
|
||||
const ctx = canvas.getContext('2d');
|
||||
@@ -31,7 +28,7 @@ function downloadSVGasPNG(svgObject) {
|
||||
const DOMURL = window.URL || window.webkitURL || window;
|
||||
const svgUrl = DOMURL.createObjectURL(svgBlob);
|
||||
|
||||
// Create an image from the SVG
|
||||
// Create a bitmap from the SVG
|
||||
const img = new Image();
|
||||
img.onload = function() {
|
||||
// First draw a white background
|
||||
@@ -69,7 +66,7 @@ function downloadSVGasPNG(svgObject) {
|
||||
};
|
||||
img.src = svgUrl;
|
||||
} catch (error) {
|
||||
console.warn("Unable to access SVG content! (Are you running locally?",error);
|
||||
console.warn("Unable to access SVG content! (Are you running locally?)",error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +76,7 @@ function createDownloadLink(svgObject) {
|
||||
downloadLink.href = '#';
|
||||
downloadLink.textContent = 'Download as PNG';
|
||||
downloadLink.className = 'download-PNG';
|
||||
// Add click event
|
||||
// Add click event handler
|
||||
downloadLink.addEventListener('click', (e) => {
|
||||
e.preventDefault(); // prevent browser trying to navigate to https://.../#
|
||||
downloadSVGasPNG(svgObject);
|
||||
|
@@ -1,55 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta charset="utf-8">
|
||||
<title>Country Pictures</title>
|
||||
<style>
|
||||
.autocomplete {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#autocomplete-list {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.autocomplete-items {
|
||||
position: absolute;
|
||||
border: 1px solid #d4d4d4;
|
||||
border-bottom: none;
|
||||
border-top: none;
|
||||
z-index: 99;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.autocomplete-items div {
|
||||
padding: 10px;
|
||||
cursor: pointer;
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #d4d4d4;
|
||||
}
|
||||
|
||||
.autocomplete-items div:hover {
|
||||
background-color: #e9e9e9;
|
||||
}
|
||||
|
||||
.autocomplete-active {
|
||||
background-color: #1E90FF !important;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.autocomplete-active {
|
||||
background-color: #1E90FF !important;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.download-PNG {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" type="text/css" href="css/countrysel.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="autocomplete">
|
||||
@@ -57,6 +11,7 @@
|
||||
<div id="autocomplete-list" class="autocomplete-items"></div>
|
||||
</div>
|
||||
<div id="countryImages"></div>
|
||||
<script src="js/downloadSVGasPNG.js"></script>
|
||||
<script src="js/countryselector.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|