Анимация HTML5-элементов холста для изменения формы (при прокрутке или опрокидывании) без пропусков между ними (элементы должны быть соединены вертикально) - PullRequest
0 голосов
/ 13 января 2019

Как я могу изменить форму всех элементов (по одному) при прокрутке на холсте или при опрокидывании каждого элемента (чтобы получить произвольную форму, но с некоторыми границами для текста, чтобы он был в разделе больше / меньше), а также чтобы держать элементы вертикально соединенными вместе? (нет промежутков между ними, чтобы следовать друг за другом). Я думаю, это можно сделать с помощью координат?

Скриншот

Я провел некоторое исследование и не нашел подобного примера. Я открыт также для других решений, библиотек javascript, SCSS, skew () CSS-функции , clip-path, CSS-свойства , SVG или маски или чего-либо еще для Интернета (я имею в виду, нет особой причины использовать только один конкретный способ).

<!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 и по часовой стрелке, начиная с верхнего левого угла до нижнего левого.

1 Ответ

0 голосов
/ 13 января 2019

Я думаю, что ваша лучшая ставка будет с svg. Вот пример того, как кто-то делает что-то похожее: https://codepen.io/erikdkennedy/pen/ygpwZg

Ключ - это точки polygon, добавленные в svg, что создает треугольный участок, добавленный к прямоугольному заголовку. У svg здесь нет фона, поэтому он фактически вырезает раздел из заголовка. Это в основном удаление раздела из родительского элемента. Вы можете изменить его на div вместо заголовка или любого элемента, который вам нужен.

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

Из документации , points являются парами (x, y) координат. SVG очень гибки и открыты для любой индивидуальной настройки. Настройка точек будет единственной сложной задачей, так как вам придется экспериментировать, пока вы не получите нужные фигуры. Вам нужно, чтобы ваши родительские элементы были достаточно большими, чтобы вы могли вырезать секции в соответствии с вашим дизайном.

Обновление

Я не видел, чтобы это было подтверждено в документации, но точки кажутся в процентах от предоставленного пространства. И по какой-то причине y переворачивается. Таким образом, используя последний пример, 0,100 100,0 100,100 переводится в нижний левый, верхний правый, нижний правый.

Обновление (анимация)

Что касается анимации ваших очков, вот еще один полезный пример по этому вопросу. Это сводится к созданию тега animate в svg с идентификатором для ссылки (документация здесь ). Вы устанавливаете свои свойства анимации на теге animate. Чтобы вызвать его, вызовите id ссылки, а затем вызовите его с помощью beginElement:

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

Обратите внимание, что свойства для to в теге animate. Это диктует, какой должна быть форма в конце анимации. В вашем случае вы захотите настроить прослушиватели событий для mouseover, mouseleave и scroll для запуска анимации в соответствии с вашим дизайном.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...