图片环形分布的那些破事

最近跟合成自定义图片杠上了,总是在搞这些无聊的事,之前文字环形分布是用svg解决的,但是图片环形分布就呵呵了。于是做了些折腾:

SVG

offset-path 能实现环形分布,实现成本最低,可以直接在客户端转化图片,精确度高,但是浏览器支持度惨不忍睹:

如果无视兼容性推荐这个:具体实现如下:

<style>
@supports (offset-path: path('M0,0 C100,100 700,200 800,100')) {
    .box {
    width: 500px;
    height: 500px;
    border: 0px dotted cyan;
    position: relative;
    transform-style: preserve-3d;
    transform: var(--transform);
    --transform: scale(1);
    display: none;
    }
  .item{
    position: absolute;
    motion-offset: 0%;
    offset-path: path('M 155 155 m -155 0 a 155 155 0 0 0 310 0 a 155 155 0 0 0 -310 0');
  }
}
</style>
<div class="box">
<span class="item"><img src="images/1-t1.png" alt=""></span>
<span class="item"><img src="images/1-t2.png" alt=""></span>
<span class="item"><img src="images/1-t3.png" alt=""></span>
<span class="item"><img src="images/1-t4.png" alt=""></span>
<span class="item"><img src="images/1-t5.png" alt=""></span>
<span class="item"><img src="images/1-t6.png" alt=""></span>
<span class="item"><img src="images/1-t7.png" alt=""></span>
<span class="item"><img src="images/1-t8.png" alt=""></span>
<span class="item"><img src="images/1-t9.png" alt=""></span>
<span class="item"><img src="images/1-t10.png" alt=""></span>
</div>
<script>
  let flags = Array.from(strand.querySelectorAll('.flag'));
  flags.forEach((flag, i) => {
    flag.style.offsetDistance = `${80 + i * 740 / flags.length}px`;
  });
</script>

 

Transform

兼容性可以,成本也很低,无法在客户端直接转化图片,位置,半径不太好精确控制,实现如下:

<style>
#list {
  height: 500px;
  width: 500px;
  position: relative;
  margin:0;padding: 0;
}
.list-item {
  list-style: none;
  height: 56px;
  width: 56px;
  position: absolute;
  top: 50%;
  left: 50%;
}
.canvas{width: 500px;height: 500px;position:absolute; top:0;left:1000px;}
</style>
<div class="canvas">
  <ul id="list"></ul>
  <button id="add-item">Add item</button>
</div>
<script>
  var list = $("#list"),
  start = 180;
  var updateLayout = function(listItems) {
    for (var i = 0; i < listItems.length; i++) {
      var offsetAngle = 360 / listItems.length;
      var rotateAngle = offsetAngle * i + start-listItems.length*offsetAngle/2;
      $(listItems[i]).css({"transform": "rotate(" + rotateAngle + "deg) translate(0, -200px)"})
    };
  };

  $(document).on("click", "#add-item", function() {
    var listItem = $("<li class='list-item'><img src='images/1-t1.png' alt=''><button class='remove-item'>Remove</button></li>");
    list.append(listItem);
    var listItems = $(".list-item");
    updateLayout(listItems);

  });

  $(document).on("click", ".remove-item", function() {
    $(this).parent().remove();
    var listItems = $(".list-item");
    updateLayout(listItems);
  });
</script>

 

 绝对定位+rotate

兼容性可以,实现成本比较高,无法在客户端直接转化图片,位置,半径能精确控制,实现如下:

<style>
.hangItem{width: 56px;position: absolute;-webkit-transition: all 1s;}
.canvas{width:500px;height:500px;position:relative;}
</style>
<div class="canvas">
  <div id="box">
    <div class="hangItem empty">
      <img src="images/empty.png" alt="">
    </div>
    <div class="hangItem">
      <img src="images/1-t1.png" alt="">
    </div>
    <div class="hangItem">
      <img src="images/1-t2.png" alt="">
    </div>
    <div class="hangItem">
      <img src="images/1-t3.png" alt="">
    </div>
    <div class="hangItem">
      <img src="images/1-t4.png" alt="">
    </div>
    <div class="hangItem">
      <img src="images/1-t5.png" alt="">
    </div>
    <div class="hangItem">
      <img src="images/1-t5a.png" alt="">
    </div>
    <div class="hangItem">
      <img src="images/1-t5b.png" alt="">
    </div>

  </div>
</div>
<script>
  var circle = document.getElementById('box'),
  imgs = $('.hangItem'),
  total = imgs.length,
  coords = {},
  diam,radius1,radius2,imgW;


  diam = parseInt(window.getComputedStyle(circle).getPropertyValue('width')),
  radius = diam / 2,
  imgW = imgs[0].getBoundingClientRect().width,

  radius2 = radius - imgW;

  var i,
  alpha = Math.PI / 2,
  len = imgs.length,
  corner = 2 * Math.PI / total;
  var offsetAngle = 360 / len,
  start = 180;

  for (i = 0; i < total; i++) {

    imgs[i].style.left = parseInt(radius - imgW / 2 + radius2 * Math.cos(alpha)) + 'px';
    imgs[i].style.top = parseInt(radius - imgW / 2 - radius2 * Math.sin(alpha)) + 'px';
    var rotateAngle = offsetAngle * i + len*offsetAngle/2;
    $(imgs[i]).css("transform", "rotate(" + rotateAngle + "deg)");//console.log(rotateAngle);
    alpha = alpha - corner;
  }

</script>

Canvas

兼容性可以,实现成本比较高,可以在客户端直接转化图片,位置,半径好精确控制,实现如下:

<canvas id="cvs2"  width="440" height="440" style="position:absolute;z-index:10;top:38px;left:26px;display: block;">
      Your browser not support canvas!
</canvas>
<script>
  var cvs2 = document.getElementById("cvs2");
  var items = [
    "images/empty.png",
    "images/1-t5.png",
    "images/1-t11.png",
    "images/1-t5.png",
    "images/1-t10.png",
    "images/1-t1.png",
  ];

  
  function rendItem(ctx,items,radius,itemWidth){
    if(items<1) return;
    var total = items.length,
      radius2 = radius - itemWidth;
    var i,
        alpha = Math.PI / 2,
       corner = 2 * Math.PI / total;
    var offsetAngle = 360 / total;

    for (i = 0; i < total; i++) {
      var itemObj = new Image();

      itemObj.src = items[i];
      
      itemObj.onload = function(){
        var itemLeft = parseInt(radius - itemWidth / 2 + radius2 * Math.cos(alpha)),
        itemTop = parseInt(radius - itemWidth / 2 - radius2 * Math.sin(alpha)),
        rotateAngle = (offsetAngle * this.index + total*offsetAngle/2) * Math.PI / 180;//offsetAngle * this.index + total*offsetAngle/2;
        ctx.save();
        ctx.translate(itemLeft + this.width / 2, itemTop+ this.height / 2);
        ctx.rotate(rotateAngle);                      
        ctx.drawImage(this, 0, 0,this.width,this.height,-.5*this.width,-.5*this.height,this.width,this.height);
        ctx.translate(-(itemLeft + this.width / 2), -(itemTop+ this.height / 2));
        ctx.restore();
        alpha = alpha - corner;
      }
      itemObj.index = i;

    }  

  }
  rendItem(ctx2,items,220,56);
</script>

最后综合选了canvas省事点,但是以上这些实现都有一个问题,就是参与排列的图片如果高度不一样,就蛋疼了无法控制按基线对齐分布,全部都是居中的,暂时还没彻底习惯canvas里面的坐标体系,暂时搁置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值