Skip to content

Commit

Permalink
Merge pull request #26 from ful1e5/dev
Browse files Browse the repository at this point in the history
Perf: Faster Cursor Bitmapping & Other fixes
  • Loading branch information
ful1e5 authored Feb 8, 2024
2 parents 93dcd63 + 73b58f6 commit ce77ba3
Show file tree
Hide file tree
Showing 8 changed files with 465 additions and 783 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [unreleased]

### Sponsors

- Shoutout @AKP2401 As one-time 5$ sponsor
- Shoutout @krishhandro As one-time 3$ sponsor

### What's New?

- Render Cursor bitmaps(SVG->PNG) on client side without `sharp` (related to #22)

### Changes

- Reusable `Marquee` Component

### Fixes

- Fixes breakage on `PRO` account link downloads
- Fixed width and font size of `ToolTip` component in mobile devices

## [v1.0.1] - 12 January 2024

Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"next-auth": "^4.24.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sharp": "^0.32.6",
"swr": "^2.2.4",
"tinycolor2": "^1.6.0",
"uuid": "^9.0.1"
Expand Down
12 changes: 6 additions & 6 deletions src/app/(home)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -355,17 +355,17 @@ export default function HomePage() {
</Link>

<Link
href='https://github.com/lovell/sharp'
href='https://github.com/Exponential-Workload/freebata'
target='_blank'
className='library-card bg-white/[.1]'>
<h5 className='library-card-heading'>Sharp</h5>
<h5 className='library-card-heading'>Freebata</h5>
<p className='library-card-text'>
High performance Node.js image processer.
Microscopic Free&amp;Open-Source Bibata Generation Tool
</p>

<div className='library-card-lang w-28 bg-yellow-400/[.1]'>
<span className='circle bg-yellow-300' />
<p className='text-xs text-yellow-200'>JavaScript</p>
<div className='library-card-lang w-28 bg-blue-400/[.1]'>
<span className='circle bg-blue-300' />
<p className='text-xs text-blue-200'>TypeScript</p>
</div>
</Link>
</div>
Expand Down
77 changes: 0 additions & 77 deletions src/app/api/svg/[id]/route.ts

This file was deleted.

79 changes: 49 additions & 30 deletions src/components/Cursors/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { DELAYS, WATCH_COLORS, COLORS_MASK as mask } from '@root/configs';

import { fetchX } from '@utils/fetchX';

import { Color, Image, SVG } from 'bibata/app';
import { Color, Image as CursorImage, SVG } from 'bibata/app';
import { ProcessingSVG } from '@components/svgs';

export const BrokenImage: React.FC = () => {
Expand All @@ -26,12 +26,14 @@ type Props = {
color: Color;

// eslint-disable-next-line no-unused-vars
onLoad?: (image: Image, loading: boolean) => void;
onLoad?: (image: CursorImage, loading: boolean) => void;
};

export const CursorCard: React.FC<Props> = (props) => {
const { base, outline, watch } = props.color;
const { id, name, isAnimated, urls } = props.svg;
const { name, isAnimated, urls } = props.svg;

let antiAlias = false;

const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
Expand All @@ -50,12 +52,39 @@ export const CursorCard: React.FC<Props> = (props) => {
[mask.watch?.c4!]: watch?.c4 || WATCH_COLORS.c4
};

const svgToPng = (
svgData: string,
widthOverwrite?: number,
heightOverwrite = widthOverwrite
) => {
if (typeof Image === 'undefined') return '';
return new Promise<string>((rs) => {
const imgObj = new Image();

imgObj.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = widthOverwrite ?? imgObj.naturalWidth;
canvas.height = heightOverwrite ?? imgObj.naturalHeight;
const context = canvas.getContext('2d')!;
context.imageSmoothingEnabled = antiAlias;
context.imageSmoothingQuality = antiAlias ? 'high' : 'low';
context.drawImage(imgObj, 0, 0, canvas.width, canvas.height);
const pngDataUrl = canvas.toDataURL('image/png');
rs(pngDataUrl);
imgObj.remove();
};
if (widthOverwrite) imgObj.width = widthOverwrite;
if (heightOverwrite) imgObj.height = heightOverwrite;
imgObj.src = `data:image/svg+xml;base64,${btoa(svgData)}`;
});
};

const fetchSvg = async (signal: AbortSignal) => {
setFrames([]);
setLoading(true);

try {
const fms: string[] = [];
const svgs: string[] = [];
const step = Math.round(urls.length / DELAYS[delayX].frames);

for (let i = 0; i < urls.length; isAnimated ? (i += step) : i++) {
Expand All @@ -68,36 +97,26 @@ export const CursorCard: React.FC<Props> = (props) => {
if (!res || signal.aborted) return;

const b64 = await res.text();
fms.push(b64);
svgs.push(b64);
}

let res = await fetchX(`/api/svg/${id}`, {
init: {
method: 'POST',
body: JSON.stringify({ colors, frames: fms }),
next: { revalidate: 360 }
},
revalidate: 1200,
group: 'bibata.svg-build-cache'
});

if (!res || signal.aborted) return;

const json = await res.json();

if (res.status !== 200) {
setError(true);
throw new Error(json['error']);
} else if (json.data.length === 0) {
setError(true);
throw new Error(
`Empty cursor frames while signal is ${signal.aborted}`
);
} else {
setFrames([...json.data]);
setLoading(false);
const pngs: string[] = [];

for (let i = 0; i < svgs.length; i++) {
let svgData = svgs[i];
if (colors && typeof colors === 'object') {
Object.entries(colors).forEach(([match, replace]) => {
svgData = svgData!.replace(new RegExp(match, 'ig'), replace);
});
}

pngs.push(await svgToPng(svgData));
}

setFrames([...pngs]);
setLoading(false);
} catch (e) {
setError(true);
if (process.env.NODE_ENV === 'development') {
console.error(e);
} else {
Expand Down
12 changes: 12 additions & 0 deletions src/components/HeroesElements/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ export const HeroesElements: React.FC<Props> = (_props) => {
role='One-time Sponsor'
classes='p-10'
/>
<Card
imgUrl='https://avatars.githubusercontent.com/u/49100352?v=4'
link='https://github.com/AKP2401'
name='Aadharsh K Praveen'
role='One-time Sponsor'
/>
<Card
imgUrl='https://avatars.githubusercontent.com/u/9942725?v=4'
link='https://github.com/krishhandro'
name='krishh'
role='One-time Sponsor'
/>

<Sponsors />

Expand Down
4 changes: 2 additions & 2 deletions src/components/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ const Tooltip: React.FC<Props> = (props) => {
onMouseLeave={() => setShowTooltip(false)}
onClick={() => setShowTooltip(!showTooltip)}>
{showTooltip && (
<div className='absolute w-96 top-1/2 left-1/2 transform -translate-x-1/2 translate-y-4 shadow'>
<div className='absolute w-56 sm:w-96 top-1/2 left-1/2 transform -translate-x-1/2 translate-y-4 shadow'>
<div className='flex max-w-xs flex-col items-center shadow-lg'>
<div className='clip-bottom h-2 w-4 bg-black' />
<div className='rounded-xl bg-black p-2 text-[14px] sm:text-md text-white'>
<div className='rounded-xl bg-black p-2 text-[9px] sm:text-md text-white'>
{props.tooltip}
</div>
</div>
Expand Down
Loading

0 comments on commit ce77ba3

Please sign in to comment.