【问题标题】:How to create lines without using an image如何在不使用图像的情况下创建线条
【发布时间】:2015-12-28 19:22:19
【问题描述】:

我正在尝试在不使用图像的情况下创建下面的图表(显然没有 ASCII 字符和实线)。我该怎么办?我在考虑 canvas 或 CSS3,除非有更好的东西。

 \                       /
  \                     /
   ---------------------
  /                     \
 /                       \

【问题讨论】:

  • 取决于你想用它做什么。就目前而言,这个问题太宽泛,无法正确回答。此外,SVG 可能是一个不错的选择。
  • 我只想在水平线的顶部和底部加上一个数字,然后在图表的两端也一样。
  • Canvas 和 SVG 都可以轻松绘制出您需要的线条和文本数字。
  • @Catfish。你问了一个好问题,但带有“最好/最简单”字样的问题注定要被关闭。具有讽刺意味的是,当前的密切投票是“过于宽泛”而不是“基于意见”,而您的问题的定义非常好和狭隘。我已经编辑了您的问题以删除那些吸引投票的词。顺便说一句,在画布中查看 moveTolineTo 命令。在 SVG 中,使用 M or mL or l 命令检查路径子元素。

标签: html css html5-canvas css-shapes


【解决方案1】:

有多种方法可以实现所提供的效果,下面提供了其中一些的 sn-ps。每个都有自己的优点和缺点,因此请根据您的要求选择其中之一。

使用 CSS 变换:

我们可以使用带有两个伪元素的 CSS 透视变换,每个伪元素大约是父元素高度的 50%。伪元素相对于父元素绝对定位,它们的边框产生线条。 (span的定位方法是随机的,你可以使用任何你觉得舒服的方法。)

在设计响应式形状时,透视变换可能非常难以处理。随着容器尺寸的变化,我们必须修改margin。形状的其他部分会消失。运行时的边际值应该是多少是相当困难的。

.shape{
  position: relative;
  height: 100px;
  width: 200px;
  margin: 20px;
}
.shape:after, .shape:before{
  position: absolute;
  content: '';
  left: 0px;
  height: calc(50% - 1px);
  width: 100%;
  border-style: solid;
}
.shape:before{
  top: 0;
  border-width: 0px 2px 1px 2px;
  transform: perspective(50px) rotateX(-10deg);
  transform-origin: bottom;
  }
.shape:after{
  bottom: 0;
  border-width: 1px 2px 0px 2px;  
  transform: perspective(50px) rotateX(10deg);
  transform-origin: top;  
}
span{
  display: block;
  position: absolute;
  top: 50%;
}
span:nth-child(1){
  left: 50%;
}
span:nth-child(2){
  left: 50%;
  transform: translateY(-100%);
}
span:nth-child(3){
  left: 0%;
  transform: translateY(-50%) translateX(-150%);
}
span:nth-child(4){
  right: 0%;
  transform: translateY(-50%) translateX(200%);  
}
<div class='shape'>
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
</div>

使用 SVG:

使用 SVG,我们可以使用 moveTo (M) 和 line (L) 命令绘制 path 来生成线条。 sn-p 中使用的 SVG 绘图命令非常简单且一目了然。我们只是移动到一个点(由 X 和 Y 坐标表示),然后从该点画线到其他指定点。再次,SVG 相对于父对象绝对定位。

SVG 设计为默认响应式,即使容器的尺寸发生变化也能很好地适应。需要注意的一件主要事情是路径的笔触也会缩放。正因为如此,当容器的高度和宽度在不保持原始比例的情况下发生变化(即仅增加高度)时,笔画的某些部分会变得比其余部分更粗(即,如果仅改变高度,则水平线变粗)。这可以通过添加属性vector-effect='non-scaling-stroke' 来解决,但 IE 不支持。

.shape {
  position: relative;
  height: 100px;
  width: 200px;
  margin: 20px;
}
svg {
  position: absolute;
  height: 100%;
  width: 100%;
}
path {
  stroke: black;
  stroke-width: 2;
  fill: none;
}
span {
  display: block;
  position: absolute;
  top: 50%;
}
span:nth-of-type(1) {
  left: 50%;
}
span:nth-of-type(2) {
  left: 50%;
  transform: translateY(-100%);
}
span:nth-of-type(3) {
  left: 0%;
  transform: translateY(-50%) translateX(-50%);
}
span:nth-of-type(4) {
  right: 0%;
  transform: translateY(-50%) translateX(50%);
}
<div class='shape'>
  <svg viewBox='0 0 200 100' preserveAspectRatio='none'>
    <path d='M0,0 L20,50 0,100 20,50 180,50 200,0 180,50 200,100' vector-effect='non-scaling-stroke' />
  </svg>
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
</div>

使用画布:

Canvas 绘图命令与 SVG 非常相似,在这里我们可以再次使用 moveTolineTo 命令绘制 path 来生成线条。我们只是移动到一个点(由 X 和 Y 坐标表示),然后从该点画线到其他指定点。同样,Canvas 相对于父级绝对定位。

画布绘图是基于光栅的(与基于矢量的 SVG 不同),因此默认情况下它不是响应式的。缩放时,Canvas 绘图会变得模糊(像素化),并且每当容器尺寸发生变化时都需要重新绘制。这使得它在容器的尺寸不固定时不太适合使用。

window.onload = function() {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  
  ctx.lineWidth = '2';
  
  ctx.beginPath();
  ctx.moveTo(0,0);
  ctx.lineTo(20,50);
  ctx.lineTo(0,100);
  ctx.lineTo(20,50);
  ctx.lineTo(180,50);
  ctx.lineTo(200,0);
  ctx.lineTo(180,50);
  ctx.lineTo(200,100);
  ctx.stroke();
}
.shape {
  position: relative;
  height: 100px;
  width: 200px;
  margin: 20px;
}
canvas{
  position: absolute;
}
svg {
  position: absolute;
  height: 100%;
  width: 100%;
}
path {
  stroke: black;
  stroke-width: 2;
  fill: none;
}
span {
  display: block;
  position: absolute;
  top: 50%;
}
span:nth-of-type(1) {
  left: 50%;
}
span:nth-of-type(2) {
  left: 50%;
  transform: translateY(-100%);
}
span:nth-of-type(3) {
  left: 0%;
  transform: translateY(-50%) translateX(-50%);
}
span:nth-of-type(4) {
  right: 0%;
  transform: translateY(-50%) translateX(50%);
}
<div class='shape'>
  <canvas id='canvas' height='100px' width='200px'></canvas>
  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
</div>

【讨论】:

    【解决方案2】:

    如果形状只是为了“装饰”,你总是可以只使用 CSS3 的边框技巧。

    #pentagon {
        position: relative;
        width: 54px;
        border-width: 50px 18px 0;
        border-style: solid;
        border-color: #1abc9c transparent;
    }
    
    #pentagon_two{
        position: relative;
        width: 54px;
        border-width: 50px 18px 0;
        border-style: solid;
        border-color: #1abc9c transparent;
        transform: rotate(180deg);
    }
    

    JSFiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-25
      • 1970-01-01
      • 2020-08-10
      • 2015-08-28
      • 2020-11-07
      • 1970-01-01
      • 1970-01-01
      • 2017-02-14
      相关资源
      最近更新 更多