创建具有 24 点或以上点阵的“新"尖刺标签

2022-01-17 00:00:00 svg html css html5-canvas css-shapes

我正在尝试制作一个点爆点,如下图所示:

I am trying to make a point burst thing like the image below:

目前,我已尝试使用伪元素进行此操作,但是,我只能生成 12 点连拍,并不能反映图像中显示的内容.

Currently, I have tried this using pseudo elements, however, I was only able to generate a 12 point burst and does not reflect that which is displayed within the image.

有没有办法用几个元素来创建一个点阵?

Is there anyway to create a point burst with only a few elements?

以下是我用来尝试此解决方案的代码:

Below is the code I have used to attempt this solution:

div{
    width:100px;
    height:100px;
    background:grey;
    transform:rotate(45deg);
    margin:50px;
}
div:after{
    position:absolute;
    content:"";
    background:grey;
    width:100px;
    height:100px;
    transform:rotate(135deg);
}
div:before{
    position:absolute;
    content:"";
    background:grey;
    width:100px;
    height:100px;
    transform:rotate(250deg);
}

<div></div>

推荐答案

Canvas Approach

您也可以使用 Canvas 实现此目的.在 Canvas 上绘图的命令与在 SVG 中几乎相同.在非常高的层次上,这种方法是在两个圆上找到点(一个半径为 x,另一个半径稍小),然后将它们连接在一起形成一条路径.当路径被填满时,它会出现一个 n 点爆发的外观.

Canvas Approach

You can also achieve this using Canvas. The commands for drawing on Canvas are pretty much the same as in SVG. The approach, on a very high level, would be to find points on two circles (one with radius as x and another with a slightly smaller radius) and then connect them together to form a path. When the path is filled, it gives the appearance of a n-point burst.

在下图中,绿色圆圈是半径为 x 的较大圆圈,蓝色圆圈是较小的内圈.通过在圆圈上绘制点并将它们连接起来(使用 lineTo 命令),我们得到红色的路径.当这条路径被填满时,我们得到了爆发的外观.(注意:内圈和外圈仅供说明,实际图中未画出).

In the below diagram, the green circle is the bigger circle with radius as x and the blue circle is the smaller inner circle. By plotting points on the circles and connecting them (with lineTo commands), we get the path which is in red. When this path is filled we get the burst appearance. (Note: The inner and outer circles are only for illustration and are not drawn in the actual diagram).

  • 圆上各点的X和Y坐标可以使用以下公式计算:
    • x = (圆的半径 * Cos(弧度的角度)) + 圆心的 x 坐标
    • y = (圆的半径 * Sin(弧度的角度)) + 中心的 y 坐标
    • The X and Y coordinates of each points on the circle can be calculated using the below formula:
      • x = (Radius of circle * Cos(Angle in Radians)) + x coordinate of center
      • y = (Radius of circle * Sin(Angle in Radians)) + y coordinate of center
      • 正如您和 Persijn 的答案中所使用的那样,角度计算为(360/爆发次数).使用 360 度是因为它是一个圆内的总角度.
      • 内圆上的点的角度应该在大圆上的 point1 和 point2 之间的中间,因此会添加一个增量.delta 是(360/no. of bursts)的一半

      window.onload = function() {
        var canvas = document.getElementById('canvas');
        var ctx = canvas.getContext('2d');
        var defaultBurst = 18;
        var defaultContent = "New";
      
        function paint(numBurst, text) {
          if (!numBurst) numBurst = defaultBurst;
          if (!text) text = defaultContent;
          ctx.clearRect(0, 0, canvas.width, canvas.height);
          ctx.fillStyle = 'crimson';
          var angleInRad = Math.PI * (360 / numBurst) / 180;
          var deltaAngleInRad = angleInRad / 2;
          ctx.beginPath();
          ctx.moveTo(75, 150);
          for (i = 0; i <= numBurst; i++) {
            x1 = 75 * Math.cos(angleInRad * i) + 150;
            y1 = 75 * Math.sin(angleInRad * i) + 150;
            x2 = 60 * Math.cos((angleInRad * i) + deltaAngleInRad) + 150;
            y2 = 60 * Math.sin((angleInRad * i) + deltaAngleInRad) + 150;
            ctx.lineTo(x1, y1);
            ctx.lineTo(x2, y2);
          }
          ctx.closePath();
          /* Add shadow only for shape */
          ctx.shadowOffsetX = -5;
          ctx.shadowOffsetY = 5;
          ctx.shadowBlur = 5;
          ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
          ctx.fill();
          ctx.font = "32px Arial";
          ctx.textAlign = "center";
          ctx.fillStyle = "gold";
          /* Nullify shadow for text */
          ctx.shadowOffsetX = 0;
          ctx.shadowOffsetY = 0;
          ctx.fillText(text, 150, 160, 120);
        }
        paint();
        var slider = document.getElementById('burst');
        var textInput = document.getElementById('content');
        slider.addEventListener('change', function() {
          paint(this.value, textInput.value);
        });
      
        textInput.addEventListener('blur', function() {
          paint(slider.value, this.value);
        });
      }

      /* For demo only */
      
      .controls {
        float: right;
        padding: 5px;
        margin: 50px 20px;
        line-height: 25px;
        border: 1px solid;
        box-shadow: 1px 1px 0px #222;
      }
      label,
      input {
        display: inline-block;
        vertical-align: middle;
        text-align: left;
      }
      h3 {
        padding: 10px;
        text-align: center;
      }
      label {
        width: 100px;
      }
      input[type='range'],
      input[type='text'] {
        width: 100px;
      }
      body {
        font-family: Calibri;
        background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%);
      }

      <canvas id='canvas' height='300px' width='300px'></canvas>
      <div class='controls'>
        <h3>Controls</h3>
      
        <label for="burst">Change Burst:</label>
        <input id="burst" class="slider" type="range" value="18" min="12" max="36" step='2' title="Adjust slider to increase or decrease burst" />
        <br/>
        <label for="content">Text Content:</label>
        <input type="text" id="content" maxlength="5" />
      </div>

      查看此 CodePen 以获得具有路径创建动画、阴影等功能的高级演示, 控制所有功能等.

      Check out this CodePen for an advanced demo with features like path creation animation, shadows, control over all the features etc.

      如果您想在页面的某处获得固定大小的图像,那么 Canvas 与 SVG 一样好.但是,如果您需要可以缩放到任何尺寸的图像,Canvas 不是正确的选择,因为 Canvas 是基于光栅的,并且在缩放时会变得像素化或模糊.

      If you want a fixed size image somewhere in the page then Canvas is as good as SVG. However, if you would need an image that can be scaled to any size, Canvas is not the right choice because Canvas is raster based and becomes pixelated or blurred when scaled.

      如果您的形状需要动态数量的突发和/或文本,Canvas 会比 SVG 和 CSS 更可取,因为您不必执行任何 DOM 操作.

      If your shape would need a dynamic number of bursts and/or text, Canvas would be more preferable over SVG and CSS because you don't have to perform any DOM manipulations.

相关文章