【问题标题】:How to generate a elongated hexagon shape with two circular sides?如何生成具有两个圆形边的细长六边形?
【发布时间】:2015-04-18 18:39:02
【问题描述】:

我正在尝试在我的设计中生成这种形状:

其中一个canvas元素出现在圆的中间,这种拉长的六边形出现在外围。

但是,我在形状方面遇到了一些问题 - 主要是如何使用渐变或背景图像制作形状(即,内部拼图看起来将是图像)。外部背景将是纯色背景 (#222)。

当前尝试

我目前的尝试是使用背景渐变来生成大部分形状,并为两侧的两个圆形部分使用伪元素::

var a = 100; // size of the black hole.
var b = 200; // distance of black hole from canvas center.
var c = 1; // speed of black hole rotation.
var d = 20; // the amount of stars to spawn every frame.

// ---------------------------------------------

var canvas = document.getElementById('c'),
  ctx = canvas.getContext('2d'),
  stars = [],
  m = {},
  r = 0

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

m.x = null;
m.y = null;

ctx.strokeStyle = '#fff';
ctx.translate(0.5, 0.5);

// create stars
function createStars(n) {

  if (m.x == null) return;

  for (var i = 0; i < n; i++) {
    var shape = {
      x: m.x,
      y: m.y,
      r: 1,
      speed: 1,
      accel: 1.01,
      accel2: 0.001,
      angle: Math.random() * 360
    }

    var vel = {
      x: a * Math.cos(shape.angle * Math.PI / 180),
      y: a * Math.sin(shape.angle * Math.PI / 180)
    };

    shape.x += vel.x;
    shape.y += vel.y;

    stars.push(shape);
  }
}

function render() {
  createStars(d);

  var bench = [];
  // ctx.save();
  // ctx.fillStyle = 'rgba(0,0,0,0.5)';
  // ctx.fillRect(0, 0, canvas.width, canvas.height);
  // ctx.restore();

  ctx.clearRect(0, 0, canvas.width, canvas.height);

  r += c;
  if (r < 360) {
    m = {
      x: canvas.width / 2,
      y: canvas.height / 2,
      angle: r
    }

    var targetAngle = m.angle * Math.PI / 180;

    m.x += b * Math.cos(targetAngle);
    m.y += b * Math.sin(targetAngle);
  } else {
    r = 0;
  }

  while (stars.length) {
    var star = stars.pop();

    var vel = {
      x: star.speed * Math.cos(star.angle * Math.PI / 180),
      y: star.speed * Math.sin(star.angle * Math.PI / 180)
    };

    ctx.beginPath();
    ctx.moveTo(star.x, star.y);
    ctx.lineTo(star.x + vel.x, star.y + vel.y);
    ctx.closePath();
    ctx.stroke();

    star.x += vel.x;
    star.y += vel.y;

    star.speed *= star.accel;

    star.accel += star.accel2;

    if (star.x < canvas.width && star.x > 0 && star.y < canvas.height && star.y > 0) {
      bench.push(star);
    }
  }

  stars = bench.slice(0).reverse();
}

window.requestAnimFrame = (function() {
  return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) {
    window.setTimeout(callback, 1000 / 60);
  };
})();

(function animloop() {
  requestAnimFrame(animloop);
  render();
})();
@import url(https://fonts.googleapis.com/css?family=Hammersmith+One);
 html {
   margin: 0;
   padding: 0;
   height: 100vh;
   background: #222;
   color: cornflowerblue;
   overflow-x: hidden;
   font-size: 18px;
   font-family: 'Hammersmith One', sans-serif;
 }
 /************************************/
 #c {
   height: 200px;
   width: 200px;
   border-radius: 50%;
   border: 5px double lightgray;
   margin-left: 150px;
   margin-right: 150px;
   background: #222;
   z-index: 10;
   position: absolute;
   left: 0px;
   top: 50px;
 }
 .canwrap {
   background: url(http://placekitten.com/g/300/300);
   height: 300px;
   width: 500px;
   position: relative;
   z-index: 0;
   margin-left: 50px;
   margin-right: 50px;
 }
 .canwrap:before {
   content: "";
   position: absolute;
   width: 150px;
   height: 100%;
   top: 0;
   left: 50%;
   transform: translateX(-50%);
   background: #222;
   z-index: -1;
 }
 .canwrap:after {
   content: "";
   position: absolute;
   height: 100px;
   width: 100px;
   top: 100px;
   left: -50px;
   background: red;
   border-radius: 50%;
   box-shadow: 500px 0 20px -5px red;
 }
<div class="canwrap">
  <canvas id="c" class="img"></canvas>
</div>

但是,这给我留下了一些问题:

  • 背景部分不能是图片
  • 圆圈无法复制图像部分
  • 渐变色表示形状没有“清晰边缘”。

我真的很感激能在构建这个形状时获得另一个视角/角度,因为我无法以我需要的方式制作它。

我知道 svg 可能是做到这一点的方法,但与 css 相比,我一直很难让 svg 正确地制作动画 - 但如果其中任何一种工作,我会很高兴(因为我的设计没有完全允许我的形象设计)!

一如既往,任何建议都会很棒。

【问题讨论】:

    标签: css css-shapes


    【解决方案1】:

    像这样的东西我用过 svg Fiddle

    <svg width="1000" height="500">
      <polygon points="100 10, 50 245, 100 500, 200 500, 200 10,100 10" fill="orange" />
      <polygon points="400 10, 460 245, 400 500, 300 500, 300 10,200 10" fill="orange" />
      <circle r="50" cx="50" cy="245" fill="orange" />
      <circle r="50" cx="460" cy="245" fill="orange" />
      <circle r="100" cx="255" cy="245" fill="midnightblue" />
    </svg>

    你也可以用图片做背景

    <svg width="1000" height="500">
         <defs>
        <pattern id="pattern" patternUnits="userSpaceOnUse" width="1000" height="1000">
            <image xlink:href="https://placekitten.com/g/200/300" x="-200" y="-10" width="1000" height="1000" />
        </pattern>
    </defs>
        <polygon points="100 10, 50 245, 100 500, 200 500, 200 10,100 10" fill="url(#pattern)"/> 
             <polygon points="400 10, 460 245, 400 500, 300 500, 300 10,200 10" fill="url(#pattern)"/> 
        <circle r="50" cx="50" cy="245" fill="url(#pattern)"/>
         <circle r="50" cx="460" cy="245" fill="url(#pattern)"/>
        <circle r="100" cx="255" cy="245" fill="midnightblue"/>

    【讨论】:

    • @Maddy 感谢 svg 非常强大
    【解决方案2】:

    虽然这不是针对画布而是针对 html 元素,但您可以在画布中执行相同的技术。 我假设你已经了解了基本的 css 3,现在因为编写代码需要做很多工作,所以我会给你说明:

    1) 前往this link

    2) 创建 2 个梯形并将它们旋转 90 度

    3) 创建 2 个小圆圈并将每个小圆圈(相对/绝对)放置在 z-index 小于梯形的梯形边缘

    4) 在中间圈一圈,你就完成了!

    【讨论】:

      【解决方案3】:

      可以使用svg,在很大程度上简化了形状的创建。

      创建路径,并填充图案。

      <svg version="1.1" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" viewBox="0 0 65 50" xmlns:xlink="http://www.w3.org/1999/xlink">
      <defs>
          <pattern id="image" patternUnits="userSpaceOnUse" width="100" height="100">
              <image xlink:href="http://www.placecage.com/g/200/300" width="50" x="-10" y="0" height="50"/>
              <image xlink:href="http://www.placekitten.com/g/200/300" width="50" x="30" y="0" height="50"/>
          </pattern>
      </defs>
      <path d="M 25 0 H 15 L 10 20 A 5.3 5.3 0 1 0 10 30 L15 50 H25 z M 40 0 H 50 L 55 20 A 5.3 5.3 0 1 1 55 30 L 50 50 H 40 z" fill="url(#image)" stroke="none"/>
      </svg>

      高度和宽度已设置为 100%,所以这应该是响应式的。此外,还可以使用 x,y 属性更改图像的位置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-23
        • 2018-08-13
        • 1970-01-01
        • 2016-06-08
        • 1970-01-01
        相关资源
        最近更新 更多