Skip to content

Commit

Permalink
envelope
Browse files Browse the repository at this point in the history
  • Loading branch information
NaridaL committed Jul 4, 2023
1 parent 61ce8b9 commit c6c3781
Show file tree
Hide file tree
Showing 16 changed files with 543 additions and 233 deletions.
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const pages = [
{ title: "Delta3D", module: "delta3d", hide: true },
{ title: "Paper Prism Box", module: "paperBox1" },
{ title: "Circle Paper Box", module: "paperBox2" },
{ title: "Paper Envelope", module: "paperEnvelope" },
{ title: "Spirograph", module: "spirograph", hide: true },
{ title: "Tiles", module: "tiles", hide: true },
{ title: "SDFs", module: "sdfs", hide: true },
Expand Down
47 changes: 47 additions & 0 deletions src/paperBox1/ExportButtons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Button from "@mui/material/Button"
import fileDownload from "js-file-download"
import { ReactElement } from "react"
import * as React from "react"
import ReactDOMServer from "react-dom/server"
import { SvgPrintContext } from "./Measure"

export function ExportButtons({
what,
baseFileName,
}: {
what: ReactElement
baseFileName: string
}) {
const getPrintSVG = () =>
ReactDOMServer.renderToStaticMarkup(
<SvgPrintContext.Provider value={true}>{what}</SvgPrintContext.Provider>,
).replace(/\s{2,}/g, " ")
const asSVG = () => {
const svg = getPrintSVG()
fileDownload(svg, baseFileName + ".svg")
}
const asTemplatePDF = async () => {
const { svgToPdf } = await import(
/* webpackChunkName: "svgToPdf" */ "../paperBox1/svgToPdf"
)

// add your content to the document here, as usual
const blob = await svgToPdf({
title: baseFileName,
author: "Adrian Leonhard",
svg: getPrintSVG(),
})

fileDownload(blob, baseFileName + ".pdf")
}
return (
<>
<Button variant="contained" onClick={asSVG}>
Download As SVG
</Button>
<Button variant="contained" onClick={asTemplatePDF}>
Template as PDF
</Button>
</>
)
}
7 changes: 6 additions & 1 deletion src/paperBox1/Measure.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import * as React from "react"
import { ReactElement } from "react"
import { createContext, ReactElement, useContext } from "react"
import { DEG, round10, V, V3 } from "ts3dutils"
import { R2 } from "./common"

export const SvgPrintContext = createContext(false)

export function Measure({
from,
to,
Expand All @@ -20,9 +22,12 @@ export function Measure({
Array.isArray(to) && (to = V(to))
const d = from.to(to)
const length = d.length()
const isSvgPrint = useContext(SvgPrintContext)
if (isSvgPrint) return null
if (length < 0.05) return null
children ||= "" + round10(length, -1)
const textBlank = 3 * children.length

return (
<g
transform={` translate(${from[0]}, ${from[1]}) rotate(${
Expand Down
7 changes: 5 additions & 2 deletions src/paperBox1/MeasureAngle.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as React from "react"
import { ReactElement } from "react"
import { ReactElement, useContext } from "react"
import { raddd, V, V3 } from "ts3dutils"
import { fmtdeg, R2 } from "./common"
import { SvgPrintContext } from "./Measure"

export function MeasureAngle({
center,
Expand All @@ -13,8 +14,10 @@ export function MeasureAngle({
start: raddd
toRel: raddd
children?: string
}): ReactElement {
}): ReactElement | null {
Array.isArray(center) && (center = V(center))
const isSvgPrint = useContext(SvgPrintContext)
if (isSvgPrint) return null
const radius = 20
const startV = V3.polar(radius, start).plus(V(center))
const endV = V3.polar(radius, start + toRel).plus(V(center))
Expand Down
44 changes: 29 additions & 15 deletions src/paperBox1/PaperAutocomplete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,30 @@ import TextField from "@mui/material/TextField"
import * as React from "react"
import { forwardRef, ReactElement } from "react"
import { MINUS } from "ts3dutils"
import { PAPER_SIZES, PaperSize } from "./common"
import { PAPER_SIZES, PaperSize, PaperSizeFromDimensions } from "./common"

export const PaperAutocomplete = forwardRef(
export interface PaperAutocompleteProps<
DisableClearance extends boolean | undefined,
> {
disableClearance?: DisableClearance
onChange: (
dimensions: DisableClearance extends true ? PaperSize : PaperSize | null,
) => void
value: PaperSize | null
label: string
}

export type PaperAutocomplete = <DisableClearance extends boolean | undefined>(
props: PaperAutocompleteProps<DisableClearance>,
) => ReactElement | null
export const PaperAutocomplete: PaperAutocomplete = forwardRef(
(
{
disableClearance = false,
onChange,
value,
label,
}: {
disableClearance?: boolean
onChange: (dimensions: PaperSize | null) => void
value: PaperSize | null
label: string
},
}: PaperAutocompleteProps<boolean | undefined>,
ref,
): ReactElement => {
let paperSize: PaperSize | null = null
Expand All @@ -39,16 +48,21 @@ export const PaperAutocomplete = forwardRef(
)}
value={paperSize}
onChange={(e, newValue) => {
let result: PaperSize | null
if ("string" === typeof newValue) {
const regex = /(\d+(?:\.\d+)?).*?(\d+(?:\.\d+)?)/
const [, widthStr, heightStr] = regex.exec(newValue)!
const [min, max] = [+widthStr, +heightStr].sort(MINUS)
result = [min, max, "custom"]
if (newValue.trim() === "") {
if (!disableClearance) {
onChange(null!)
}
} else {
const match = /(\d+(?:\.\d+)?).*?(\d+(?:\.\d+)?)/.exec(newValue)
if (match) {
const [, widthStr, heightStr] = match
onChange(PaperSizeFromDimensions(+widthStr, +heightStr))
}
}
} else {
result = newValue
onChange(newValue!)
}
onChange(result)
}}
getOptionLabel={(val) => {
const [width, height, name = "custom"] = val
Expand Down
136 changes: 66 additions & 70 deletions src/paperBox1/PrismBoxSvg.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from "react"
import { CSSProperties, ReactElement } from "react"
import { CSSProperties, ReactElement, useContext } from "react"
import { encodeSVGPath, SVGPathData } from "svg-pathdata"
import { arrayRange, DEG, round10, TAU, V, V3 } from "ts3dutils"

Expand All @@ -9,7 +9,7 @@ import {
INCH,
radiusFromSideWidth,
} from "./common"
import { Measure } from "./Measure"
import { Measure, SvgPrintContext } from "./Measure"
import { MeasureAngle } from "./MeasureAngle"

export function PrismBoxSvg({
Expand All @@ -20,7 +20,6 @@ export function PrismBoxSvg({
theta: thetaDeg,
sideWidth,
sides,
print = false,
style,
}: {
height: number
Expand All @@ -30,7 +29,6 @@ export function PrismBoxSvg({
theta: number
sideWidth: number
sides: number
print?: boolean
style?: CSSProperties
}): ReactElement {
const shapeAngle = TAU / sides
Expand All @@ -48,6 +46,8 @@ export function PrismBoxSvg({
const centerToSide = centerToSideFromSideWidth(sides, sideWidth)
const boxWidth = centerToSide + (sides % 2 === 0 ? centerToSide : radius)

const print = useContext(SvgPrintContext)

const valley = encodeSVGPath([
// bottom lip horizontal
{
Expand Down Expand Up @@ -139,8 +139,8 @@ export function PrismBoxSvg({
strokeWidth: (2 * INCH) / 300,
...style,
}}
width={print ? width * (96 / INCH) : svgViewBox[2] + "mm"}
height={print ? height * (96 / INCH) : svgViewBox[3] + "mm"}
width={svgViewBox[2] + "mm"}
height={svgViewBox[3] + "mm"}
viewBox={svgViewBox.join(" ")}
className="adrian"
>
Expand Down Expand Up @@ -178,73 +178,69 @@ export function PrismBoxSvg({
return <circle key={i} cx={pos.x} cy={pos.y} r={0.5} stroke="black" />
})}
</g>
{!print && (
<>
<Measure from={[0, 0]} to={[0, topLip]}>
topLip
</Measure>
<Measure from={[0, topLip]} to={[0, height - bottomLip]}>
{"" + round10(height - topLip - bottomLip, -1)}
</Measure>
<Measure from={[0, height - bottomLip]} to={[0, height]}>
bottomLip
</Measure>
<Measure from={[0, 0]} to={[sideWidth, 0]}>
sideWidth
</Measure>
{arrayRange(1, sides).map((i) => (
<Measure
key={i}
from={[i * sideWidth, 0]}
to={[(i + 1) * sideWidth, 0]}
hideRight
>
{"" + round10(sideWidth * (i + 1), -1)}
</Measure>
))}
<Measure from={[0, 0]} to={[0, topLip]}>
topLip
</Measure>
<Measure from={[0, topLip]} to={[0, height - bottomLip]}>
{"" + round10(height - topLip - bottomLip, -1)}
</Measure>
<Measure from={[0, height - bottomLip]} to={[0, height]}>
bottomLip
</Measure>
<Measure from={[0, 0]} to={[sideWidth, 0]}>
sideWidth
</Measure>
{arrayRange(1, sides).map((i) => (
<Measure
key={i}
from={[i * sideWidth, 0]}
to={[(i + 1) * sideWidth, 0]}
hideRight
>
{"" + round10(sideWidth * (i + 1), -1)}
</Measure>
))}

<Measure from={[0, height]} to={[firstIntersect, height]}>
{"" + round10(firstIntersect, -2)}
</Measure>
{arrayRange(0, sides).map((i) => (
<Measure
key={i}
from={[firstIntersect + i * sideWidth, height]}
to={[firstIntersect + (i + 1) * sideWidth, height]}
hideRight
>
{"" + round10(firstIntersect + sideWidth * (i + 1), -1)}
</Measure>
))}
<Measure from={[0, height]} to={[firstIntersect, height]}>
{"" + round10(firstIntersect, -2)}
</Measure>
{arrayRange(0, sides).map((i) => (
<Measure
key={i}
from={[firstIntersect + i * sideWidth, height]}
to={[firstIntersect + (i + 1) * sideWidth, height]}
hideRight
>
{"" + round10(firstIntersect + sideWidth * (i + 1), -1)}
</Measure>
))}

<Measure from={[sides * sideWidth, 0]} to={[width, 0]}>
{"" + round10(rightTabWidth, -1)}
</Measure>
<Measure
from={[sideWidth, height]}
to={[sideWidth + intersect, height]}
offset={1}
>
{"" + round10(intersect, -1)}
</Measure>
{intersect < sideWidth && (
<Measure
from={[sideWidth + intersect, height]}
to={[sideWidth + sideWidth, height]}
offset={1}
>
{"" + round10(sideWidth - intersect, -1)}
</Measure>
)}
<MeasureAngle
center={[sideWidth * 2, height - bottomLip]}
start={90 * DEG}
toRel={-creaseAngle}
>
{fmtdeg(creaseAngle)}
</MeasureAngle>
</>
<Measure from={[sides * sideWidth, 0]} to={[width, 0]}>
{"" + round10(rightTabWidth, -1)}
</Measure>
<Measure
from={[sideWidth, height]}
to={[sideWidth + intersect, height]}
offset={1}
>
{"" + round10(intersect, -1)}
</Measure>
{intersect < sideWidth && (
<Measure
from={[sideWidth + intersect, height]}
to={[sideWidth + sideWidth, height]}
offset={1}
>
{"" + round10(sideWidth - intersect, -1)}
</Measure>
)}
<MeasureAngle
center={[sideWidth * 2, height - bottomLip]}
start={90 * DEG}
toRel={-creaseAngle}
>
{fmtdeg(creaseAngle)}
</MeasureAngle>
{!print && (
<g
transform={`translate(200, ${boxHeight * 2})`}
Expand Down
8 changes: 6 additions & 2 deletions src/paperBox1/ValleyMountainLegend.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import * as React from "react"
import { CSSProperties, ReactElement } from "react"
import { CSSProperties, ReactElement, useContext } from "react"
import { SvgPrintContext } from "./Measure"

export const ValleyMountainLegend = (
props: React.SVGProps<SVGGElement>,
): ReactElement => {
): ReactElement | null => {
const textStyle: CSSProperties = {
fontSize: 4,
dominantBaseline: "middle",
}
const print = useContext(SvgPrintContext)
if (print) return null

return (
<g {...props}>
<text style={textStyle} y={-4}>
Expand Down
Loading

0 comments on commit c6c3781

Please sign in to comment.