Создание 9 кругов в каждом прямоугольнике (по 4 в каждом углу, 4 по бокам и 1 в середине) одновременно/сразу после создания прямоугольника

#javascript #svg #snap.svg

Вопрос:

У меня есть задача, в которой я пытаюсь создать 9 кругов в каждом прямоугольнике (по 4 в каждом углу, 4 по бокам и 1 в середине) одновременно после немедленного создания прямоугольника. В моем подходе 4 круга создаются с прямоугольником, что нежелательно!

  • Каждый прямоугольник должен содержать 9 кругов (по 4 в каждом углу, 4 по бокам и 1 в середине) в то же время, когда он будет создан.
  • Чтобы быть более точным, требуется 9 кругов одновременно при создании каждого прямоугольника.
  • Я использовал библиотеку snap.svg для создания кругов и прямоугольников.
  • Вы можете использовать следующий фрагмент кода.
 const svgId = 'campus_map';
const width = document.getElementById(svgId).viewBox.baseVal.width;
const height = document.getElementById(svgId).viewBox.baseVal.height;
let draw = Snap("#tiles");
let c = 0;
let size = Math.round(0.05 * width);
let circleSize = 25;
let circleColor = ["#ff0000", "#000000", "#00ffe1", "#0051ff"];
let svg = document.getElementById(svgId);
for (let i = 0; i <= width; i = i   size) {
    for (let j = 0; j <= height; j = j   size) {
        c  = 1;
        let rect = draw.rect(i, j, size, size);
        let circle1 = draw.circle(i, j, circleSize);
        let circle2 = draw.circle(i   (size / 2), j, circleSize);
        let circle3 = draw.circle(i, j   (size / 2), circleSize);
        let circle4 = draw.circle(i   (size / 2), j   (size / 2), circleSize);

        rect.attr({
            fill: "#d00bf3",
            "fill-opacity": 0.2,
            stroke: "#000",
            "stroke-width": "1px",
            id: "rect_"   c,
            name: "rect"   c
        });
        circle1.attr({
            fill: circleColor[0],
            "fill-opacity": 1,
            stroke: "#000",
            "stroke-width": "1px",
            id: "circle1_"   c,
            name: "circle1_"   c
        });
        circle2.attr({
            fill: circleColor[1],
            "fill-opacity": 1,
            stroke: "#000",
            "stroke-width": "1px",
            id: "circle2_"   c,
            name: "circle2_"   c
        });
        circle3.attr({
            fill: circleColor[2],
            "fill-opacity": 1,
            stroke: "#000",
            "stroke-width": "1px",
            id: "circle3_"   c,
            name: "circle3_"   c
        });
        circle4.attr({
            fill: circleColor[3],
            "fill-opacity": 1,
            stroke: "#000",
            "stroke-width": "1px",
            id: "circle4_"   c,
            name: "circle4_"   c
        });
    }
} 
 <script src="https://unpkg.com/snapsvg@0.5"></script>

<svg viewBox="0 0 8204.08 6413.17" version="1.1" id="campus_map"
    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"
    xmlns:svg="http://www.w3.org/2000/svg">

    <g id="tiles"></g>
</svg> 

Комментарии:

1. Вы создали только четыре круга. Вы пробовали создавать другие круги? Что конкретно касается создания других кругов, на которых вы застряли?

2. я пробовал, но 9 кругов не могут быть созданы одновременно в прямоугольнике одновременно.

3. я знаю, что это трудная задача.

4. Пожалуйста, опубликуйте свой код там, где вы создали девять кругов.

5. И то, что вы подразумеваете под «не может быть создано». Вы получаете сообщение об ошибке? Не появляются ли круги? Или 4?Нам нужна более подробная информация о том, что вы пробовали

Ответ №1:

В вашем цикле вы создаете только четыре круга на плитку. Если вы добавите еще пять, ваш код будет работать. Что вам мешает это сделать?

Похоже, вы хотите, чтобы круги были внутри квадрата. Чтобы достичь этого, вам нужно переместить круги на один радиус круга.

Вот несколько измененных кодов, в которых я вычисляю это смещение и использую петлю для размещения девяти кругов.

 const svgId = 'campus_map';
const width = document.getElementById(svgId).viewBox.baseVal.width;
const height = document.getElementById(svgId).viewBox.baseVal.height;
let draw = Snap("#tiles");
let c = 0;
let size = Math.round(0.05 * width);
let circleSize = 25;
let circleColor = ["#ff0000", "#000000", "#00ffe1", "#0051ff"];
let svg = document.getElementById(svgId);
for (let i = 0; i <= width; i = i   size) {
    for (let j = 0; j <= height; j = j   size) {
        c  = 1;
        let rect = draw.rect(i, j, size, size);
        rect.attr({
            fill: "#d00bf3",
            "fill-opacity": 0.2,
            stroke: "#000",
            "stroke-width": "1px",
            id: "rect_"   c,
            name: "rect"   c
        });
        
        // Now have another loop to create the nine circles.
        // It sounds like you want to have the circle INSIDE the rectangle
        // so you need to move the away from the rectangle corners by 
        // the radius (circleSize).
        
        // The distance between the circles is the square size - two radiuses
        // then divided in half
        let circleSpacing = (size - circleSize * 2) / 2;
        // Top left circle is one radius inside the top left square corner
        let circleStartX = i   circleSize;
        let circleStartY = j   circleSize;
        for (let i2 = 0; i2 < 3; i2  ) {
            for (let j2 = 0; j2 < 3; j2  ) {
                c  = 1;
                let circle = draw.circle(circleStartX   i2 * circleSpacing, circleStartY   j2 * circleSpacing, circleSize);
                circle.attr({
                    fill: circleColor[0],
                    "fill-opacity": 1,
                    stroke: "#000",
                    "stroke-width": "1px",
                    id: "circle1_"   c,
                    name: "circle1_"   c
                });
            }
        }
    }
} 
 <script src="https://unpkg.com/snapsvg@0.5"></script>

<svg viewBox="0 0 8204.08 6413.17" version="1.1" id="campus_map"
    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
    xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"
    xmlns:svg="http://www.w3.org/2000/svg">

    <g id="tiles"></g>
</svg> 

Ответ №2:

Рассмотрим использование шаблона SVG

Это самое простое решение для вашего приложения.
Вы можете легко изменить его содержимое в любое время.
Вы также можете заполнить контейнеры любой формы рисунком и сделать их отзывчивыми.

Пожалуйста, ознакомьтесь с комментариями, чтобы понять, как расположить элементы шаблона.

 <svg width="100%" height="100%" version="1.1"  viewBox="0 0 800 800" 
      xmlns="http://www.w3.org/2000/svg" >
       <defs>
      <pattern id="myPattern"
             x="0" y="0" width="40" height="40"
             patternUnits="userSpaceOnUse" >
               <rect x="0" y="0" width="40" height="40" fill="#F6CEFD" stroke-width="0.5" stroke="black" />
        <g stroke="none"  > 
                   <!-- Central circle -->
                <circle cx="20" cy="20" r="3" fill="#0051FF"/>
                        <!-- Top mid circle -->
                <circle cx="20" cy="0.5" r="3" fill="#000000"/>
                        <!-- Bottom mid circle -->
                <circle cx="20" cy="40" r="3" fill="000"/>
                        <!-- left middle circle -->
                <circle cx="0" cy="20" r="3" fill="#00FFE1"/> 
                        <!-- right middle circle -->
                <circle cx="40" cy="20" r="3" fill="#00FFE1"/>  
                         <!-- upper left corner -->
                <circle cx="0" cy="0" r="3" fill="#FF0000"/>
                         <!-- upper bottom corner -->
                <circle cx="0" cy="40" r="3" fill="#FF0000"/>
                         <!-- top right corner -->
                <circle cx="40" cy="0" r="3" fill="#FF0000"/>
                         <!-- bottom right corner -->
                <circle cx="40" cy="40" r="3" fill="#FF0000"/>
                
   </g>
           
      </pattern>
              
  </defs>
      <rect x="0" y="0" width="100%" height="100%"
         style="stroke: #000000; fill: url(#myPattern);" /> 
 </svg> 

Пример заполнения рождественской елки рисунком

 <svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1"  width="267" height="347" viewBox="0 0 267 347" >
 <defs>
    <pattern id="myPattern"
             x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse" >
            <rect x="0" y="0" width="40" height="40" fill="green" stroke-width="0.5" stroke="black" />
        <g stroke="none"  > 
                   <!-- Central circle -->
                <circle cx="20" cy="20" r="3" fill="#0051FF"/>
                        <!-- Top mid circle -->
                <circle cx="20" cy="0.5" r="3" fill="gold"/>
                        <!-- Bottom mid circle -->
                <circle cx="20" cy="40" r="3" fill="gold"/>
                        <!-- left middle circle -->
                <circle cx="0" cy="20" r="3" fill="#00FFE1"/> 
                        <!-- right middle circle -->
                <circle cx="40" cy="20" r="3" fill="#00FFE1"/>  
                         <!-- upper left corner -->
                <circle cx="0" cy="0" r="3" fill="#FF0000"/>
                         <!-- upper bottom corner -->
                <circle cx="0" cy="40" r="3" fill="#FF0000"/>
                         <!-- top right corner -->
                <circle cx="40" cy="0" r="3" fill="#FF0000"/>
                         <!-- bottom right corner -->
                <circle cx="40" cy="40" r="3" fill="#FF0000"/>
        </g>
    </pattern>
 </defs> 
         <!-- filling a Christmas tree with a pattern -->
         
  <path id="path4146" d="m119 262 28 0 0 86-28-2z" fill="brown" />
  <path id="tree" fill="url(#myPattern)" d="M261 327 169 244c16 9 103 34 76 15-25-18-81-74-81-74 8 5 94 45 71 27-24-19-78-88-78-88 7 5 42 11 42 11-24-13-47-73-47-73 11 8 21 7 21 7C149 51 133 0 133 0c0 0-15 51-39 69 0 0 9 1 21-7 0 0-23 60-47 73 0 0 35-7 42-12 0 0-38 58-78 89-20 15 61-23 69-28 0 0-25 38-75 85-14 14 63-13 72-25 0 0-70 64-88 86-6 7 123-56 123-56 0 0 133 70 129 52z" id="path4" fill="#008000"/>
</svg> 

введите описание изображения здесь