8

我尝试编写一个小插件,以更有机的方式打开模态框,因此我决定为 clip-path 属性设置动画。

现在此代码仅适用于 chrome: http ://codepen.io/meodai/pen/GgGzYo?editors=011

看起来firefox 不支持 polygon()clip-path 属性。Safari 和移动 Safari 也确实在为此苦苦挣扎。

是否有类似的简单方法可以在 Firefox 和 Safari 以及 Mobile Safari 中进行这项工作?知道如何解决这个问题吗?

这是一个工作示例:

var $ov = $('.overlay');

$(document).on('click touchstart', '.inner', function(){
  var coords, coordArray, coordsString;

  coords = this.getBoundingClientRect();

  coordArray = [
    Math.floor(parseInt(coords.left)) + 'px ' + Math.floor(parseInt(coords.top)) + 'px',
    Math.ceil((parseInt(coords.left) + parseInt(coords.width))) + 'px ' + Math.ceil(parseInt(coords.top)) + 'px',
    Math.ceil((parseInt(coords.left) + parseInt(coords.width))) + 'px ' + Math.ceil((parseInt(coords.top) + parseInt(coords.height) )) + 'px',
    Math.ceil(parseInt(coords.left)) + 'px ' + Math.floor((parseInt(coords.top) + parseInt(coords.height) )) + 'px'
  ];


  coordsString = 'polygon(' + coordArray[0] + ',' + coordArray[1] + ',' + coordArray[2] + ',' + coordArray[3] + ')';

  $ov.css({
    '-webkit-clip-path': coordsString,
    'clip-path': coordsString
  });

  setTimeout(function(){
    $ov.addClass('show');
  },50);

  setTimeout(function(){
    coordsString = 'polygon(0% 0%,' + coordArray[1] + ',' + coordArray[2] + ',' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,
        'clip-path': coordsString
    });
  },100);
  setTimeout(function(){
    coordsString = 'polygon(0% 0%,100% 0%,' + coordArray[2] + ',' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,
        'clip-path': coordsString
    });
  },180);
  setTimeout(function(){
    coordsString = 'polygon(0% 0%,100% 0%,100% 100%,' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,
        'clip-path': coordsString
    });
  },260);

  setTimeout(function(){
    coordsString = 'polygon(0% 0%,100% 0%,100% 100%,0 100%)';
    $ov.css({
      '-webkit-clip-path': coordsString,
        'clip-path': coordsString
    });
  },340);

  // reverse
  setTimeout(function(){
    coordsString = 'polygon(0% 0%,100% 0%,100% 100%,' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,
        'clip-path': coordsString
    });
  },1500);

  setTimeout(function(){
    coordsString = 'polygon(0% 0%,100% 0%,' + coordArray[2] + ',' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,
        'clip-path': coordsString
    });
  },1580);
  setTimeout(function(){
    coordsString = 'polygon(0% 0%,' + coordArray[1] + ',' + coordArray[2] + ',' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,
        'clip-path': coordsString
    });
  },1640);
  setTimeout(function(){
    coordsString = 'polygon(' + coordArray[0] + ',' + coordArray[1] + ',' + coordArray[2] + ',' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,
        'clip-path': coordsString
    });
  },1740);



   setTimeout(function(){
    $ov.removeClass('show');
  },2000);

});
body, html {
  background: silver;
}

.grid {
  float: left;
  width: 25%;
  height: 25vw;
  box-shizing: border-box;
  position: relative;
}

.inner {
  position: absolute;
  top: 10px;
  left: 10px;
  bottom: 10px;
  right: 10px;
  background: #ddd;
  -webkit-transition: background-color 111ms;
          transition: background-color 111ms;
}
.inner:hover {
  background: #fff;
}

.overlay {
  opacity: 0;
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: #fff;
  pointer-events: none;
  box-sizing: border-box;
  padding: 20px;
}

.overlay.show {
  opacity: 1;
  will-change: clip-path;
  -webkit-transition: clip-path 200ms;
          transition: clip-path 200ms;
  -webkit-transition: -webkit-clip-path 200ms;
          transition: -webkit-clip-path 200ms;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="grid">
  <div class="inner"></div>
</div>
<div class="overlay"></div>
4

4 回答 4

10

您可能想查看 svgs,因为您可以为多边形的点设置动画并将其变形为所需的形状。

演示

带图像和标题的演示

这个演示使用snap.svg库来制作正方形并在点击事件上操作它们。
它目前还没有完成,并且有一些错误,但你应该明白了

我完全重构了代码,感谢rlemon帮助我让它变得更好。我在最新的 FF 和 Chrome 中对其进行了测试,一位用户报告说它可以在带有 safari 的 iphone 上运行。

这些项目是用多边形制成的,单击时会添加一个方形多边形,并且它的点会被一一动画化以成为特色。

var items = [
  [ 1, 1,24, 1,24,24, 1,24],
  [26, 1,49, 1,49,24,26,24],
  [51, 1,74, 1,74,24,51,24],
  [76, 1,99, 1,99,24,76,24],
  [ 1, 26,24, 26,24,49, 1,49],
  [26, 26,49, 26,49,49,26,49],
  [51, 26,74, 26,74,49,51,49],
  [76, 26,99, 26,99,49,76,49],
  [ 1, 51,24, 51,24,74, 1,74],
  [26, 51,49, 51,49,74,26,74],
  [51, 51,74, 51,74,74,51,74],
  [76, 51,99, 51,99,74,76,74],
  [ 1, 76,24, 76,24,99, 1,99],
  [26, 76,49, 76,49,99,26,99],
  [51, 76,74, 76,74,99,51,99],
  [76, 76,99, 76,99,99,76,99]
],
    item = [],points= [],i, p=[],open = 0,
    s = Snap().attr({viewBox:"0 0 100 100","fill":"#585247"});

function runAnimations(el) {
  if( !animationSequences.length ) return;
  var sequence = animationSequences.shift();
  el.animate(sequence,120,mina.linear, runAnimations.bind(null,el));
}


function register(x,i) {
  item[i] = s.polygon(items[i]);  
  item[i].click(function () {
    var featured = s.polygon(items[i]).attr({"fill":"#585247"});
    p = items[i];
    animationSequences = [
      {"points": p[0]/2+","+p[1]/2+","+p[2]+","+p[3]+","+p[4]+","+p[5]+","+p[6]+","+p[7]},
      {"points": p[0]/3+","+p[1]/3+",100,0,100,100,"+p[6]+","+p[7]},
      {"points": p[0]/4+","+p[1]/4+",100,0,100,100,0,100"},
      {"points": "0,0,100,0,100,100,0,100"},
    ];
    runAnimations(featured);
    featured.animate({"fill":"#ACA696"},300);
    featured.click(function(){
      this.stop().animate({"points":p,"fill":"#585247"},200,mina.linear,featured.remove);
    });
  });
}
items.forEach(register);
*{margin:0;padding:0;}
body{background:#E3DFD2;}
svg{display:block;}
<script src="http://thisisa.simple-url.com/js/snapsvg.js"></script>

于 2015-03-25T18:02:53.697 回答
7

Clip-path 仅支持点值的数字,看起来您正在使用百分比/像素比例,这就是它在 Firefox 中失败的原因。

更改为整数值:

coordsString = 'polygon(0 0,123 0,' + coordArray[2] + ',' + coordArray[3] + ')';
$ov.css({
  '-webkit-clip-path': coordsString,
    'clip-path': coordsString
});

您将需要从 coordArray 中删除像素引用并根据百分比计算实际的 int 值。

于 2015-03-25T15:55:25.343 回答
3

我遇到了这个问题,我的剪辑元素在 iPhoneX 上没有显示为剪辑。

添加 webkit 为我解决了这个问题:

clip-path: polygon(0 0, 0% 100%, 100% 0); -webkit-clip-path: polygon(0 0, 0% 100%, 100% 0);

于 2018-07-12T06:11:59.707 回答
0

我已经测试了很多可能性,但根据http://caniuse.com/#search=polygon FF(!)不支持多边形。我尝试了很多可能性,但每次 FF 开发工具都告诉我这不是一个正确的值。

我测试过的代码(来自你的codepen):

var $ov = $('.overlay');

$(document).on('click touchstart', '.inner', function(){
  var coords, coordArray, coordsString;
  var windowWidth = window.innerWidth + "";
  coords = this.getBoundingClientRect();

  coordArray = [
    Math.floor(parseInt(coords.left)) + ' ' + Math.floor(parseInt(coords.top)) + '',
    Math.ceil((parseInt(coords.left) + parseInt(coords.width))) + ' ' + Math.ceil(parseInt(coords.top)) + '',
    Math.ceil((parseInt(coords.left) + parseInt(coords.width))) + ' ' + Math.ceil((parseInt(coords.top) + parseInt(coords.height) )) + '',
    Math.ceil(parseInt(coords.left)) + ' ' + Math.floor((parseInt(coords.top) + parseInt(coords.height) )) + ''
  ];


  coordsString = 'polygon(' + coordArray[0] + ',' + coordArray[1] + ',' + coordArray[2] + ',' + coordArray[3] + ')';

  $ov.css({
    '-webkit-clip-path': coordsString,

    'clip-path': coordsString
  });

  setTimeout(function(){
    $ov.addClass('show');
  },50);

  setTimeout(function(){
    coordsString = 'polygon(0 0,' + coordArray[1] + ',' + coordArray[2] + ',' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,

      'clip-path': coordsString
    });
  },100);
  setTimeout(function(){
    coordsString = 'polygon(0 0 ,'+windowWidth+' 0,' + coordArray[2] + ',' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,

      'clip-path': coordsString
    });
  },180);
  setTimeout(function(){
    coordsString = 'polygon(0 0,'+windowWidth+' 0,'+windowWidth+' '+windowWidth+',' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,

      'clip-path': coordsString
    });
  },260);

  setTimeout(function(){
    coordsString = 'polygon(0 0,'+windowWidth+' 0,'+windowWidth+' '+windowWidth+',0 '+windowWidth+')';
    $ov.css({
      '-webkit-clip-path': coordsString,

      'clip-path': coordsString
    });
  },340);

  // reverse
  setTimeout(function(){
    coordsString = 'polygon(0 0,'+windowWidth+' 0,'+windowWidth+' '+windowWidth+',' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,

      'clip-path': coordsString
    });
  },1500);

  setTimeout(function(){
    coordsString = 'polygon(0 0,'+windowWidth+' 0,' + coordArray[2] + ',' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,

      'clip-path': coordsString
    });
  },1580);
  setTimeout(function(){
    coordsString = 'polygon(0 0,' + coordArray[1] + ',' + coordArray[2] + ',' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,

      'clip-path': coordsString
    });
  },1640);
  setTimeout(function(){
    coordsString = 'polygon(' + coordArray[0] + ',' + coordArray[1] + ',' + coordArray[2] + ',' + coordArray[3] + ')';
    $ov.css({
      '-webkit-clip-path': coordsString,

      'clip-path': coordsString
    });
  },1740);



   setTimeout(function(){
    $ov.removeClass('show');
  },2000);

});
于 2015-03-30T14:07:22.790 回答