diff --git a/lib/badge-data.js b/lib/badge-data.js index 7fd8ef5fe2e5aa97535b7d09fb00462106d1c045..8c72bbb393244d4a6866a80ebb6c2105e8aa7a73 100644 --- a/lib/badge-data.js +++ b/lib/badge-data.js @@ -105,6 +105,7 @@ function makeBadgeData(defaultLabel, overrides) { colorscheme: 'lightgrey', template: overrides.style, logo: makeLogo(undefined, overrides), + logoPosition: +overrides.logoPosition, logoWidth: +overrides.logoWidth, links: toArray(overrides.link), colorA: makeColor(overrides.colorA), diff --git a/lib/badge-data.spec.js b/lib/badge-data.spec.js index 518ed7e7c501eb75abdff5a94deb54d70e68177b..6cdf3fb9c7e7449bccb671417f42d8f57fe44c9e 100644 --- a/lib/badge-data.spec.js +++ b/lib/badge-data.spec.js @@ -67,6 +67,7 @@ describe('Badge data helpers', function() { label: 'no, my badge', style: 'flat-square', logo: 'image/svg+xml;base64,PHN2ZyB4bWxu', + logoPosition: 10, logoWidth: '25', link: 'https://example.com/', colorA: 'blue', @@ -76,6 +77,7 @@ describe('Badge data helpers', function() { colorscheme: 'lightgrey', template: 'flat-square', logo: 'data:image/svg+xml;base64,PHN2ZyB4bWxu', + logoPosition: 10, logoWidth: 25, links: ['https://example.com/'], colorA: 'blue', diff --git a/lib/export-supported-features-cli.js b/lib/export-supported-features-cli.js index bed3cc0efdcd8c180838504cc110cd3e84e18d39..7757412239738955ff7e0ca0de5fad503ef135b0 100644 --- a/lib/export-supported-features-cli.js +++ b/lib/export-supported-features-cli.js @@ -12,6 +12,8 @@ const supportedFeatures = { 'flat', 'flat-square', 'for-the-badge', + 'popout', + 'popout-square', 'social', ], }; diff --git a/lib/make-badge.js b/lib/make-badge.js index a0b625d83b2e3f4af8cc312bb4ee1fac4655c8f4..dfe43523abe4612c4f12bd4680b795d5348cea2c 100644 --- a/lib/make-badge.js +++ b/lib/make-badge.js @@ -109,6 +109,7 @@ function makeBadge (measurer, { colorA, colorB, logo, + logoPosition, logoWidth, links = ['', ''], }) { @@ -122,6 +123,14 @@ function makeBadge (measurer, { if (!(`${template}-${format}` in templates)) { template = format === 'svg' ? 'flat' : 'default'; } + if (template.startsWith('popout')) { + if (logo){ + logoPosition = (logoPosition <= 10 && logoPosition >= -10) ? logoPosition : 0; + logoWidth = +logoWidth || 32; + } else { + template = template.replace('popout', 'flat'); + } + } if (template === 'social') { text[0] = capitalize(text[0]); } else if (template === 'for-the-badge') { @@ -164,6 +173,7 @@ function makeBadge (measurer, { ], links: links.map(escapeXml), logo, + logoPosition, logoWidth, logoPadding, colorA, diff --git a/lib/request-handler.js b/lib/request-handler.js index d4bc0964e04158378282db6f5be6fa73acaceb66..998d80e5694b241de9b01302ca56993c9273a3dc 100644 --- a/lib/request-handler.js +++ b/lib/request-handler.js @@ -40,6 +40,7 @@ const globalQueryParams = new Set([ 'style', 'link', 'logo', + 'logoPosition', 'logoWidth', 'link', 'colorA', diff --git a/templates/popout-square-template.svg b/templates/popout-square-template.svg new file mode 100644 index 0000000000000000000000000000000000000000..c6767fdb81f0decfa14ee640fe164b86e1b3ffed --- /dev/null +++ b/templates/popout-square-template.svg @@ -0,0 +1,23 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{{=it.widths[0]+it.widths[1]}}" height="40"> + <g shape-rendering="crispEdges"> + <rect width="{{=it.widths[0]}}" y="{{=10-it.logoPosition}}" height="20" fill="{{=it.escapeXml(it.colorA||"#555")}}"/> + <rect x="{{=it.widths[0]}}" y="{{=10-it.logoPosition}}" width="{{=it.widths[1]}}" height="20" fill="{{=it.escapeXml(it.colorB||"#4c1")}}"/> + </g> + <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> + {{?it.logo}} + <image x="5" y="3" width="{{=it.logoWidth}}" height="32" xlink:href="{{=it.logo}}"/> + {{?}} + <text x="{{=(((it.widths[0]+it.logoWidth+it.logoPadding)/2)+1)*10}}" y="{{=(24-it.logoPosition)*10}}" transform="scale(0.1)" textLength="{{=(it.widths[0]-(10+it.logoWidth+it.logoPadding))*10}}" lengthAdjust="spacing">{{=it.escapedText[0]}}</text> + <text x="{{=(it.widths[0]+it.widths[1]/2-1)*10}}" y="{{=(24-it.logoPosition)*10}}" transform="scale(0.1)" textLength="{{=(it.widths[1]-10)*10}}" lengthAdjust="spacing">{{=it.escapedText[1]}}</text> + </g> + {{?(it.links[0] && it.links[0].length)}} + <a xlink:href="{{=it.links[0]}}"> + <rect width="{{=it.widths[0]}}" height="40" fill="rgba(0,0,0,0)"/> + </a> + {{?}} + {{?(it.links[0] && it.links[0].length || it.links[1] && it.links[1].length)}} + <a xlink:href="{{=it.links[1] || it.links[0]}}"> + <rect x="{{=it.widths[0]}}" width="{{=it.widths[1]}}" height="40" fill="rgba(0,0,0,0)"/> + </a> + {{?}} +</svg> diff --git a/templates/popout-template.svg b/templates/popout-template.svg new file mode 100644 index 0000000000000000000000000000000000000000..98afc5896022ab9eccb2a4280f96a8aea1377023 --- /dev/null +++ b/templates/popout-template.svg @@ -0,0 +1,37 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{{=it.widths[0]+it.widths[1]}}" height="40"> + <linearGradient id="smooth" x2="0" y2="100%"> + <stop offset="0" stop-color="#bbb" stop-opacity=".1"/> + <stop offset="1" stop-opacity=".1"/> + </linearGradient> + + <clipPath id="round"> + <rect width="{{=it.widths[0]+it.widths[1]}}" y="{{=10-it.logoPosition}}" height="20" rx="3" fill="#fff"/> + </clipPath> + + <g clip-path="url(#round)"> + <rect width="{{=it.widths[0]}}" y="{{=10-it.logoPosition}}" height="20" fill="{{=it.escapeXml(it.colorA||"#555")}}"/> + <rect x="{{=it.widths[0]}}" y="{{=10-it.logoPosition}}" width="{{=it.widths[1]}}" height="20" fill="{{=it.escapeXml(it.colorB||"#4c1")}}"/> + <rect width="{{=it.widths[0]+it.widths[1]}}" y="{{=10-it.logoPosition}}" height="20" fill="url(#smooth)"/> + </g> + + <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> + {{?it.logo}} + <image x="5" y="3" width="{{=it.logoWidth}}" height="32" xlink:href="{{=it.logo}}"/> + {{?}} + <text x="{{=(((it.widths[0]+it.logoWidth+it.logoPadding)/2)+1)*10}}" y="{{=(25-it.logoPosition)*10}}" fill="#010101" fill-opacity=".3" transform="scale(0.1)" textLength="{{=(it.widths[0]-(10+it.logoWidth+it.logoPadding))*10}}" lengthAdjust="spacing">{{=it.escapedText[0]}}</text> + <text x="{{=(((it.widths[0]+it.logoWidth+it.logoPadding)/2)+1)*10}}" y="{{=(24-it.logoPosition)*10}}" transform="scale(0.1)" textLength="{{=(it.widths[0]-(10+it.logoWidth+it.logoPadding))*10}}" lengthAdjust="spacing">{{=it.escapedText[0]}}</text> + <text x="{{=(it.widths[0]+it.widths[1]/2-1)*10}}" y="{{=(25-it.logoPosition)*10}}" fill="#010101" fill-opacity=".3" transform="scale(0.1)" textLength="{{=(it.widths[1]-10)*10}}" lengthAdjust="spacing">{{=it.escapedText[1]}}</text> + <text x="{{=(it.widths[0]+it.widths[1]/2-1)*10}}" y="{{=(24-it.logoPosition)*10}}" transform="scale(0.1)" textLength="{{=(it.widths[1]-10)*10}}" lengthAdjust="spacing">{{=it.escapedText[1]}}</text> + </g> + + {{?(it.links[0] && it.links[0].length)}} + <a xlink:href="{{=it.links[0]}}"> + <rect width="{{=it.widths[0]}}" height="40" fill="rgba(0,0,0,0)"/> + </a> + {{?}} + {{?(it.links[0] && it.links[0].length || it.links[1] && it.links[1].length)}} + <a xlink:href="{{=it.links[1] || it.links[0]}}"> + <rect x="{{=it.widths[0]}}" width="{{=it.widths[1]}}" height="40" fill="rgba(0,0,0,0)"/> + </a> + {{?}} +</svg>