如何用随机锯齿获得撕裂的纸张效果?

Aks*_*hay 44 html css svg css3 css-shapes

我试图制作撕碎的纸张效果,如下图所示:

在此输入图像描述

底部撕裂的效果.我看到了这个并且能够产生撕裂的纸张效果,如下所示

.box {
  width: 300px;
  height: 150px;
  background: darkred;
  position: relative;
  display: inline-block;
}
.box:after {
  position: absolute;
  content: "";
  width: 15px;
  height: 15px;
  transform: rotate(45deg);
  transform-origin: 0% 100%;
  background: darkred;
  left: 0;
  bottom: 0;
  box-shadow: 15px -15px 0 0 darkred, 30px -30px 0 0 darkred, 45px -45px 0 0 darkred, 60px -60px 0 0 darkred, 75px -75px 0 0 darkred, 90px -90px 0 0 darkred, 105px -105px 0 0 darkred, 120px -120px 0 0 darkred, 135px -135px 0 0 darkred, 150px -150px 0 0 darkred, 165px -165px 0 0 darkred, 180px -180px 0 0 darkred, 195px -195px 0 0 darkred;
}
Run Code Online (Sandbox Code Playgroud)
<div class="box"></div>
Run Code Online (Sandbox Code Playgroud)

但问题是撕裂的边缘看起来很相似.我希望它们具有不同的尺寸和不同的形状.

Aks*_*hay 48

这可以使用svg来完成.我正在使用Snap和jquery来制作它,因为它使一切变得更容易.

以下片段会产生随机撕裂的纸张效果.

注意:支持快照 - IE9及更高版本,Safari,Chrome,Firefox和Opera 查看规格

支持svg caniuse

$(document).ready(function() {
  var s = Snap('svg');
  var width = $('.content').outerWidth();
  $('.effect').width(width);
  var lastX = 0;
  var pointsArray = [0, 0];
  while (lastX <= width) {
    var randX = Math.floor(Math.random() * 25);
    var randY = Math.floor(Math.random() * 30);
    pointsArray.push(randX + lastX + ' ' + randY);
    lastX = lastX + randX;
  }
  var torn = s.polygon(pointsArray + " " + width + " 0").attr({
    fill: 'orange'
  })
})
Run Code Online (Sandbox Code Playgroud)
.content {
  width: 400px;
  height: 400px;
  background: orange;
  padding: 20px;
}
.effect {
  height: 50px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div class="torn">
  <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
  <div class="effect">
    <svg width="100%" height="100%"></svg>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

这是怎么回事?

首先创建一个数组来保存jquery随机创建的坐标.使用Math.random()和创建x和y坐标并将其添加到数组中.在添加到数组之前,将当前x坐标添加到接收的最后一个x坐标.这是为了使它连续.

改变10randX可变允许我们以增加或减少一个线的长度并改变30randY可变允许改变一个线的高度.

这是一个使用low的片段 randX

$(document).ready(function() {
  var s = Snap('svg');
  var width = $('.content').outerWidth();
  $('.effect').width(width);
  var lastX = 0;
  var lastY = 0;
  var pointsArray = [0, 0];
  while (lastX <= width) {
    var randX = Math.floor(Math.random() * 2);
    var randY = Math.floor(Math.random() * 30);
    pointsArray.push(randX + lastX + ' ' + randY);
    lastX = lastX + randX;
  }
  var torn = s.polygon(pointsArray + " " + width + " 0").attr({
    fill: 'orange'
  })
})
Run Code Online (Sandbox Code Playgroud)
.content {
  width: 400px;
  height: 400px;
  background: orange;
  padding: 20px;
}
.effect {
  height: 50px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div class="torn">
  <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
  <div class="effect">
    <svg width="100%" height="100%"></svg>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

想有一个带边框?

更改polygonpolyline并添加stroke

$(document).ready(function() {
  var s = Snap('svg');
  var width = $('.content').outerWidth();
  $('.effect').width(width);
  var lastX = 0;
  var lastY = 0;
  var pointsArray = [0, 0];
  while (lastX <= width) {
    var randX = Math.floor(Math.random() * 20);
    var randY = Math.floor(Math.random() * 30);
    pointsArray.push(randX + lastX + ' ' + randY);
    lastX = lastX + randX;
  }
  var torn = s.polyline(pointsArray + " " + (width - 3) + " 0").attr({
    fill: 'orange',
    'stroke': 'black',
    'stroke-width': 3
  })
})
Run Code Online (Sandbox Code Playgroud)
.torn {
  margin: 50px;
}
.content {
  width: 400px;
  height: 400px;
  background: orange;
  padding: 20px;
  border: 3px solid #000;
  border-bottom: 0;
}
.effect {
  height: 50px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div class="torn">
  <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
  <div class="effect">
    <svg width="100%" height="100%"></svg>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

不喜欢随机撕裂的效果?

我建议从随机的那些中挑选一个很好的撕裂效果并像我在这里一样复制它的html

.torn {
  margin: 50px;
}
.content {
  width: 400px;
  height: 400px;
  background: orange;
  padding: 20px;
}
.effect {
  height: 50px;
}
Run Code Online (Sandbox Code Playgroud)
<div class="torn">
  <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
  <div class="effect" style="width: 440px;">
    <svg width="100%" height="100%">
      <desc>Created with Snap</desc>
      <defs></defs>
      <polygon points="0,0,10 25,20 15,27 21,43 24,51 14,70 9,84 25,88 18,96 11,100 20,113 6,117 5,123 1,136 25,151 29,157 4,166 29,181 2,197 28,212 8,226 8,232 12,240 8,254 16,270 5,279 26,291 5,304 0,307 5,325 26,329 18,347 3,360 5,372 26,382 9,393 21,406 27,411 8,415 4,429 8,441 19 437 0"
      fill="#ffa500"></polygon>
    </svg>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

需要背景图片?

使用snap添加图像,将其y坐标设置为-440(即,如果避免填充,则将内容的高度设置为400.)并使用多边形将其剪切

$(document).ready(function() {
  var s = Snap('svg');
  var width = $('.content').outerWidth();
  $('.effect').width(width);
  var lastX = 0;
  var lastY = 0;
  var pointsArray = [0, 0];
  while (lastX <= width) {
    var randX = Math.floor(Math.random() * 20);
    var randY = Math.floor(Math.random() * 30);
    pointsArray.push(randX + lastX + ' ' + randY);
    lastX = lastX + randX;
  }
  var img = s.image('https://placeimg.com/440/500/any', 0, -440, 440, 500)
  var torn = s.polygon(pointsArray + " " + (width - 3) + " 0").attr({

  })
  img.attr({
    'clip-path': torn
  })
})
Run Code Online (Sandbox Code Playgroud)
.torn {
  margin: 50px;
}
.content {
  width: 400px;
  height: 400px;
  background: orange;
  padding: 20px;
  background: url('https://placeimg.com/440/500/any');
}
.effect {
  height: 50px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div class="torn">
  <div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
  <div class="effect">
    <svg width="100%" height="100%"></svg>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

  • @machineyearning:我肯定会同意Akshay的答案看起来好多了,但只是为了让你知道我答案中的前3个片段有固定点,这是任意添加的.当阵列生成逻辑调整为与Akshay完全相同时,最后一个将产生Akshay答案中的确切输出.这只是阵列生成的问题. (2认同)

Har*_*rry 40

使用剪辑路径:

撕裂的纸张效果也可以使用clip-path它只能用HTML和CSS完成,但纯CSS版本不会像我们使用SNAP或其他SVG库那样产生随机剪辑效果,但它确实会产生撕裂的纸张效果.

使用CSS 的缺点clip-path是它目前仅在Webkit驱动的浏览器中受支持.Firefox仅支持url()语法,因此需要内联SVG,而IE完全不支持.[ 我可以使用 ]

.torn-paper{
  height: 300px;
  width: 400px;
  background: tomato;
  -webkit-clip-path: polygon(0% 0%, 0% 97%, 2% 95%, 6% 99%, 12% 88%, 18% 92%, 27% 90%, 31% 97%, 39% 91%, 47% 95%, 60% 83%, 62% 81%, 69% 93%, 72% 96%, 79% 87%, 100% 99%, 100% 0%);
  clip-path: polygon(0% 0%, 0% 97%, 2% 95%, 6% 99%, 12% 88%, 18% 92%, 27% 90%, 31% 97%, 39% 91%, 47% 95%, 60% 83%, 62% 81%, 69% 93%, 72% 96%, 79% 87%, 100% 99%, 100% 0%);  
}
Run Code Online (Sandbox Code Playgroud)
<div class='torn-paper'>Lorem ipsum dolor sit amet</div>
Run Code Online (Sandbox Code Playgroud)

由于clip-path是基于百分比,它默认是响应的,它也可以在容器div具有背景图像时工作.

.torn-paper{
  height: 300px;
  width: 400px;
  background: url(http://lorempixel.com/400/300);
  -webkit-clip-path: polygon(0% 0%, 0% 97%, 2% 95%, 6% 99%, 12% 88%, 18% 92%, 27% 90%, 31% 97%, 39% 91%, 47% 95%, 60% 83%, 62% 81%, 69% 93%, 72% 96%, 79% 87%, 100% 99%, 100% 0%);
  clip-path: polygon(0% 0%, 0% 97%, 2% 95%, 6% 99%, 12% 88%, 18% 92%, 27% 90%, 31% 97%, 39% 91%, 47% 95%, 60% 83%, 62% 81%, 69% 93%, 72% 96%, 79% 87%, 100% 99%, 100% 0%);  
}
Run Code Online (Sandbox Code Playgroud)
<div class='torn-paper'>Lorem ipsum dolor sit amet</div>
Run Code Online (Sandbox Code Playgroud)

如果我们真的想要一个随机撕裂的纸张效果,那么我们可以polygon使用JS 设置剪辑路径的坐标,然后将其添加为内联样式,如下面的代码段所示.该代码段使用与您的答案中类似的逻辑来填充数组.

var el = document.getElementsByClassName('torn-paper')[0];

var lastX = 0,
  randX, randY, polygonPoints = ["0% 0%"];

randY = Math.floor(Math.random() * 20) + 80;

polygonPoints.push(lastX + '% ' + randY + '%');

while (lastX <= 100) {
  randX = Math.floor(Math.random() * 5);
  randY = Math.floor(Math.random() * 10) + 85;
  polygonPoints.push(randX + lastX + '% ' + randY + '%');
  lastX = lastX + randX;
}
polygonPoints.push("100% 0%");

el.style['-webkit-clip-path'] = 'polygon(' + polygonPoints.join() + ')';
el.style['clip-path'] = 'polygon(' + polygonPoints.join() + ')';
Run Code Online (Sandbox Code Playgroud)
.torn-paper {
  height: 300px;
  width: 400px;
  background: tomato;
}
Run Code Online (Sandbox Code Playgroud)
0
<div class='torn-paper'>Lorem ipsum dolor sit amet</div>
Run Code Online (Sandbox Code Playgroud)

我没有将以下内容作为我的主要答案,因为在Akshay的答案中已经以不同的方式介绍了SVG,但是使用内联SVG clip-path 也可以在Firefox中使用.IE仍然不支持它.

var el = document.getElementsByClassName('torn-paper')[0];
var path = document.getElementById('clipper-path');

var lastX = 0,
  randX, randY, polygonPoints = ["0 0"];

randY = (Math.floor(Math.random() * 20) + 80) / 100;

polygonPoints.push(lastX + ' ' + randY + '');

while (lastX <= 1) {
  randX = Math.floor(Math.random() * 5) / 100;
  randY = (Math.floor(Math.random() * 10) + 85) / 100;
  polygonPoints.push(randX + lastX + ' ' + randY + '');
  lastX = lastX + randX;
}
polygonPoints.push("1 0");

path.setAttribute('d', 'M' + polygonPoints.join() + 'z');
Run Code Online (Sandbox Code Playgroud)
.torn-paper {
  height: 300px;
  width: 400px;
  background: tomato;
  -webkit-clip-path: url(#clipper);
  clip-path: url(#clipper);
}
Run Code Online (Sandbox Code Playgroud)
<svg width="0" height="0">
  <defs>
    <clipPath id="clipper" clipPathUnits="objectBoundingBox">
      <path d='M0 0, 1 0, 1 1, 0 1z' id='clipper-path' />
    </clipPath>
  </defs>
</svg>
<div class="torn-paper">Lorem ipsum dolor sit amet</div>
Run Code Online (Sandbox Code Playgroud)


使用Canvas:

我知道你没有标记Canvas,但如果你在IE中寻找支持,那么使用Canvas也是一个不错的选择.Canvas具有非常好的浏览器支持(与SVG相同).我把它包括在这里作为另一种可以使用的选项.

该方法与前面解释的方法非常相似,因为这里我们还创建了一个路径,然后根据路径剪切画布.

以下代码段在IE9 +,Edge,Firefox,Chrome,Safari和Opera中进行了测试.

var canvas = document.getElementById('torn-canvas');
var ctx = canvas.getContext('2d');
var lastX = 0,
  randX, randY;

ctx.save();
ctx.beginPath();
ctx.moveTo(0, 0);

randY = (Math.floor(Math.random() * 10) + 85) / 100 * canvas.height;
ctx.lineTo(0, randY);

while (lastX <= canvas.width) {
  randX = (Math.floor(Math.random() * 7.5)) / 100 * canvas.width;
  randY = (Math.floor(Math.random() * 10) + 85) / 100 * canvas.height;
  lastX = lastX + randX;
  ctx.lineTo(lastX, randY);
}
ctx.lineTo(canvas.width, 0);
ctx.closePath();
ctx.clip();
ctx.beginPath();
ctx.fillStyle = 'tomato';
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.fill();
ctx.restore();
Run Code Online (Sandbox Code Playgroud)
.container {
  position: relative;
  height: 300px;
  width: 400px;
}
#torn-canvas {
  position: absolute;
  z-index: -1;
}
Run Code Online (Sandbox Code Playgroud)
<div class='container'>
  <canvas id='torn-canvas' height='300px' width='300px'></canvas>Lorem ipsum dolor sit amet...</div>
Run Code Online (Sandbox Code Playgroud)

我们甚至可以通过首先将图像绘制到Canvas上然后将其剪切为形状来添加图像作为背景.

var canvas = document.getElementById('torn-canvas');
var ctx = canvas.getContext('2d');
var lastX = 0,
  randX, randY, img = new Image();

ctx.save();
img.src = 'http://lorempixel.com/400/300/nature/4';
img.onload = function() {
  ctx.drawImage(img, 0, 0);
}
ctx.restore();
ctx.beginPath();
ctx.moveTo(0, 0);

randY = (Math.floor(Math.random() * 10) + 85) / 100 * canvas.height;
ctx.lineTo(0, randY);

while (lastX <= canvas.width) {
  randX = (Math.floor(Math.random() * 5)) / 100 * canvas.width;
  randY = (Math.floor(Math.random() * 10) + 85) / 100 * canvas.height;
  lastX = lastX + randX;
  ctx.lineTo(lastX, randY);
}
ctx.lineTo(canvas.width, 0);
ctx.closePath();
ctx.clip();
ctx.beginPath();
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.restore();
Run Code Online (Sandbox Code Playgroud)
.container {
  position: relative;
  height: 300px;
  width: 400px;
  color: white;
}
#torn-canvas {
  position: absolute;
  z-index: -1;
}
Run Code Online (Sandbox Code Playgroud)
<div class='container'>
  <canvas id='torn-canvas' height='300px' width='300px'></canvas>Lorem ipsum dolor sit amet...</div>
Run Code Online (Sandbox Code Playgroud)

  • 可能被低估了,因为它不像其他答案那样便携. (3认同)
  • 那么另一个适用于IE和Firefox.添加答案没有错,只是因为它不起作用而被贬低就不会变咸. (3认同)
  • 我已经添加了一个适用于Firefox的版本.我并没有变咸,但我发现人们只是因为技术现在没有得到普遍支持而得到答复,这是荒谬的.我可以理解,如果你(不完全是你)选择不投票,而是选择一个回答问题的答案,该问题表明没有任何浏览器限制是完全荒谬的. (3认同)

小智 5

我确信这篇文章可能已经死了,但我会在这里留下这条评论,以防有人觉得它有帮助。我使用以下 CSS 创建了锯齿状效果:

clip-path: polygon(3% 0, 7% 1%, 11% 0%, 16% 2%, 20% 0, 23% 2%, 28% 2%, 32% 1%, 35% 1%, 39% 3%, 41% 1%, 45% 0%, 47% 2%, 50% 2%, 53% 0, 58% 2%, 60% 2%, 63% 1%, 65% 0%, 67% 2%, 69% 2%, 73% 1%, 76% 1%, 79% 0, 82% 1%, 85% 0, 87% 1%, 89% 0, 92% 1%, 96% 0, 98% 3%, 99% 3%, 99% 6%, 100% 11%, 98% 15%, 100% 21%, 99% 28%, 100% 32%, 99% 35%, 99% 40%, 100% 43%, 99% 48%, 100% 53%, 100% 57%, 99% 60%, 100% 64%, 100% 68%, 99% 72%, 100% 75%, 100% 79%, 99% 83%, 100% 86%, 100% 90%, 99% 94%, 99% 98%, 95% 99%, 92% 99%, 89% 100%, 86% 99%, 83% 100%, 77% 99%, 72% 100%, 66% 98%, 62% 100%, 59% 99%, 54% 99%, 49% 100%, 46% 98%, 43% 100%, 40% 98%, 38% 100%, 35% 99%, 31% 100%, 28% 99%, 25% 99%, 22% 100%, 19% 99%, 16% 100%, 13% 99%, 10% 99%, 7% 100%, 4% 99%, 2% 97%, 1% 97%, 0% 94%, 1% 89%, 0% 84%, 1% 81%, 0 76%, 0 71%, 1% 66%, 0% 64%, 0% 61%, 0% 59%, 1% 54%, 0% 49%, 1% 45%, 0% 40%, 1% 37%, 0% 34%, 1% 29%, 0% 23%, 2% 20%, 1% 17%, 1% 13%, 0 10%, 1% 6%, 1% 3%);
Run Code Online (Sandbox Code Playgroud)

现在,我确信这可以进一步细化以提供更令人信服的外观,但我认为这是为图像区域提供粗略形状的好方法。