#javascript #svg
Необходимо сделать фон из многоугольников.
Фон случайным образом заполняется многоугольниками
Основа многоугольников это правильная фигура с равными рёбрами, но вершины должны
случайным образом отходить от правильной фигуры. То есть к координатам каждой вершины
прибавляем случайный вектор небольшого размера.
Цвета многоугольников заранее заданы палитрой, массив цветов.
При наведении мышкой на многоугольник запускается анимация смены цвета на заданный,
увеличение размера, и возвращение в исходное состояние. Так же анимация случайного
вращения вокруг центра во время трансформации цвета и размера.
Это Вопрос-Ответ в рамках обучающей инициативы нашего Ru.StackOverflow SVG чата.
Ответы
Ответ 1
Первое что мы сделаем это научимся генерировать равнобедренные многогранники. Итак наш код: function MakeIdealMnogogrannik(rad, n) { var angle = 2 * Math.PI / n; var points = []; for (var i = 0; i < n; i++) { points.push({ x: rad * Math.cos(angle * i), y: rad * Math.sin(angle * i) }); } return points; } Далее напишем функцию которая сгенерирует равнобедренные многогранники и сохранит во внешнюю переменную var radius = 22; var minGranNumber = 3; var maxGranNumber = 6; var mnogograniksIdeal = new Array(maxGranNumber - minGranNumber + 1); function MakeIdeals() { var number = maxGranNumber - minGranNumber + 1; for (var i = 0; i < number; i++) { mnogograniksIdeal[i] = MakeIdealMnogogrannik(radius, i + minGranNumber); } } Генерируем кривоугольники на основе правильных многогранников. /* палитра цветов */ var colors = ["rgb(187, 61, 255)","rgb(255, 194, 61)","rgb(255, 255, 61)","rgb(61, 155, 255)","rgb(226, 61, 255)"]; var svgNS = "http://www.w3.org/2000/svg"; /* передаём количество граней, расстояние на которое вершина может случайно отъехать в сторону, координаты кривоугольника */ function MakeRandomMnogogrannik(granNumber, distance, x, y) { var path = document.createElementNS(svgNS, "path"); var points = new Array(mnogograniksIdeal[granNumber].length); /* случайно смещаем вершины равнобедренных многогранников что бы получить кривоугольник */ for (var i = 0; i < points.length; i++) { points[i] = { x: mnogograniksIdeal[granNumber][i].x + randomMax(distance) + x, y: mnogograniksIdeal[granNumber][i].y + randomMax(distance) + y } } var d = `M ${points[0].x} ${points[0].y}`; for (var i = 1; i < points.length; i++) { d += ` L ${points[i].x} ${points[i].y}`; } d += " Z"; path.setAttribute("stroke", "black"); var color = colors[randomMax(colors.length - 1)]; path.setAttribute("fill", color); /* запоминаем цвет в кастомную переменную, что бы во время анимации можно было вернуться к исходному цвету */ path.setAttribute("mycolor", color); var rot = randomMax(360); path.setAttribute("transform", `rotate(${rot} ${x} ${y})`); path.setAttribute("d", d); path.addEventListener("mouseover", MouseOver1); return path; } Функция заполнения области var svg = document.getElementById("svg1"); var width; var height; var distance = 4; function FillArea() { /* получаем ширину и высоту окна */ var style = window.getComputedStyle(svg); width = parseInt(style.width); height = parseInt(style.height); /* вычисляем количество кривоугольников на основе плотности - density */ var elementsNumber = density * width * height / (100 * 100); for (var i = 0; i < elementsNumber; i++) { /* ставим на случайную точку */ var x = randomMax(width); var y = randomMax(height); /* чередуем количество граней */ var path = MakeRandomMnogogrannik(i % mnogograniksIdeal.length, distance, x, y); svg.appendChild(path); } } Анимация при наведении мыши с использованием SVG.js function MouseOver1() { /* получаем объект SVG.js */ var rect1 = SVG.adopt(this); /* прекращаем и фиксируем ранее идущую анимацию если есть */ rect1.finish(); var rot = (Math.random() - 0.5) * 90; /* помещаем фигуру на самый верх полотна, что бы была видна анимация */ svg.append(this); /* цвет для восстановления из кастомного аттрибута */ var color = this.getAttribute("mycolor"); /* увеличиваем размер и делаем заданный цвет */ rect1.fill("rgb(255, 0, 0)"); rect1.scale(1.4); /* запускаем анимацию */ rect1.animate(1100, "-") .rotate(rot) .scale(1) .attr({ fill: color }); } Результирующий код var svg = document.getElementById("svg1"); var minGranNumber = 3; var maxGranNumber = 6; var radius = 17; var distance = 4; var density = 60; var mnogograniksIdeal = new Array(maxGranNumber - minGranNumber + 1); var colors = ["rgb(187, 61, 255)", "rgb(255, 194, 61)", "rgb(255, 255, 61)", "rgb(61, 155, 255)", "rgb(226, 61, 255)"]; var svgNS = "http://www.w3.org/2000/svg"; function MakeIdeals() { var number = maxGranNumber - minGranNumber + 1; for (var i = 0; i < number; i++) { mnogograniksIdeal[i] = MakeIdealMnogogrannik(radius, i + minGranNumber); } } function MakeIdealMnogogrannik(rad, n) { var angle = 2 * Math.PI / n; var points = []; for (var i = 0; i < n; i++) { points.push({ x: rad * Math.cos(angle * i), y: rad * Math.sin(angle * i) }); } return points; } function MakeRandomMnogogrannik(granNumber, distance, x, y) { var path = document.createElementNS(svgNS, "path"); var points = new Array(mnogograniksIdeal[granNumber].length); for (var i = 0; i < points.length; i++) { points[i] = { x: mnogograniksIdeal[granNumber][i].x + randomMax(distance) + x, y: mnogograniksIdeal[granNumber][i].y + randomMax(distance) + y } } var d = `M ${points[0].x} ${points[0].y}`; for (var i = 1; i < points.length; i++) { d += ` L ${points[i].x} ${points[i].y}`; } d += " Z"; path.setAttribute("stroke", "black"); var color = colors[randomMax(colors.length - 1)]; path.setAttribute("fill", color); path.setAttribute("mycolor", color); var rot = randomMax(360); path.setAttribute("transform", `rotate(${rot} ${x} ${y})`); path.setAttribute("d", d); path.addEventListener("mouseover", MouseOver1); return path; } var width; var height; function FillArea() { var style = window.getComputedStyle(svg); width = parseInt(style.width); height = parseInt(style.height); var elementsNumber = density * width * height / (100 * 100); for (var i = 0; i < elementsNumber; i++) { var x = randomMax(width); var y = randomMax(height); var path = MakeRandomMnogogrannik(i % mnogograniksIdeal.length, distance, x, y); svg.appendChild(path); } } function MouseOver1() { var rect1 = SVG.adopt(this); rect1.finish(); var rot = (Math.random() - 0.5) * 90; svg.append(this); var color = this.getAttribute("mycolor"); rect1.fill("rgb(255, 0, 0)"); rect1.scale(1.4); rect1.animate(1100, "-") .rotate(rot) .scale(1) .attr({ fill: color }); } function randomBool() { if (Math.random() > 0.5) { return true; } return false; } function randomMinMax(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); } function randomMax(max) { return Math.floor(Math.random() * (max + 1)); } MakeIdeals(); FillArea(); body { margin: 0; } Ссылка на Codepen. Дополнения версия с мозаичным текстом.
Комментариев нет:
Отправить комментарий