簡體   English   中英

對HTML5畫布元素進行動畫處理以更改形狀(滾動或翻轉時),它們之間沒有間隙(這些元素必須垂直連接)

[英]Animate HTML5 canvas elements to change shape (on scroll or rollover) without gaps between them (the elements must be vertically connected)

我如何在畫布上滾動或將每個元素翻轉時修改所有元素的形狀(一個一個地變)(以獲取隨機形狀,但要使文本在部分中具有更多/更少的邊界),並且還要保留這些元素垂直連接在一起? (彼此之間沒有差距)。 我猜這可以用坐標來完成嗎?

截圖

我已經做了一些研究,但沒有找到類似的例子。 我也對其他解決方案,JavaScript庫,SCSS, skew()CSS函數剪切路徑CSS屬性 ,SVG或mask或其他用於Web的網站持開放態度(我的意思是,沒有特別的理由只使用一種特定的方式) 。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <style type="text/css">
    #myCanvas {
      border: 1px solid black;
      width: 100%;
      height: auto;
    }
  </style>
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
</head>
<body>

    <canvas id="myCanvas"></canvas>

    <script>
    $(function() {

        var canvas = document.getElementById('myCanvas'),
        width = window.innerWidth,
        height = window.innerHeight,
        elemWidth = window.innerWidth - 20,
        lineheight = 30,
        txt1 = 'Lorem 1 ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula\neget dolor. Aenean massa. Cum sociis natoque penatibus et',
        txt2 = 'Lorem 2 ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula\neget dolor. Aenean massa. Cum sociis natoque penatibus et',
        txt3 = 'Lorem 3 ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula\neget dolor. Aenean massa. Cum sociis natoque penatibus et',
        lines1 = txt1.split('\n'),
        lines2 = txt2.split('\n'),
        lines3 = txt3.split('\n');

        window.addEventListener('resize', resizeCanvas, false);

        function resizeCanvas() {
            canvas.width = width;
            canvas.height = height;
            drawStuff();
        }

        resizeCanvas();

        function drawStuff() {

            // element 1
            var poly1 = [5,100, (elemWidth-100),5, elemWidth,400, 5,300 ];
            var ctx1 = canvas.getContext('2d');
            ctx1.fillStyle = '#ff8080';
            ctx1.beginPath();
            ctx1.moveTo(poly1[0], poly1[1]);
            for(item = 2 ; item < poly1.length - 1 ; item += 2) {
                ctx1.lineTo(poly1[item], poly1[item + 1]);
            }
            ctx1.closePath();
            ctx1.fill();
            ctx1.fillStyle = "Black";
            ctx1.font = '70px Arial';
            ctx1.fillText("Some title 1",300,180);
            ctx1.font = '30px Arial';
            for (var i = 0; i<lines1.length; i++) {
                ctx1.fillText(lines1[i], 300, 220 + (i*lineheight) );
            }

            // element 2
            var poly2 = [5,300, elemWidth,400, (elemWidth-100),800, 50,600];
            var ctx2 = canvas.getContext('2d');
            ctx2.fillStyle = '#e9afaf';
            ctx2.beginPath();
            ctx2.moveTo(poly2[0], poly2[1]);
            for(item = 2 ; item < poly2.length - 1 ; item += 2) {
                ctx2.lineTo(poly2[item], poly2[item + 1]);
            }
            ctx2.closePath();
            ctx2.fill();
            ctx2.fillStyle = "Black";
            ctx2.font = '70px Arial';
            ctx2.fillText("Some title 2",300,480);
            ctx2.font = '30px Arial';
            for (var i = 0; i<lines2.length; i++) {
                ctx2.fillText(lines2[i], 300, 520 + (i*lineheight) );
            }

            // element 3
            var poly3 = [50,600, (elemWidth-100),800, elemWidth,940, 5,900];
            var ctx3 = canvas.getContext('2d');
            ctx3.fillStyle = '#c8b7b7';
            ctx3.beginPath();
            ctx3.moveTo(poly3[0], poly3[1]);
            for(item = 2 ; item < poly3.length - 1 ; item += 2) {
                ctx3.lineTo(poly3[item], poly3[item + 1]);
            }
            ctx3.closePath();
            ctx3.fill();
            ctx3.fillStyle = "Black";
            ctx3.font = '70px Arial';
            ctx3.fillText("Some title 3",300,780);
            ctx3.font = '30px Arial';
            for (var i = 0; i<lines3.length; i++) {
                ctx3.fillText(lines3[i], 300, 820 + (i*lineheight) );
            }

        }

    });
    </script>
</body>
</html>

更新:我創建了建議的SVG,因為我的目標是動畫,所以有關更新這些多邊形點值的任何建議/想法(例如,在翻轉時,我可以使用jquery),下一個多邊形可以動態跟隨(更新點),還保持聯系?

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<style type="text/css">
  svg {
    width: 100%;
    height: auto;
  }
</style>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
</head>
<body>
<svg width="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
  <polygon fill="#99bde5" points="0,5 95,0 100,35, 0,20" id="testElem"/>
  <text x="10" y="12" text-anchor="left" fill="black" font-size="6">Some title 1</text>
  <text x="10" y="15" text-anchor="left" fill="black" font-size="3">
      <tspan>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</tspan>
      <tspan x="10" dy="3">Aenean commodo ligula eget dolor. Aenean massa.</tspan>
  </text>

  <polygon fill="#c9e599" points="0,20 100,35 100,55, 5,50" id="testElem"/>
  <text x="10" y="36" text-anchor="left" fill="black" font-size="6">Some title 1</text>
  <text x="10" y="40" text-anchor="left" fill="black" font-size="3">
      <tspan>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</tspan>
      <tspan x="10" dy="3">Aenean commodo ligula eget dolor. Aenean massa.</tspan>
  </text>

  <polygon fill="#a5e599" points="5,50 100,55 94,75, 5,80" id="testElem"/>
  <text x="10" y="63" text-anchor="left" fill="black" font-size="6">Some title 1</text>
  <text x="10" y="67" text-anchor="left" fill="black" font-size="3">
      <tspan>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</tspan>
      <tspan x="10" dy="3">Aenean commodo ligula eget dolor. Aenean massa.</tspan>
  </text>

  <polygon fill="#99e5ca" points="5,80 94,74 100,100, 0,100" id="testElem"/>
  <text x="10" y="89" text-anchor="left" fill="black" font-size="6">Some title 1</text>
  <text x="10" y="92" text-anchor="left" fill="black" font-size="3">
      <tspan>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</tspan>
      <tspan x="10" dy="3">Aenean commodo ligula eget dolor. Aenean massa.</tspan>
  </text>
</svg>
</body>
</html>

PS。 SVG點是x,y,從左上角到左下角是順時針方向。

我認為最好的選擇是svg 這是某人做類似事情的示例: https : //codepen.io/erikdkennedy/pen/ygpwZg

關鍵是在svg中添加的polygon的點,該點創建添加到矩形標題的三角形截面。 此處的svg沒有背景,因此實際上是從標頭中切出一部分。 這基本上是從父元素中刪除一個部分。 您可以將其更改為div而不是header或您需要的任何元素。

<polygon fill="white" points="0,100 100,0 100,100"/>

根據文檔points是(x,y)坐標對。 SVG非常靈活,可以根據需要進行任何自定義。 設置點將是唯一棘手的部分,因為您必須進行實驗,直到獲得所需的形狀為止。 您需要您的父元素足夠大,以便可以切出適合您的設計的部分。

更新

我在文檔中沒有看到它的確認,但是要點似乎是所提供空間的百分比。 並且,由於某些原因, y被翻轉。 因此,使用最后一個示例, 0,100 100,0 100,100轉換為左下,右上,右下。

更新(動畫)

至於使您的觀點生氣勃勃,這是另一個有用的例子 這歸結為在svg內創建一個帶有參考ID的animate標簽(請參見此處的文檔 )。 您可以在animate標簽上設置動畫屬性。 要觸發它,請調用引用的id ,然后使用beginElement觸發它:

var animationToStar = document.getElementById("animation-to-star")
animationToStar.beginElement();

請注意, animate標簽上的to屬性。 這決定了動畫結束時的形狀。 對於您的用例,您將需要為mouseovermouseleave設置事件監聽器,並scroll以根據設計觸發動畫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM