Fix #640: generate an icon with a white background automatically
This commit is contained in:
parent
508ef8a970
commit
278fce8726
4 changed files with 103 additions and 83 deletions
|
@ -277,8 +277,6 @@
|
|||
],
|
||||
"id": "bike_repair_station-opening_hours"
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
"question": {
|
||||
"en": "Who maintains this cycle pump?",
|
||||
|
@ -331,7 +329,6 @@
|
|||
"render": "<a href='tel:{phone}'>{phone}</a>",
|
||||
"id": "bike_repair_station-phone"
|
||||
},
|
||||
|
||||
{
|
||||
"id": "bike_repair_station-bike-chain-tool",
|
||||
"question": {
|
||||
|
|
|
@ -9,52 +9,52 @@
|
|||
"orientation": "portrait-primary, landscape-primary",
|
||||
"icons": [
|
||||
{
|
||||
"src": "assets/generated/svg_mapcomplete_logo72.png",
|
||||
"src": "./assets/generated/svg_mapcomplete_logo72.png",
|
||||
"sizes": "72x72",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "assets/generated/svg_mapcomplete_logo96.png",
|
||||
"src": "./assets/generated/svg_mapcomplete_logo96.png",
|
||||
"sizes": "96x96",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "assets/generated/svg_mapcomplete_logo120.png",
|
||||
"src": "./assets/generated/svg_mapcomplete_logo120.png",
|
||||
"sizes": "120x120",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "assets/generated/svg_mapcomplete_logo128.png",
|
||||
"src": "./assets/generated/svg_mapcomplete_logo128.png",
|
||||
"sizes": "128x128",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "assets/generated/svg_mapcomplete_logo144.png",
|
||||
"src": "./assets/generated/svg_mapcomplete_logo144.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "assets/generated/svg_mapcomplete_logo152.png",
|
||||
"src": "./assets/generated/svg_mapcomplete_logo152.png",
|
||||
"sizes": "152x152",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "assets/generated/svg_mapcomplete_logo180.png",
|
||||
"src": "./assets/generated/svg_mapcomplete_logo180.png",
|
||||
"sizes": "180x180",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "assets/generated/svg_mapcomplete_logo192.png",
|
||||
"src": "./assets/generated/svg_mapcomplete_logo192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "assets/generated/svg_mapcomplete_logo384.png",
|
||||
"src": "./assets/generated/svg_mapcomplete_logo384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "assets/generated/svg_mapcomplete_logo512.png",
|
||||
"src": "./assets/generated/svg_mapcomplete_logo512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
},
|
||||
|
|
|
@ -7,7 +7,6 @@ import * as all_known_layouts from "../assets/generated/known_layers_and_themes.
|
|||
import {LayoutConfigJson} from "../Models/ThemeConfig/Json/LayoutConfigJson";
|
||||
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig";
|
||||
import xml2js from 'xml2js';
|
||||
import {exec} from "child_process";
|
||||
|
||||
const sharp = require('sharp');
|
||||
const template = readFileSync("theme.html", "utf8");
|
||||
|
@ -18,9 +17,7 @@ function enc(str: string): string {
|
|||
return encodeURIComponent(str.toLowerCase());
|
||||
}
|
||||
|
||||
const alreadyWritten = []
|
||||
|
||||
async function createIcon(iconPath: string, size: number) {
|
||||
async function createIcon(iconPath: string, size: number, alreadyWritten: string[]) {
|
||||
let name = iconPath.split(".").slice(0, -1).join(".");
|
||||
if (name.startsWith("./")) {
|
||||
name = name.substr(2)
|
||||
|
@ -53,7 +50,7 @@ async function createIcon(iconPath: string, size: number) {
|
|||
return newname;
|
||||
}
|
||||
|
||||
async function createManifest(layout: LayoutConfig) {
|
||||
async function createManifest(layout: LayoutConfig, alreadyWritten: string[]) {
|
||||
const name = layout.id;
|
||||
|
||||
Translation.forcedLanguage = "en"
|
||||
|
@ -64,6 +61,7 @@ async function createManifest(layout: LayoutConfig) {
|
|||
if (icon.endsWith(".svg") || icon.startsWith("<svg") || icon.startsWith("<?xml")) {
|
||||
// This is an svg. Lets create the needed pngs and do some checkes!
|
||||
|
||||
const whiteBackgroundPath = "./assets/generated/theme_"+layout.id+"_white_background.svg"
|
||||
{
|
||||
const svgResult = await xml2js.parseStringPromise(readFileSync(icon, "UTF8"))
|
||||
const svg = svgResult.svg
|
||||
|
@ -82,7 +80,11 @@ async function createManifest(layout: LayoutConfig) {
|
|||
}))//*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
const builder = new xml2js.Builder();
|
||||
const withRect = {rect: {"$":{width, height, style: "fill:#ffffff;"}}, ...svg}
|
||||
const xml = builder.buildObject({svg: withRect});
|
||||
writeFileSync(whiteBackgroundPath, xml)
|
||||
}
|
||||
|
||||
let path = layout.icon;
|
||||
|
@ -94,9 +96,10 @@ async function createManifest(layout: LayoutConfig) {
|
|||
|
||||
const sizes = [72, 96, 120, 128, 144, 152, 180, 192, 384, 512];
|
||||
for (const size of sizes) {
|
||||
const name = await createIcon(path, size);
|
||||
const name = await createIcon(path, size, alreadyWritten);
|
||||
createIcon(whiteBackgroundPath, size, alreadyWritten)
|
||||
icons.push({
|
||||
src: name,
|
||||
src: "./"+name,
|
||||
sizes: size + "x" + size,
|
||||
type: "image/png"
|
||||
})
|
||||
|
@ -133,7 +136,6 @@ async function createManifest(layout: LayoutConfig) {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
async function createLandingPage(layout: LayoutConfig, manifest) {
|
||||
|
||||
Locale.language.setData(layout.language[0]);
|
||||
|
@ -176,7 +178,7 @@ async function createLandingPage(layout: LayoutConfig, manifest) {
|
|||
if (icon.type !== "image/png") {
|
||||
continue;
|
||||
}
|
||||
apple_icons.push(`<link rel="apple-touch-icon" sizes="${icon.sizes}" href="${icon.src}">`)
|
||||
apple_icons.push(`<link rel="apple-touch-icon" sizes="${icon.sizes}" href="./assets/generated/generated_theme_${layout.id}_white_background${icon.sizes.substr(icon.sizes.indexOf("x")+ 1)}.png">`)
|
||||
}
|
||||
|
||||
let themeSpecific = [
|
||||
|
@ -211,65 +213,78 @@ async function createIndexFor(theme: LayoutConfig) {
|
|||
appendFileSync(filename, codeTemplate)
|
||||
}
|
||||
|
||||
const generatedDir = "./assets/generated";
|
||||
if (!existsSync(generatedDir)) {
|
||||
mkdirSync(generatedDir)
|
||||
function createDir(path){
|
||||
if (!existsSync(path)) {
|
||||
mkdirSync(path)
|
||||
}
|
||||
}
|
||||
|
||||
const blacklist = ["", "test", ".", "..", "manifest", "index", "land", "preferences", "account", "openstreetmap", "custom", "theme"]
|
||||
// @ts-ignore
|
||||
const all: LayoutConfigJson[] = all_known_layouts.themes;
|
||||
const args = process.argv
|
||||
const theme = args[2]
|
||||
if(theme !== undefined){
|
||||
console.warn("Only generating layout "+theme)
|
||||
}
|
||||
for (const i in all) {
|
||||
const layoutConfigJson: LayoutConfigJson = all[i]
|
||||
if(theme !== undefined && layoutConfigJson.id !== theme){
|
||||
continue
|
||||
async function main(): Promise<void>{
|
||||
|
||||
|
||||
const alreadyWritten = []
|
||||
createDir("./assets/generated")
|
||||
createDir("./assets/generated/layers")
|
||||
createDir("./assets/generated/themes")
|
||||
createDir("./assets/generated/white_background")
|
||||
|
||||
const blacklist = ["", "test", ".", "..", "manifest", "index", "land", "preferences", "account", "openstreetmap", "custom", "theme"]
|
||||
// @ts-ignore
|
||||
const all: LayoutConfigJson[] = all_known_layouts.themes;
|
||||
const args = process.argv
|
||||
const theme = args[2]
|
||||
if(theme !== undefined){
|
||||
console.warn("Only generating layout "+theme)
|
||||
}
|
||||
const layout = new LayoutConfig(layoutConfigJson, true, "generating layouts")
|
||||
const layoutName = layout.id
|
||||
if (blacklist.indexOf(layoutName.toLowerCase()) >= 0) {
|
||||
console.log(`Skipping a layout with name${layoutName}, it is on the blacklist`);
|
||||
continue;
|
||||
}
|
||||
const err = err => {
|
||||
if (err !== null) {
|
||||
console.log("Could not write manifest for ", layoutName, " because ", err)
|
||||
for (const i in all) {
|
||||
const layoutConfigJson: LayoutConfigJson = all[i]
|
||||
if(theme !== undefined && layoutConfigJson.id !== theme){
|
||||
continue
|
||||
}
|
||||
};
|
||||
createManifest(layout).then(manifObj => {
|
||||
const layout = new LayoutConfig(layoutConfigJson, true, "generating layouts")
|
||||
const layoutName = layout.id
|
||||
if (blacklist.indexOf(layoutName.toLowerCase()) >= 0) {
|
||||
console.log(`Skipping a layout with name${layoutName}, it is on the blacklist`);
|
||||
continue;
|
||||
}
|
||||
const err = err => {
|
||||
if (err !== null) {
|
||||
console.log("Could not write manifest for ", layoutName, " because ", err)
|
||||
}
|
||||
};
|
||||
await createManifest(layout, alreadyWritten).then(manifObj => {
|
||||
const manif = JSON.stringify(manifObj, undefined, 2);
|
||||
const manifestLocation = encodeURIComponent(layout.id.toLowerCase()) + ".webmanifest";
|
||||
writeFile(manifestLocation, manif, err);
|
||||
|
||||
// Create a landing page for the given theme
|
||||
createLandingPage(layout, manifObj).then(landing => {
|
||||
writeFile(enc(layout.id) + ".html", landing, err)
|
||||
});
|
||||
createIndexFor(layout)
|
||||
}).catch(e => console.log("Could not generate the manifest: ", e))
|
||||
|
||||
}
|
||||
|
||||
await createManifest(new LayoutConfig({
|
||||
icon: "assets/svg/mapcomplete_logo.svg",
|
||||
id: "index",
|
||||
layers: [],
|
||||
maintainer: "Pieter Vander Vennet",
|
||||
socialImage: "assets/SocialImage.png",
|
||||
startLat: 0,
|
||||
startLon: 0,
|
||||
startZoom: 0,
|
||||
title: {en: "MapComplete"},
|
||||
version: Constants.vNumber,
|
||||
description: {en: "A thematic map viewer and editor based on OpenStreetMap"}
|
||||
}), alreadyWritten).then(manifObj => {
|
||||
const manif = JSON.stringify(manifObj, undefined, 2);
|
||||
const manifestLocation = encodeURIComponent(layout.id.toLowerCase()) + ".webmanifest";
|
||||
writeFile(manifestLocation, manif, err);
|
||||
|
||||
// Create a landing page for the given theme
|
||||
createLandingPage(layout, manifObj).then(landing => {
|
||||
writeFile(enc(layout.id) + ".html", landing, err)
|
||||
});
|
||||
createIndexFor(layout)
|
||||
}).catch(e => console.log("Could not generate the manifest: ", e))
|
||||
writeFileSync("index.manifest", manif)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
createManifest(new LayoutConfig({
|
||||
icon: "assets/svg/mapcomplete_logo.svg",
|
||||
id: "index",
|
||||
layers: [],
|
||||
maintainer: "Pieter Vander Vennet",
|
||||
socialImage: "assets/SocialImage.png",
|
||||
startLat: 0,
|
||||
startLon: 0,
|
||||
startZoom: 0,
|
||||
title: {en: "MapComplete"},
|
||||
version: Constants.vNumber,
|
||||
description: {en: "A thematic map viewer and editor based on OpenStreetMap"}
|
||||
})).then(manifObj => {
|
||||
const manif = JSON.stringify(manifObj, undefined, 2);
|
||||
writeFileSync("index.manifest", manif)
|
||||
})
|
||||
|
||||
|
||||
console.log("All done!");
|
||||
main().then(() => {
|
||||
console.log("All done!")
|
||||
})
|
20
test.ts
20
test.ts
|
@ -1,7 +1,15 @@
|
|||
import {AllKnownLayouts} from "./Customizations/AllKnownLayouts";
|
||||
import List from "./UI/Base/List";
|
||||
import Link from "./UI/Base/Link";
|
||||
import {FixedUiElement} from "./UI/Base/FixedUiElement";
|
||||
import xml2js from 'xml2js';
|
||||
import {readFileSync} from "fs";
|
||||
|
||||
const allHidden = AllKnownLayouts.layoutsList.filter(l => l.hideFromOverview)
|
||||
new List(allHidden.map(th => new Link(new FixedUiElement(th.id), "theme.html?layout=" + th.id))).AttachTo("maindiv")
|
||||
const xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
|
||||
"<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"375px\" height=\"375px\" viewBox=\"0 0 375 375\" version=\"1.1\">\n" +
|
||||
" <g id=\"surface1\">\n" +
|
||||
" <path style=\" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;\" d=\"M 54.046875 233.558594 C 75.683594 233.558594 93.1875 215.566406 93.1875 193.296875 C 93.1875 171.148438 75.683594 153.148438 54.046875 153.148438 C 32.496094 153.148438 15 171.148438 15 193.296875 C 15 215.558594 32.496094 233.558594 54.046875 233.558594 Z M 273.269531 302.675781 C 275.09375 301.386719 277.5 301.777344 278.828125 303.554688 L 286.066406 313.84375 C 287.296875 315.628906 286.921875 318.195312 285.195312 319.589844 L 232.09375 359.242188 C 230.378906 360.53125 227.878906 360.128906 226.523438 358.359375 L 219.308594 348.066406 C 218.070312 346.28125 218.460938 343.726562 220.175781 342.335938 Z M 213.246094 251.550781 L 192.1875 213.578125 L 181.132812 221.878906 L 202.191406 260.054688 Z M 164.113281 162.847656 L 82.214844 15 L 66.546875 15.105469 L 152.960938 171.253906 Z M 241.222656 241.074219 C 245.851562 237.613281 256.441406 232.5 262.5 232.5 L 337.5 232.5 C 352.304688 232.5 360 247.394531 360 262.53125 C 360 277.753906 352.304688 285 337.5 285 L 270 285 L 188.730469 348.765625 C 160.171875 369.90625 142.859375 346.679688 142.859375 346.679688 L 79.238281 281.210938 C 68.566406 268.066406 70.875 243.046875 83.671875 231.96875 L 171.710938 167.488281 C 180.457031 159.988281 193.441406 161.167969 200.851562 170.0625 C 208.171875 179.0625 207.015625 192.515625 198.253906 200.03125 L 141.890625 242.460938 L 182.386719 283.589844 Z M 241.222656 241.074219 \"/>\n" +
|
||||
" </g>\n" +
|
||||
"</svg>"
|
||||
|
||||
xml2js.parseStringPromise(xml).then(svgResult => {
|
||||
const svg = svgResult.svg
|
||||
const builder = new xml2js.Builder();
|
||||
console.log(builder.buildObject(svg))
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue