diff --git a/api/top-langs.js b/api/top-langs.js
index d183d3b455ca0..19cccb894e33a 100644
--- a/api/top-langs.js
+++ b/api/top-langs.js
@@ -29,6 +29,7 @@ export default async (req, res) => {
locale,
border_radius,
border_color,
+ disable_animations,
} = req.query;
res.setHeader("Content-Type", "image/svg+xml");
@@ -75,6 +76,7 @@ export default async (req, res) => {
border_radius,
border_color,
locale: locale ? locale.toLowerCase() : null,
+ disable_animations: parseBoolean(disable_animations),
}),
);
} catch (err) {
diff --git a/readme.md b/readme.md
index bfe042fcc2032..716bda22758c6 100644
--- a/readme.md
+++ b/readme.md
@@ -304,6 +304,7 @@ You can provide multiple comma-separated values in the bg_color option to render
- `langs_count` - Show more languages on the card, between 1-10 _(number)_. Default `5`.
- `exclude_repo` - Exclude specified repositories _(Comma-separated values)_. Default: `[] (blank array)`.
- `custom_title` - Sets a custom title for the card _(string)_. Default `Most Used Languages`.
+- `disable_animations` - Disables all animations in the card _(boolean)_. Default: `false`.
> **Warning**
> Language names should be URI-escaped, as specified in [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding)
diff --git a/scripts/push-theme-readme.sh b/scripts/push-theme-readme.sh
index 4a035db3041a0..1ab5de474ea5a 100755
--- a/scripts/push-theme-readme.sh
+++ b/scripts/push-theme-readme.sh
@@ -9,6 +9,6 @@ git config --global user.name "GitHub Readme Stats Bot"
git branch -d $BRANCH_NAME || true
git checkout -b $BRANCH_NAME
git add --all
-git commit --message "docs(theme): Auto update theme readme" || exit 0
+git commit --no-verify --message "docs(theme): Auto update theme readme"
git remote add origin-$BRANCH_NAME https://${PERSONAL_TOKEN}@github.com/${GH_REPO}.git
git push --force --quiet --set-upstream origin-$BRANCH_NAME $BRANCH_NAME
diff --git a/src/cards/top-languages-card.js b/src/cards/top-languages-card.js
index 602d1b811b5df..9396ff8e73d5e 100644
--- a/src/cards/top-languages-card.js
+++ b/src/cards/top-languages-card.js
@@ -39,46 +39,53 @@ const getLongestLang = (arr) =>
* Creates a node to display usage of a programming language in percentage
* using text and a horizontal progress bar.
*
- * @param {object[]} props Function properties.
+ * @param {object} props Function properties.
* @param {number} props.width The card width
* @param {string} props.name Name of the programming language.
* @param {string} props.color Color of the programming language.
* @param {string} props.progress Usage of the programming language in percentage.
+ * @param {number} props.index Index of the programming language.
* @returns {string} Programming language SVG node.
*/
-const createProgressTextNode = ({ width, color, name, progress }) => {
+const createProgressTextNode = ({ width, color, name, progress, index }) => {
+ const staggerDelay = (index + 3) * 150;
const paddingRight = 95;
const progressTextX = width - paddingRight + 10;
const progressWidth = width - paddingRight;
return `
- ${name}
- ${progress}%
- ${createProgressNode({
- x: 0,
- y: 25,
- color,
- width: progressWidth,
- progress,
- progressBarBackgroundColor: "#ddd",
- })}
+
+ ${name}
+ ${progress}%
+ ${createProgressNode({
+ x: 0,
+ y: 25,
+ color,
+ width: progressWidth,
+ progress,
+ progressBarBackgroundColor: "#ddd",
+ delay: staggerDelay + 300,
+ })}
+
`;
};
/**
* Creates a text only node to display usage of a programming language in percentage.
*
- * @param {object[]} props Function properties.
+ * @param {object} props Function properties.
* @param {Lang} props.lang Programming language object.
* @param {number} props.totalSize Total size of all languages.
+ * @param {number} props.index Index of the programming language.
* @returns {string} Compact layout programming language SVG node.
*/
-const createCompactLangNode = ({ lang, totalSize }) => {
+const createCompactLangNode = ({ lang, totalSize, index }) => {
const percentage = ((lang.size / totalSize) * 100).toFixed(2);
+ const staggerDelay = (index + 3) * 150;
const color = lang.color || "#858585";
return `
-
+
${lang.name} ${percentage}%
@@ -104,7 +111,6 @@ const createLanguageTextNode = ({ langs, totalSize }) => {
createCompactLangNode({
lang,
totalSize,
- // @ts-ignore
index,
}),
);
@@ -134,12 +140,13 @@ const createLanguageTextNode = ({ langs, totalSize }) => {
*/
const renderNormalLayout = (langs, width, totalLanguageSize) => {
return flexLayout({
- items: langs.map((lang) => {
+ items: langs.map((lang, index) => {
return createProgressTextNode({
- width: width,
+ width,
name: lang.name,
color: lang.color || DEFAULT_LANG_COLOR,
progress: ((lang.size / totalLanguageSize) * 100).toFixed(2),
+ index,
});
}),
gap: 40,
@@ -187,7 +194,7 @@ const renderCompactLayout = (langs, width, totalLanguageSize) => {
return `
-
+
${compactProgressBar}
@@ -276,6 +283,7 @@ const renderTopLanguages = (topLangs, options = {}) => {
langs_count = DEFAULT_LANGS_COUNT,
border_radius,
border_color,
+ disable_animations,
} = options;
const i18n = new I18n({
@@ -324,11 +332,43 @@ const renderTopLanguages = (topLangs, options = {}) => {
colors,
});
- card.disableAnimations();
+ if (disable_animations) card.disableAnimations();
+
card.setHideBorder(hide_border);
card.setHideTitle(hide_title);
card.setCSS(
- `.lang-name { font: 400 11px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${colors.textColor} }`,
+ `
+ @keyframes slideInAnimation {
+ from {
+ width: 0;
+ }
+ to {
+ width: calc(100%-100px);
+ }
+ }
+ @keyframes growWidthAnimation {
+ from {
+ width: 0;
+ }
+ to {
+ width: 100%;
+ }
+ }
+ .lang-name {
+ font: 400 11px "Segoe UI", Ubuntu, Sans-Serif;
+ fill: ${colors.textColor};
+ }
+ .stagger {
+ opacity: 0;
+ animation: fadeInAnimation 0.3s ease-in-out forwards;
+ }
+ #rect-mask rect{
+ animation: slideInAnimation 1s ease-in-out forwards;
+ }
+ .lang-progress{
+ animation: growWidthAnimation 0.6s ease-in-out forwards;
+ }
+ `,
);
return card.render(`
diff --git a/src/cards/types.d.ts b/src/cards/types.d.ts
index 502314c41fa92..c5945d48be71e 100644
--- a/src/cards/types.d.ts
+++ b/src/cards/types.d.ts
@@ -37,6 +37,7 @@ export type TopLangOptions = CommonOptions & {
layout: "compact" | "normal";
custom_title: string;
langs_count: number;
+ disable_animations: boolean;
};
type WakaTimeOptions = CommonOptions & {
diff --git a/src/common/createProgressNode.js b/src/common/createProgressNode.js
index c36818b193b2f..2825583c7406a 100644
--- a/src/common/createProgressNode.js
+++ b/src/common/createProgressNode.js
@@ -10,6 +10,7 @@ import { clampValue } from "./utils.js";
* @param {string} createProgressNodeParams.color Progress color.
* @param {string} createProgressNodeParams.progress Progress value.
* @param {string} createProgressNodeParams.progressBarBackgroundColor Progress bar bg color.
+ * @param {number} createProgressNodeParams.delay Delay before animation starts.
* @returns {string} Progress node.
*/
const createProgressNode = ({
@@ -19,20 +20,22 @@ const createProgressNode = ({
color,
progress,
progressBarBackgroundColor,
+ delay,
}) => {
const progressPercentage = clampValue(progress, 2, 100);
return `
`;
};
diff --git a/tests/renderStatsCard.test.js b/tests/renderStatsCard.test.js
index e39e45b7870e3..5afb1f0218e5d 100644
--- a/tests/renderStatsCard.test.js
+++ b/tests/renderStatsCard.test.js
@@ -329,7 +329,7 @@ describe("Test renderStatsCard", () => {
document.querySelector(
'g[transform="translate(0, 25)"]>.stagger>.stat.bold',
).textContent,
- ).toMatchInlineSnapshot(`"累计提交数(commit) (2022):"`);
+ ).toMatchInlineSnapshot(`"累计提交数(commit) (2023):"`);
expect(
document.querySelector(
'g[transform="translate(0, 50)"]>.stagger>.stat.bold',