如何生成具有两个圆形边的细长六边形?

时间:2015-03-31 09:50:00

标签: css css3 css-shapes

我试图在我的设计中产生这种形状:

enter image description here

其中一个画布元素出现在圆圈的中间部分,这种细长的六边形出现在外面。

然而,我在形状方面存在一些问题 - 主要是我如何使用渐变或背景图像制作形状(即内部拼图块看起来是一个图像)。外部背景将是纯色背景(#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();
})();
&#13;
@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;
 }
&#13;
<div class="canwrap">
  <canvas id="c" class="img"></canvas>
</div>
&#13;
&#13;
&#13;

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

  • 背景部分不能是图像
  • 圈子无法复制图像部分
  • 渐变停止颜色意味着没有明确的边缘&#39;形状。

我真的很感激能够在构建这个形状时获得另一种观点/角度,因为我还没有能够以我需要的方式产生这种形状。

我知道svg可能就是这样做的方式,但是与css相比,我总是很难让svg成为正确的动画 - 但如果要么工作,我会很高兴(因为我的设计并不完全允许我的图像设计)!

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

3 个答案:

答案 0 :(得分:4)

我使用svg Fiddle

这样的事情怎么样

&#13;
&#13;
<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>
&#13;
&#13;
&#13;

您也可以将图像作为背景

&#13;
&#13;
<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"/>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

虽然这不适用于画布,但对于html元素,您可以在画布中执行相同的技术。 我假设你已经知道了基本的css 3,现在因为编码很多,我会给你指示:

1)前往this link

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

3)创建2个小圆圈并将每个圆圈(相对/绝对)定位在梯形边缘上,其z-index小于梯形

4)中间有一个圆圈,你完成了!

答案 2 :(得分:0)

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

创建路径,并填写模式。

&#13;
&#13;
<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>
&#13;
&#13;
&#13;

高度和宽度已设置为100%,因此应该具有响应性。此外,可以使用x,y属性更改图像的位置。