Skip to content

Commit a619fb1

Browse files
authored
Merge pull request #18 from leviarista/rewrite
Rewrite
2 parents 470f7f5 + a406bfb commit a619fb1

25 files changed

+607
-376
lines changed

README.md

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@
44

55
## What is it?
66

7-
A simple but nice header image generator for your Github profile Readme. [Website Link](https://leviarista.github.io/github-profile-header-generator/).
7+
A simple but nice header image generator for your __Github profile Readme__.
8+
You can use it for your __repo banners__ too!
9+
10+
[Create my banner!](https://leviarista.github.io/github-profile-header-generator/)
811

912
## How to use it?
10-
1. Create a nice github header image.
13+
14+
1. Create a nice github header image.
1115
2. Create your GitHub profile README following [this guide](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/customizing-your-profile/managing-your-profile-readme).
1216
3. Upload your header to your profile repo.
13-
4. Add this line to your README:
14-
```` Markdown
15-
![Header](./[Your header image])
16-
````
17+
4. Add this line to your README:
18+
```Markdown
19+
![Header](./[Your header image])
20+
```
1721

1822
## Examples
1923

@@ -34,23 +38,27 @@ A simple but nice header image generator for your Github profile Readme. [Websit
3438
- Set background pattern image, its color, size and opacity.
3539
- Add decorations.
3640
- Upload your own decoration, octocat or profile pic.
37-
- Toogle Github dark and light mode.
41+
- Toogle between Github dark and light mode.
3842
- Download image as png.
39-
- Randomize between predefined themes.
43+
- Choose from predefined presets or get a random one.
4044

4145
## Tech used
4246

4347
- [Vite](https://vitejs.dev/)
44-
- [html2canvas](https://html2canvas.hertzen.com/)
48+
- [snapdom](https://zumerlab.github.io/snapdom/)
4549

4650
## Get started
4751

48-
- `npm run dev`- starts dev server
49-
- `npm run build` - builds for production
50-
- `npm run preview` - locally previews production build
52+
- `npm run dev`- starts dev server
53+
- `npm run build` - builds for production
54+
- `npm run preview` - locally previews production build
5155

5256
## Get started with Docker
5357

5458
```bash
5559
docker-compose up -d --build --force-recreate
5660
```
61+
62+
## Contributing
63+
64+
Check out our [Contributing guide](https://github.com/leviarista/github-profile-header-generator/blob/main/.github/CONTRIBUTING.md)

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
<div class="tab">
1717
<button class="tablinks" data-name="presets-section">
18-
Themes
18+
Presets
1919
<div
2020
style="position: absolute; background-color: rgba(255, 255, 255, 1); top: 5px; color: #585c9c; padding: 2px 5px; font-size: 10px; font-weight: bold; border-radius: 5px; transform: translateX(-40px)">
2121
NEW

js/banner.js

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
import { getPattern } from './data/patterns';
2+
import { getMainElements } from "./helpers/elements";
3+
import { isLocalDevelopment } from './helpers/helpers';
4+
5+
const {
6+
bannerImage,
7+
bannerTitle,
8+
bannerSubtitle,
9+
toolbox,
10+
toolboxDecorations,
11+
toolboxBackground,
12+
} = getMainElements();
13+
14+
function updateBanner(theme) {
15+
console.table(theme);
16+
console.log('•ᴗ• Updating Banner ...');
17+
applyTheme(theme);
18+
if (!theme.ignoreSave) saveTheme(theme);
19+
}
20+
21+
function applyTheme({
22+
padding,
23+
background,
24+
titleColor,
25+
subtitleColor,
26+
borderColor,
27+
borderSize,
28+
borderRadius,
29+
textAlign,
30+
decoration,
31+
decorationSize,
32+
pattern,
33+
patternColor,
34+
patternOpacity,
35+
patternSize,
36+
titleFont,
37+
subtitleFont,
38+
titleFontSize,
39+
subtitleFontSize,
40+
title,
41+
subtitle,
42+
decorationLocal = false
43+
}) {
44+
if (padding) {
45+
let paddingValue = `${padding}px`;
46+
bannerImage.style.padding = paddingValue;
47+
48+
document.querySelectorAll('.img-decoration-container img')
49+
.forEach(dec => {
50+
if (dec.style.left === 'auto')
51+
dec.style.right = paddingValue;
52+
else
53+
dec.style.left = paddingValue;
54+
});
55+
}
56+
if (background) bannerImage.style.backgroundColor = background;
57+
if (titleColor) bannerTitle.style.color = titleColor;
58+
if (subtitleColor) bannerSubtitle.style.color = subtitleColor;
59+
if (borderColor && borderSize && borderRadius) {
60+
bannerImage.style.border = `solid ${borderColor} ${borderSize}px`;
61+
bannerImage.style.borderRadius = `${borderRadius}px`;
62+
}
63+
if (borderColor) bannerImage.style.borderColor = borderColor;
64+
if (textAlign) {
65+
bannerImage.style.alignItems = textAlign;
66+
67+
// const paddingValue = document.querySelector('#paddings-input').value || 25;
68+
const paddingValue = padding || 25;
69+
const paddingPx = `${paddingValue}px`;
70+
const imageDecoration = document.querySelector('.img-decoration-container img');
71+
if (textAlign === 'flex-end') {
72+
document.querySelector('.img-decoration-container .img-decoration-2')?.remove();
73+
imageDecoration.style.left = paddingPx;
74+
imageDecoration.style.right = 'auto';
75+
} else if (textAlign === 'flex-start') {
76+
document.querySelector('.img-decoration-container .img-decoration-2')?.remove();
77+
imageDecoration.style.left = 'auto';
78+
imageDecoration.style.right = paddingPx;
79+
} else if (textAlign === 'center') {
80+
imageDecoration.style.left = 'auto';
81+
imageDecoration.style.right = paddingPx;
82+
if (!document.querySelector('.img-decoration-container .img-decoration-2')) {
83+
const clonedImageDecoration = imageDecoration.cloneNode(true);
84+
clonedImageDecoration.style.left = paddingPx;
85+
clonedImageDecoration.style.right = 'auto';
86+
clonedImageDecoration.className = 'img-decoration-2';
87+
const imageDecorationContainer = document.querySelector('.img-decoration-container');
88+
imageDecorationContainer.appendChild(clonedImageDecoration)
89+
}
90+
}
91+
}
92+
if (decoration) {
93+
const imageDecoration = bannerImage.querySelector('.img-decoration-container .img-decoration');
94+
const otherImageDecoration = bannerImage.querySelector('.img-decoration-container .img-decoration-2');
95+
96+
if (decoration === 'none') {
97+
imageDecoration.style.display = 'none';
98+
if (otherImageDecoration)
99+
otherImageDecoration.style.display = 'none';
100+
} else {
101+
let imageSrc = decorationLocal ? decoration : `images/decorations/${decoration}`;
102+
103+
imageDecoration.style.display = 'block';
104+
imageDecoration.src = imageSrc;
105+
if (otherImageDecoration) {
106+
otherImageDecoration.style.display = 'block';
107+
otherImageDecoration.src = imageSrc;
108+
}
109+
}
110+
}
111+
if (decorationSize) {
112+
const imageDecoration = bannerImage.querySelector('.img-decoration-container .img-decoration');
113+
const otherImageDecoration = bannerImage.querySelector('.img-decoration-container .img-decoration-2');
114+
115+
imageDecoration.style.width = `${decorationSize}px`;
116+
if (otherImageDecoration)
117+
otherImageDecoration.style.width = `${decorationSize}px`;
118+
}
119+
if (pattern || patternColor || patternOpacity || patternSize) {
120+
bannerImage.style.backgroundImage = getPattern(pattern, patternColor.replace('#', ''), patternOpacity);
121+
bannerImage.style.backgroundSize = `${patternSize}px`;
122+
}
123+
if (titleFont && subtitleFont) {
124+
// document.fonts.ready.then(() => {
125+
bannerTitle.style.fontFamily = `"${titleFont}"`;
126+
bannerSubtitle.style.fontFamily = `"${subtitleFont}"`;
127+
// });
128+
}
129+
if (titleFontSize || subtitleFontSize) {
130+
bannerTitle.style.fontSize = `${titleFontSize}px`;
131+
bannerSubtitle.style.fontSize = `${subtitleFontSize}px`;
132+
}
133+
if (title || subtitle) {
134+
bannerTitle.innerText = title || '';
135+
bannerSubtitle.innerText = subtitle || '';
136+
}
137+
}
138+
139+
function saveTheme(theme) {
140+
console.log('•ᴗ• Saving theme ...')
141+
// if (!theme.persistText) {
142+
// delete theme['title'];
143+
// delete theme['subtitle'];
144+
// }
145+
const oldTheme = JSON.parse(localStorage.getItem('theme'));
146+
let newTheme;
147+
if (oldTheme) {
148+
newTheme = { ...oldTheme, ...theme };
149+
} else {
150+
newTheme = theme;
151+
}
152+
localStorage.setItem('theme', JSON.stringify(newTheme));
153+
154+
if (isLocalDevelopment) {
155+
// console.log(theme);
156+
console.table(newTheme);
157+
}
158+
}
159+
160+
function updateUIOptions({
161+
padding = 25,
162+
background,
163+
titleColor,
164+
subtitleColor,
165+
borderColor,
166+
borderSize,
167+
borderRadius,
168+
textAlign,
169+
decoration,
170+
decorationSize,
171+
pattern,
172+
patternColor,
173+
patternSize,
174+
patternOpacity,
175+
titleFont,
176+
subtitleFont,
177+
titleFontSize = 40,
178+
subtitleFontSize = 20,
179+
title,
180+
subtitle
181+
}) {
182+
console.log('•ᴗ• Updating UI Options ...')
183+
184+
if (padding) {
185+
const paddingInput = document.querySelector('#paddings-input');
186+
paddingInput.value = padding;
187+
paddingInput.nextElementSibling.value = padding;
188+
}
189+
if (background) {
190+
const mainTabBgColorSelector = document.querySelector('.color-selectors-container input#main-bg-color-selector');
191+
const backgroundTabBgColorSelector = document.querySelector('.bg-color-selectors input#background-bg-color-selector');
192+
mainTabBgColorSelector.value = background;
193+
backgroundTabBgColorSelector.value = background;
194+
}
195+
if (titleColor) {
196+
const mainTabtitleColorSelector = toolbox.querySelector('.color-selectors-container input#title-color-selector');
197+
mainTabtitleColorSelector.value = titleColor;
198+
}
199+
if (subtitleColor) {
200+
const mainTabSubtitleColorSelector = toolbox.querySelector('.color-selectors-container input#subtitle-color-selector');
201+
mainTabSubtitleColorSelector.value = subtitleColor;
202+
}
203+
if (borderColor || borderSize || borderRadius) {
204+
const borderColorSelector = toolboxBackground.querySelector('.bg-color-selectors input#border-color-selector');
205+
const borderInput = toolboxBackground.querySelector('.border-inputs input#border-input');
206+
const borderRadiusInput = toolboxBackground.querySelector('.border-inputs input#border-radius-input');
207+
borderColorSelector.value = borderColor;
208+
borderInput.value = borderSize;
209+
borderInput.nextElementSibling.value = borderSize;
210+
borderRadiusInput.value = borderRadius;
211+
borderRadiusInput.nextElementSibling.value = borderRadius;
212+
}
213+
if (textAlign) { }
214+
if (decoration) { }
215+
if (decorationSize) {
216+
const decorationSizeInput = toolboxDecorations.querySelector('.decorations-size-inputs input#decoration-size-input');
217+
decorationSizeInput.value = decorationSize;
218+
decorationSizeInput.nextElementSibling.value = decorationSize;
219+
}
220+
if (pattern) { }
221+
if (patternSize) {
222+
const patternSizeInput = toolboxBackground.querySelector('.pattern-inputs input#pattern-size-input');
223+
patternSizeInput.value = patternSize;
224+
patternSizeInput.nextElementSibling.value = patternSize;
225+
226+
}
227+
if (patternColor || patternOpacity) {
228+
const patternOpacityInput = toolboxBackground.querySelector('.pattern-inputs input#pattern-opacity-input');
229+
const patternColorSelector = toolboxBackground.querySelector('.pattern-inputs input#pattern-color-selector');
230+
patternOpacityInput.value = patternOpacity
231+
patternOpacityInput.nextElementSibling.value = patternOpacity
232+
patternColorSelector.value = patternColor;
233+
}
234+
if (titleFont || subtitleFont) {
235+
toolbox.querySelector('.font-selectors-container #title-font-selector').value = titleFont ?? 'Red Hat Display';
236+
toolbox.querySelector('.font-selectors-container #subtitle-font-selector').value = subtitleFont ?? 'Kalam';
237+
}
238+
if (titleFontSize || subtitleFontSize) {
239+
const titleFontSizeInput = toolbox.querySelector('.font-size-inputs input#title-font-size-input');
240+
titleFontSizeInput.value = titleFontSize;
241+
titleFontSizeInput.nextElementSibling.value = titleFontSize;
242+
243+
const subtitleFontSizeInput = toolbox.querySelector('.font-size-inputs input#subtitle-font-size-input');
244+
subtitleFontSizeInput.value = subtitleFontSize;
245+
subtitleFontSizeInput.nextElementSibling.value = subtitleFontSize;
246+
}
247+
if (title || subtitle) {
248+
toolbox.querySelector('.text-inputs input#title-input').value = title;
249+
toolbox.querySelector('.text-inputs input#subtitle-input').value = subtitle;
250+
}
251+
}
252+
253+
function getSavedThemeProp(prop) {
254+
if (!prop) return '';
255+
const theme = JSON.parse(localStorage.getItem('theme'));
256+
return theme[prop];
257+
}
258+
259+
export {
260+
updateBanner,
261+
updateUIOptions,
262+
getSavedThemeProp
263+
};

0 commit comments

Comments
 (0)