Skip to content

Commit

Permalink
facelift and small updates
Browse files Browse the repository at this point in the history
  • Loading branch information
alexewerlof committed Jan 6, 2024
1 parent e595ad3 commit 9727e32
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 106 deletions.
19 changes: 5 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

This is a tiny web app that puts a badged on your profile picture consistent with LinkedIn style but with your prefered text and colors.

👉[**See it live**](https://badge.alexewerlof.com/)
👉[**Use it live**](https://badge.alexewerlof.com/)

## Why?

Expand All @@ -18,22 +18,13 @@ Regardless of your opinion on the matter, the badge is a great place to spice up

## How does it work?

- Upload a profile picture. The image stays in your browser. This app doesn't have any backend.
- The image should be have a square ratio. We recommend `500px` width and `500px` height.
- Tweak the settings to your liking.
- Download the image
- Go to your LinkedIn profile and [update your image](https://www.linkedin.com/help/linkedin/answer/a541850/add-change-edit-or-delete-your-linkedin-profile-photo)

## No, I mean how does it really work?

This is a very simple application using vanilla JavaScript (no frameworks).

* The trick is to use a `<svg>` that overlays the image file in a hidden `<canvas>` element.
* Upon tweaking the attibutes a simple JavaScript function updates the relevant element in `<svg>`.
* The code is quick and dirty and I got a bit of help from [Copilot](https://github.com/features/copilot) too.
* The `<canvas>` is normally hidden (you can make it visible by commenting out the `display: none` in the CSS).
* Upon change of any property, the `<canvas>` is updated.
* The trick is to use a `<svg>` that overlays the image file that is loaded into an `<img>`.
* Upon tweaking the settings a simple JavaScript function updates the relevant element in the `<svg>`.
* This also redraws a `<canvas>` element. The `<canvas>` is normally hidden (you can make it visible by commenting out the `display: none` in the CSS).
* Upon download, the contents of the `<canvas>` is converted to `image/png`, put in a the `href` attribute of a `<link>` which is then programmatically clicked
* The code is quick and dirty and I got a bit of help from [Copilot](https://github.com/features/copilot) too.

# How can I support you?

Expand Down
32 changes: 22 additions & 10 deletions index.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,44 @@ a, a:visited {
}

input[type="text"] {
background-color: inherit;
color: inherit;
background-color: #FFF5E6;
color: #001426;
border-style: none;
border: 1px solid #FFBC52;
border: none;
padding: 0.5em;
font-family: inherit;
font-size: 1em;
}

input[type="color"] {
border: none;
}

button {
font-family: 'Alata', sans-serif;
background-color: #FFBC52;
padding: 1em;
border-style: none;
font-size: 1em;
}

#app {
box-shadow: 0 0 1em black;
margin: 2em;
border-radius: 0.8em;
}

header {
padding: 1em;
margin: 1em 1em 0 1em;
text-align: center;
background-color: #001B33;
border-top-left-radius: 0.8em;
border-top-right-radius: 0.8em;
margin-bottom: 1px;
}

main {
padding: 2em 1em;
margin: 0 1em;
padding: 2em;
border-bottom-left-radius: 0.8em;
border-bottom-right-radius: 0.8em;
background-color: #001426;
Expand All @@ -54,12 +65,13 @@ footer {
padding: 1em;
margin-top: 3em;
text-align: center;
text-shadow: 0 0 0.3em #FFBC52;
}

#image-preview {
position: relative;
height: 300px;
width: 300px;
height: 200px;
width: 200px;
margin: 1em 0;
}

Expand All @@ -73,6 +85,6 @@ footer {
#canvas-image {
/* for debugging purpose you can make it visible */
display: none;
height: 300px;
width: 300px;
height: 200px;
width: 200px;
}
179 changes: 97 additions & 82 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,110 +7,125 @@
<link rel="stylesheet" href="overlay.css">
<link rel="stylesheet" href="index.css">
<link rel="icon" type="image/png" href="example.png">

<meta name="description" content="Enhance your LinkedIn profile with our easy-to-use web app. Personalize your profile picture with custom badges. Simple, privacy-focused, and free. Try it now!">

<meta property="og:url" content="https://badge.alexewerlof.com" />
<meta property="og:type" content="website" />
<meta property="og:title" content="LinkedIn profile badge" />
<meta property="og:description" content="Create a custom badge for your LinkedIn profile for free" />
<meta property="og:image" content="https://badge.alexewerlof.com/example.png" />

<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@your-twitter-handle" />
<meta name="twitter:site" content="@alexewerlof" />
<meta name="twitter:title" content="LinkedIn profile badge" />
<meta name="twitter:description" content="Create a custom badge for your LinkedIn profile for free" />
<meta name="twitter:image" content="https://badge.alexewerlof.com/example.png" />
</head>
<body>
<header>
<h1>LinkedIn profile badge</h1>
</header>
<div id="app">
<header>
<h1>LinkedIn profile badge</h1>
<p>
Looking to stand out on LinkedIn with a custom badge? This privacy focused open source app does exactly that.
<a href="https://github.com/alexewerlof/badge" target="_blank">Read more...</a>
</p>
</header>
<main>
<label for="portrait-image-upload"><h2>1. Choose Portrait</h2></label>
<p>Choose a picture that is in square aspect ratio. We recommend 500x500px. The photo will not leave your browser. All processing is done on your machine.</p>
<input type="file" id="portrait-image-upload" accept="image/*">

<main>
<label for="portrait-image-upload"><h2>Portrait</h2></label>
<input type="file" id="portrait-image-upload" accept="image/*">
<div id="image-preview">
<img id="portrait-image" width="200" height="200" src="placeholder.jpg">
<svg
id="overlay-svg"
width="200"
height="200"
viewBox="0 0 132.29167 132.29169"
version="1.1"
id="svg5"
xml:space="preserve"
sodipodi:docname="linkedin profile.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs id="defs2">
<linearGradient id="overlay-circle-gradient">
<stop
style="stop-color:#446E2E;stop-opacity:1;"
offset="0"
id="left-bottom-stop" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="right-top-stop" />
</linearGradient>
<linearGradient
xlink:href="#overlay-circle-gradient"
id="linearGradient5958"
x1="34.373016"
y1="97.87925"
x2="58.266445"
y2="71.889893"
gradientUnits="userSpaceOnUse" />
</defs>
<g>
<path
id="overlay-text-bg"
d="M 0,0 V 132.29167 H 132.29167 V 0 Z M 66.145833,21.083468 A 45.06218,45.06218 0 0 1 111.2082,66.145833 45.06218,45.06218 0 0 1 66.145833,111.2082 45.06218,45.06218 0 0 1 21.083468,66.145833 45.06218,45.06218 0 0 1 66.145833,21.083468 Z" />
<path
id="text-circle-path"
d="M 76.595273,127.28886 A 62.02951,62.02951 0 0 0 127.28886,55.696389 62.02951,62.02951 0 0 0 55.696387,5.0028092 62.02951,62.02951 0 0 0 5.0028029,76.59527 62.02951,62.02951 0 0 0 76.595273,127.28886 Z" />
<text
xml:space="preserve"
id="overlay-text">
<textPath
xlink:href="#text-circle-path"
startOffset="100%"
style="fill: #EDF9EB"
id="overlay-text-path">#CREATING</textPath>
</text>
</g>
</svg>
</div>

<label for="badge-text-input"><h2>Text</h2></label>
<input type="text" id="badge-text-input" maxlength="20" value="#CREATING">
<label for="badge-text-input"><h2>2. Configure</h2></label>
<input type="text" id="badge-text-input" maxlength="20" value="#CREATING">

<h2>Colors</h2>
<p>
<input type="color" id="badge-bg-color-input" value="#446E2E">
<label for="badge-bg-color-input">Background</label>
</p>
<p>
<input type="color" id="badge-text-color-input" value="#EDF9EB">
<label for="badge-text-color-input">Text</label>
</p>

<h2>3. Download</h2>
<button id="download-button">Save file</button>
<h2>4. Update your profile</h2>
<p>
<a href="https://www.linkedin.com/help/linkedin/answer/a541850/add-change-edit-or-delete-your-linkedin-profile-photo" target="_blank">How to change your LinkedIn profile</a>
</p>
</main>
</div>

<input type="color" name="" id="badge-bg-color-input" value="#446E2E">
<label for="badge-bg-color-input">Background</label>
<br>
<input type="color" name="" id="badge-text-color-input" value="#EDF9EB">
<label for="badge-text-color-input">Text</label>
<div>
<canvas id="canvas-image" height="500" width="500"></canvas>
</div>

<div id="image-preview">
<img id="portrait-image" width="300" height="300" src="placeholder.jpg">
<svg
id="overlay-svg"
width="300"
height="300"
viewBox="0 0 132.29167 132.29169"
version="1.1"
id="svg5"
xml:space="preserve"
sodipodi:docname="linkedin profile.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs id="defs2">
<linearGradient id="overlay-circle-gradient">
<stop
style="stop-color:#446E2E;stop-opacity:1;"
offset="0"
id="left-bottom-stop" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="right-top-stop" />
</linearGradient>
<linearGradient
xlink:href="#overlay-circle-gradient"
id="linearGradient5958"
x1="34.373016"
y1="97.87925"
x2="58.266445"
y2="71.889893"
gradientUnits="userSpaceOnUse" />
</defs>
<g>
<path
id="overlay-text-bg"
d="M 0,0 V 132.29167 H 132.29167 V 0 Z M 66.145833,21.083468 A 45.06218,45.06218 0 0 1 111.2082,66.145833 45.06218,45.06218 0 0 1 66.145833,111.2082 45.06218,45.06218 0 0 1 21.083468,66.145833 45.06218,45.06218 0 0 1 66.145833,21.083468 Z" />
<path
id="text-circle-path"
d="M 76.595273,127.28886 A 62.02951,62.02951 0 0 0 127.28886,55.696389 62.02951,62.02951 0 0 0 55.696387,5.0028092 62.02951,62.02951 0 0 0 5.0028029,76.59527 62.02951,62.02951 0 0 0 76.595273,127.28886 Z" />
<text
xml:space="preserve"
id="overlay-text">
<textPath
xlink:href="#text-circle-path"
startOffset="100%"
style="fill: #EDF9EB"
id="overlay-text-path">#CREATING</textPath>
</text>
</g>
</svg>
</div>
<button id="download-button">Download</button>
<div>
<canvas id="canvas-image" height="500" width="500"></canvas>
</div>
<footer>
<p>
<a href="https://www.linkedin.com/help/linkedin/answer/a541850/add-change-edit-or-delete-your-linkedin-profile-photo" target="_blank">How to change your LinkedIn profile</a>
Support my work by subscribing to my newsletter about technical leadership, software reliability, and growth.
</p>
</main>
<footer>
<p>
🇸🇪 Made in Sweden by <a href="https://alexewerlof.com/" target="_blank">Alex Ewerlöf</a>
|
<a href="https://github.com/alexewerlof/badge" target="_blank">README</a>
This app doesn't track you or upload your image anywhere.
</p>
<p>
We don't track you or upload your image anywhere. Everything is done in your browser.
Enjoy and spread it if you find it useful.
🇸🇪 Made in Sweden by <a href="https://alexewerlof.com/" target="_blank">Alex Ewerlöf</a>
</p>
</footer>
<script src="index.js"></script>
Expand Down

0 comments on commit 9727e32

Please sign in to comment.