Skip to content

Commit

Permalink
Merge pull request #30 from meetqy/29-分享图增加多种选择
Browse files Browse the repository at this point in the history
29 分享图增加多种选择
  • Loading branch information
meetqy authored Mar 8, 2024
2 parents a227932 + 1b80b8a commit 668e312
Show file tree
Hide file tree
Showing 11 changed files with 278 additions and 191 deletions.
1 change: 0 additions & 1 deletion public/content.json

This file was deleted.

Binary file added public/share-card-bg/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 0 additions & 34 deletions src/app/[lang]/poem/[id]/components/auto-hant.tsx

This file was deleted.

1 change: 0 additions & 1 deletion src/app/[lang]/poem/[id]/components/body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export const Body = (props: {
const { py, poem } = props;

const content = poem.content.split("\n");
console.log(content);
const contentPinYin = poem.contentPinYin?.split("\n") ?? [];

const isCenter = content.every((line) => line.length <= 16);
Expand Down
71 changes: 71 additions & 0 deletions src/app/[lang]/poem/[id]/components/share/draw/default.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { type Author, type Poem } from "@prisma/client";

interface Props {
data: Poem & { author: Author };
}

const DrawDefaultPreview = (props: Props) => {
const { data: poem } = props;

const content =
poem.content
.replaceAll("\n", "")
.match(/[^。|!|?|,|;]+[。|!|?|,|;]+/g)
?.slice(0, 2) || [];

return (
<div
id="draw-share-card"
style={{
height: 1440,
width: 1080,
position: "relative",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
backgroundColor: "#3d345a",
color: "#fff",
}}
>
{content.map((c, i) => {
return (
<div
key={i}
style={{
fontSize: 112,
display: "flex",
marginTop: i === 0 ? "-10%" : 0,
}}
>
{c}
</div>
);
})}

<div
style={{
marginTop: 132,
fontSize: 36,
color: "#d4ceea",
display: "flex",
}}
>
—— {poem.author.dynasty}·{poem.author.name}{poem.title}
</div>

<div
style={{
position: "absolute",
bottom: "7%",
fontSize: 32,
color: "#bbb",
}}
>
aspoem.com
</div>
</div>
);
};

export default DrawDefaultPreview;
57 changes: 57 additions & 0 deletions src/app/[lang]/poem/[id]/components/share/draw/wu-yan.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* eslint-disable @next/next/no-img-element */
import { type Author, type Poem } from "@prisma/client";
import { Verse } from "~/components/verse";
import { cn } from "~/utils";

interface Props {
data: Poem & { author: Author };
className?: string;
}

export default function DrawWuYanPreview({ data, className }: Props) {
const content = data.content
.replace(/\n/g, "")
.match(/[^(?|,|。|!)]+(?|,|。|!)?|(?|,|。|!)/g);

const py = data.contentPinYin?.split(". ");

return (
<div
className={cn("relative h-[732px] w-[540px]", className)}
id="draw-share-card"
>
<img
src="/share-card-bg/1.png"
alt="background"
className="z-1 absolute left-0 top-0 h-full w-full"
/>
<div className="absolute bottom-44 left-24 text-lg text-muted-foreground">
aspoem.com
</div>
<div className={"flex h-full w-full justify-center py-24"}>
<div>
<Verse
content={data.title}
variant="title"
py={data.titlePinYin || ""}
/>
<p className="mb-6 mt-3 text-center text-xl">
{data.author.dynasty} · {data.author.name}
</p>
<div className="space-y-4">
{content!.map((line, index) => {
return (
<Verse
key={index}
content={line}
variant="shi"
py={py![index] || ""}
/>
);
})}
</div>
</div>
</div>
</div>
);
}
81 changes: 81 additions & 0 deletions src/app/[lang]/poem/[id]/components/share/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"use client";

import { Button } from "~/components/ui/button";
import { createPortal } from "react-dom";
import domToImage from "dom-to-image";
import { useEffect, useState } from "react";

interface Props {
children: React.ReactNode;
title: React.ReactNode;
scale?: number;
}

const SaveShareButton = (props: Props) => {
const { scale = 1 } = props;
const [visable, setVisable] = useState(false);

useEffect(() => {
if (visable) {
const box = document.getElementById("draw-share-card")!;

void domToImage
.toBlob(box, {
width: box.clientWidth * scale,
height: box.clientHeight * scale,
style: {
innerWidth: box.clientWidth,
innerHeight: box.clientHeight,
transform: `scale(${scale})`,
transformOrigin: "top left",
},
})
.then((blob) => {
const div = document.createElement("div");
div.style.position = "fixed";
div.style.top = "0";
div.style.left = "0";
div.style.width = "100%";
div.style.height = "100%";
div.style.backgroundColor = "rgba(0, 0, 0, 0.25)";
div.style.zIndex = "9998";
div.style.display = "flex";
div.style.justifyContent = "center";
div.style.alignItems = "center";

div.onclick = () => {
document.body.removeChild(div);
};

const img = new Image();
img.src = URL.createObjectURL(blob);
img.style.height = "90%";
img.style.width = "auto";
// contain
img.style.objectFit = "contain";

div.appendChild(img);

document.body.appendChild(div);

setVisable(false);
});
}
}, [scale, visable]);

return (
<>
{visable && createPortal(props.children, document.body)}
<Button
variant={"outline"}
onClick={() => {
setVisable(true);
}}
>
{props.title}
</Button>
</>
);
};

export default SaveShareButton;
Loading

0 comments on commit 668e312

Please sign in to comment.