TryShape 背后的故事:一个展示 CSS clip-path 属性的平台

Avatar of Tapas Adhikary
Tapas Adhikary

DigitalOcean 提供适用于您旅程各个阶段的云产品。立即开始使用 $200 免费额度!

我喜欢形状,尤其是彩色的!网站上的形状与背景颜色、图像、横幅、分隔符、艺术作品等一样重要:它们可以帮助我们理解上下文,并通过可供性告知我们的操作。

几个月前,我开发了一个应用程序来帮助我 7 岁的女儿学习数学。除了基本的加减运算外,我的目标是用形状呈现问题。那时我熟悉了 CSS clip-path 属性,这是在网络上创建形状的可靠方法。然后,我最终利用 clip-path 的强大功能开发了另一个名为 TryShape 的应用程序。

我将带您了解 TryShape 背后的故事,以及它如何帮助创建、管理、共享和导出形状。在此过程中,我们将深入了解 CSS clip-path,以及它如何帮助我快速构建应用程序。

以下是一些重要链接

首先,CSS clip-path 属性和形状

想象一下,您有一张白纸和一支铅笔,要在上面画一个形状(比如一个正方形)。您将如何操作?最有可能的是,您将从一个开始,然后画一条线到达另一个点,然后重复此操作三次,回到起点。您还需要确保对边平行长度相同

因此,形状的必要元素包括点、线、方向、曲线、角度和长度等。CSS clip-path 帮助指定其中许多属性,以裁剪 HTML 元素的区域,以显示特定区域。裁剪区域内的部分将显示,其余部分将隐藏。它为开发人员提供了无限的机会,让他们可以使用 clip-path 属性创建各种形状。

了解有关裁剪的更多信息,以及它与遮罩的不同之处。

用于创建形状的 clip-path 值

clip-path 属性接受以下值来创建形状

  • circle()
  • ellipse()
  • inset()
  • polygon()
  • 使用 url() 函数的剪辑源
  • path()

我们需要稍微了解一下基本坐标系才能使用这些值。当在元素上应用 clip-path 属性来创建形状时,我们必须考虑 x 轴、y 轴以及元素左上角的初始坐标 (0,0)

这是一个带有 x 轴、y 轴和初始坐标 (0,0)div 元素。

A blue square with its starting point located at a zero zero position on a chart with x and y axes.
带有 x 轴和 y 轴的初始坐标 (0,0)

现在让我们使用 circle() 值来创建一个圆形形状。我们可以使用此值指定圆形的位置和半径。例如,要在坐标位置 (70, 70) 处剪辑一个半径为 70px 的圆形形状,我们可以将 clip-path 属性值指定为

clip-path: circle(70px at 70px 70px)

因此,圆形的中心位于坐标 (70, 70) 处,半径为 70px。现在,只有这个圆形区域被裁剪并显示在元素上。元素的其余部分被隐藏,从而产生一个圆形形状的印象。

A blue circle on a grid with an x and y axis. The circle starts at the zero zero position and its center is located at 70 px and 70px. A zoomed in area shows the clipping path, which is also located at 70x and 70px.
圆形的中心位于 (70, 70) 坐标处,裁剪了 70px x 70px 的区域。因此,整个圆形都显示出来了。

接下来,如果我们想将位置指定为 (0,0),该怎么办?在这种情况下,圆形的中心位于 (0,0) 位置,半径为 70px。这使得圆形只有一部分可见在元素内部。

The center of a blue circle is placed at the 0,0 coordinates with a 70px by 70px area clipping the bottom-left region of the circle.
圆形的中心位于 (0, 0) 坐标处,裁剪了 70px x 70px 的区域,裁剪掉了圆形的左下区域。

让我们继续使用另外两个基本值,inset()polygon()。我们使用内边距来定义一个矩形形状。我们可以指定四个边可能具有的间隙,以从元素中剪辑一个区域。例如

clip-path: inset(30px)

上面的 clip-path 值通过从元素的边缘去除 30px 的值来裁剪一个区域。我们可以在下面的图像中看到这一点。我们还可以为每个边指定不同的内边距值。

inset() 函数允许我们从形状的外部边缘裁剪一个区域。

接下来是 polygon() 值。我们可以使用一组顶点来创建一个多边形形状。以这个例子为例

clip-path: polygon(10% 10%, 90% 10%, 90% 90%, 10% 80%)

这里我们指定了一组顶点来创建裁剪区域。下面的图像显示了每个顶点的位置,以创建一个多边形形状。我们可以根据需要指定任意数量的顶点。

A square with four points inside of it located at 10% by 10%, 90% by 10%, 10% by 80% and 90% by 90%, creating the clipped area.
polygon() 函数允许我们使用传递给它的顶点集创建多边形形状。

接下来,让我们看看 ellipse()url() 值。ellipse() 值通过指定两个半径值和一个位置来帮助创建形状。在下面的图像中,我们看到一个椭圆形位于半径为 (50%,50%) 的位置,形状为 70px 宽,100px 高。

A blue blue against a light blue background. The ellipse is 70 pixels wide and 100 pixels tall and it's radius is centered at 50% 50%.
我们需要指定两个半径值和一个位置来创建一个椭圆形。

url() 是一个 CSS 函数,用于指定 clip-path 元素的 ID 值来呈现 SVG 形状。请查看下面的图像。我们使用 clipPathpath 元素定义了一个 SVG 形状。您可以将 clipPath 元素的 ID 值用作 url() 函数的参数,以呈现此形状。

Showing the SVG code for a heart-shaped path and the actual heart next to it in blue.
在这里,我们使用 url() 函数创建了一个心形形状

此外,我们可以在 path() 函数中直接使用路径值来绘制形状。

Showing a line of CSS code for the clip-path property filled in with the code of an SVG path inside the path function. The result is below the code, a parabolic curve that's filled in blue.
在这里,我们使用 path() 函数创建了一个弯曲的形状。

好吧。希望您已经了解了不同的 clip-path 属性值。有了这些理解,让我们看一看一些实现并与它们一起玩。这里有一个供您使用的 Pen。请使用它尝试添加和修改值来创建新的形状。

让我们来谈谈 TryShape

现在该谈谈 TryShape 及其背景故事了。TryShape 是一款开源应用程序,它可以帮助创建、导出、共享和使用您选择的任何形状。您可以创建横幅、圆形、艺术作品、多边形,并将它们导出为 SVG、PNG 和 JPEG 文件。您还可以创建 CSS 代码片段以复制并使用在您的应用程序中。

TryShape 使用以下框架和库构建(当然也包括 clip-path

  • CSS clip-path:我们已经讨论过这个很棒的 CSS 属性的强大功能。
  • Next.js:最酷的 React 框架。它帮助我创建页面、组件、交互和连接到后端数据库的 API。
  • HarperDB:一个灵活的数据库,用于存储数据并使用 SQL 和 No-SQL 交互来查询它们。TryShape 在 HarperDB 云中创建了其模式和表。Next.js API 与模式和表进行交互,以从用户界面执行所需的 CRUD 操作。
  • Firebase:来自 Google 的身份验证服务。TryShape 使用它来使使用 Google、GitHub、Twitter 和其他帐户的社交登录正常工作。
  • react-icons:一个面向所有基于 React 的应用程序的图标一站式商店
  • date-fns:用于日期格式化的现代、轻量级库
  • axios:从 React 组件轻松进行 API 调用
  • styled-components:一种从 React 组件创建 CSS 规则的结构化方法
  • react-clip-path:一个内部模块,用于在 React 应用程序中处理 clip-path 属性
  • react-draggable:使 React 应用程序中的 HTML 元素可拖动。TryShape 使用它来调整形状顶点的位置。
  • downloadjs:从 JavaScript 触发下载
  • html-to-image:将 HTML 元素转换为图像(包括 SVG、JPEG 和 PNG)
  • Vercel:最适合托管 Next.js 应用程序

使用 CSS clip-path 在 TryShape 中创建形状

让我重点介绍帮助使用 CSS clip-path 属性创建形状的源代码。下面的代码段定义了一个容器元素(Box)的用户界面结构,该元素为 300px 正方形。Box 元素有两个子元素,ShadowComponent

<Box 
  height="300px" 
  width="300px" 
  onClick={(e) => props.handleChange(e)}>
  { 
    props.shapeInformation.showShadow && 
    <Shadow 
      backgroundColor={props.shapeInformation.backgroundColor} 
      id="shapeShadow" /> 
  }
  <Component 
    formula={props.shapeInformation.formula} 
    backgroundColor={props.shapeInformation.backgroundColor} 
    id="clippedShape" />
</Box>

Shadow 组件定义了被 clip-path 剪裁隐藏的区域。我们创建它是为了显示一个浅色背景,使该区域对最终用户部分可见。Component 用于分配 clip-path 值以显示剪裁区域。

请参见下方 BoxShadowComponent 的样式化组件定义

// The styled-components code to create the UI components using CSS properties

// The container div
const Box = styled.div`
  width: ${props => props.width || '100px'};
  height: ${props => props.height || '100px'};
  margin: 0 auto;
  position: relative;
`;

// Shadow defines the area that is hidden by the `clip-path` clipping
// We show a light color background to make this area partially visible.
const Shadow = styled.div`
  background-color: ${props => props.backgroundColor || '#00c4ff'};
  opacity: 0.25;
  position: absolute;
  top: 10px;
  left: 10px;
  right: 10px;
  bottom: 10px;
`;

// The actual component that takes the `clip-path` value (formula) and set
// to the `clip-path` property.
const Component = styled.div`
  clip-path: ${props => props.formula}; // the formula is the clip-path value
  background-color: ${props => props.backgroundColor || '#00c4ff'};
  position: absolute;
  top: 10px;
  left: 10px;
  right: 10px;
  bottom: 10px;
`;
An illustration of a blue box with its inset clip points drawing another square that indicates the visible area of the shape in a darker blue.
用于在剪裁后显示形状(可见和隐藏区域)的组件。

欢迎您查看 GitHub 仓库中的完整代码库

TryShape 的未来范围

TryShape 很好地支持使用 CSS clip-path 在背景中创建和管理基本形状。它有助于导出形状和 CSS 代码片段,以便在您的 Web 应用程序中使用。它有潜力随着更多有价值的功能而发展。主要的将是能够创建具有曲线边的形状。

为了支持曲线形状,我们需要在 TryShape 中支持以下值

  • 使用 url() 的剪裁源,以及
  • path().

借助这些值,我们可以使用 SVG 创建形状,然后使用上述值之一。以下是用 url() CSS 函数使用 SVG 支持创建形状的示例。

<div class="heart">Heart</div>
<svg>
  <clipPath id="heart-path" clipPathUnits="objectBoundingBox">
    <path d="M0.5,1
      C 0.5,1,0,0.7,0,0.3
      A 0.25,0.25,1,1,1,0.5,0.3
      A 0.25,0.25,1,1,1,1,0.3
      C 1,0.7,0.5,1,0.5,1 Z" />
  </clipPath>
</svg>

然后,CSS:

.heart {
  clip-path: url(#heart-path);
}
It produces a heart shape like this.

现在,让我们使用 path() 值创建一个形状。HTML 应该有一个类似 div 的元素

<div class="curve">Curve</div>

在 CSS 中

.curve {
  clip-path: path("M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80");
}

在结束之前…

我希望您喜欢我的 TryShape 应用程序,并了解导致它的想法、我考虑的策略、底层技术及其未来潜力。请考虑尝试它并查看源代码。当然,欢迎您通过问题、功能请求和代码来为它做出贡献。

在结束之前,我想让您观看这段为 Hashnode 黑客马拉松准备的简短视频,TryShape 作为参赛作品最终进入了获奖名单。我希望您喜欢它。

让我们保持联系。您可以在Twitter (@tapasadhikary) 上用评论@我,或者随时关注。