web-dev-qa-db-ja.com

ランダムのこぎり歯で破れた紙の効果を得るには?

下の画像のような破れた紙の効果を作ろうとしています。

enter image description here

底面に破れた効果があります。 これを見たそして、以下に示すように破れた紙の効果を作ることができた

.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;
}
<div class="box"></div>

しかし、問題は、引き裂かれたエッジが似ていることです。さまざまな形でさまざまなサイズにする必要があります。

43
Akshay

これは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'
  })
})_
_.content {
  width: 400px;
  height: 400px;
  background: orange;
  padding: 20px;
}
.effect {
  height: 50px;
}_
_<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>_

これはどのように機能しますか?

最初に、jqueryによってランダムに作成された座標を保持する配列が作成されます。 xおよびy座標はMath.random()を使用して作成され、配列に追加されます。配列に追加する前に、現在のx座標が最後に受信したx座標に追加されます。これは、それを連続させることです。

randX変数の_10_を変更すると、1行の長さを増減でき、randY変数の_30_を変更すると、 1行。

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'
  })
})_
_.content {
  width: 400px;
  height: 400px;
  background: orange;
  padding: 20px;
}
.effect {
  height: 50px;
}_
_<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>_

ボーダー付きのものが欲しいですか?

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
  })
})_
_.torn {
  margin: 50px;
}
.content {
  width: 400px;
  height: 400px;
  background: orange;
  padding: 20px;
  border: 3px solid #000;
  border-bottom: 0;
}
.effect {
  height: 50px;
}_
_<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>_

ランダムな破れた効果が好きではありませんか?

ここでやったように、ランダムなものからニースの破れた効果を選び、そのhtmlをコピーすることをお勧めします

_.torn {
  margin: 50px;
}
.content {
  width: 400px;
  height: 400px;
  background: orange;
  padding: 20px;
}
.effect {
  height: 50px;
}_
_<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>_

背景画像が必要ですか?

スナップを使用して画像を追加し、y座標を-440(つまり、パディングが回避される場合はcontent.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
  })
})_
_.torn {
  margin: 50px;
}
.content {
  width: 400px;
  height: 400px;
  background: orange;
  padding: 20px;
  background: url('https://placeimg.com/440/500/any');
}
.effect {
  height: 50px;
}_
_<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>_
47
Akshay

クリップパスの使用:

破れた紙の効果は_clip-path_を使用しても生成できます。HTMLとCSSのみで実行できますが、純粋なCSSバージョンではSNAPを使用して達成できるようなランダムなクリップ効果は生成されませんまたは他のSVGライブラリですが、破れた紙のような効果があります。

CSS _clip-path_を使用する場合のdrawbackは、Webkitを搭載したブラウザでのみ現在サポートされていることです。 Firefoxはurl()構文のみをサポートしているため、IEではまったくサポートされていませんが、インラインSVGが必要です。 [ 使用できます ]

_.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%);  
}_
_<div class='torn-paper'>Lorem ipsum dolor sit amet</div>_

_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%);  
}_
_<div class='torn-paper'>Lorem ipsum dolor sit amet</div>_

破れた紙のランダム効果が本当に必要な場合は、JSを使用してpolygonクリップパスの座標を設定し、以下のスニペットのようにインラインスタイルとして追加できます。このスニペットは、回答のロジックと同様のロジックを使用して、配列にデータを取り込みます。

_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() + ')';_
_.torn-paper {
  height: 300px;
  width: 400px;
  background: tomato;
}_
_0
<div class='torn-paper'>Lorem ipsum dolor sit amet</div>_

Akshayの回答ではSVGがすでに別の方法で説明されていましたが、clip-path_にインラインSVGを使用すると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');_
_.torn-paper {
  height: 300px;
  width: 400px;
  background: tomato;
  -webkit-clip-path: url(#clipper);
  clip-path: url(#clipper);
}_
_<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>_

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();_
_.container {
  position: relative;
  height: 300px;
  width: 400px;
}
#torn-canvas {
  position: absolute;
  z-index: -1;
}_
_<div class='container'>
  <canvas id='torn-canvas' height='300px' width='300px'></canvas>Lorem ipsum dolor sit amet...</div>_

最初に画像をキャンバスに描画し、それを切り取って形にすることで、背景として画像を追加することもできます。

_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();_
_.container {
  position: relative;
  height: 300px;
  width: 400px;
  color: white;
}
#torn-canvas {
  position: absolute;
  z-index: -1;
}_
_<div class='container'>
  <canvas id='torn-canvas' height='300px' width='300px'></canvas>Lorem ipsum dolor sit amet...</div>_
40
Harry

この投稿はおそらく死んでいると思いますが、だれかが役に立つと思われる場合に備えて、このコメントをここに残しています。次の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%);

今、私はこれがさらに説得力のある外観を与えるためにさらに洗練できると確信していますが、これは画像領域に大まかな形状を与える素晴らしい方法だと思います。

2
Tymn Urban