2017-01-10 24 views
6

Próbuję stworzyć jakąś mapę cieplną dla sieci, nad którą pracuję. Chciałem użyć ula na to, ponieważ wygląda fantazyjnie i daje mi świetne wykorzystanie przestrzeni.Tworzenie elastycznego, wypełniającego przestrzeń ula za pomocą CSS

jeśli znalazłem tę stronę, na której dowiedziałem się, jak używać sześciokątów z czystym CSS. ale to było bardzo zależne od wierszy i przesunięć. Cały mój interfejs użytkownika jest oparty na KnockoutJS i ma dynamiczną liczbę komputerów w sieci w danym momencie. (w większości pojemniki dokowane idą w górę lub w dół).

Klastry mogą się różnić od 1 do n + 1 węzłów.

Spojrzałem na tę stronę: CSS Hexagon i znalazłem kilka rozwiązań do zarządzania sześciokątami, ale wszystkie z nich są NAPRAWDĘ ograniczone w ich dynamicznym użyciu.

Jest to kod przeznaczone:

<div class="panel-body> 
     {{noescape "<!-- ko foreach: { data: vm.dash().nodes, as: 'node' } -->" }} 
      <span class="flex-span" data-bind="attr: { 'id': node.id }, css: { up: node.Status == 2, down: node.Status != 2 }">&#x2B22;</span> 
     {{noescape "<!-- /ko -->"}} 
</div> 

W oparciu o to, że daje sześciokąta kolor, który będzie wskazywać górę/w dół

Mam bita non nokaut skrzypce z mojego schematu flexbox pomysł , ale nie w pełni zrozumieć schematu flexbox że dobrze więc to oczywiście nie działa: Fiddle

#container { 
 
    max-width:400px; 
 
    max-height:400px; 
 
} 
 

 
.hex:before { 
 
    content: " "; 
 
    width: 0; height: 0; 
 
    border-bottom: 30px solid #6C6; 
 
    border-left: 52px solid transparent; 
 
    border-right: 52px solid transparent; 
 
    position: absolute; 
 
    top: -30px; 
 
    flex-shrink: 1; 
 
    flex-grow:1; 
 
    flex-basis: 130px; 
 
} 
 

 
.hex { 
 
    margin-top: 30px; 
 
    width: 104px; 
 
    height: 60px; 
 
    background-color: #6C6; 
 
    position: relative; 
 
    float:left; 
 
    margin-bottom:30px; 
 
    flex-shrink: 1; 
 
    flex-grow:1; 
 
    flex-basis: 130px; 
 
} 
 

 
.hex:after { 
 
    content: ""; 
 
    width: 0; 
 
    position: absolute; 
 
    bottom: -30px; 
 
    border-top: 30px solid #6C6; 
 
    border-left: 52px solid transparent; 
 
    border-right: 52px solid transparent; 
 
    flex-shrink: 1; 
 
    flex-grow:1; 
 
    flex-basis: 130px; 
 
}
<div id="container"> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
</div>

Problemy biegnę na to:

  1. Jak skalować te DIV dynamicznie, niezależnie od liczby i zajmując maksymalną przestrzeń.
  2. Jak używać czystego rozwiązania CSS, aby upewnić się, że wszystkie "rzędy" są przesunięte o pół sześciokąta.

!! AKTUALIZACJA !!

Dodałem więc koncepcję wcześniej ustalonych wierszy: fiddle Ciągle szukam sposobu, aby przesunięcie wiersza było zależne od szerokości klasy ".hex". i mieć skalę klasy szesnastkowej z ilością elementów. ale myślę, że sama siatka wygląda teraz naprawdę dobrze.

+0

idealnie chciałbym użyć czegoś podobnego :: nawet linii ale znaleźliśmy tylko :: first-line, aby zrobić przesunięcia dla sześciokątów. – Puzzle84

+0

Jeśli już używasz nokautu, dlaczego potrzebujesz czystego rozwiązania CSS? Polecam wykonanie komponentu typu knockout i powiązanie atrybutów css z obliczonymi właściwościami, które obliczają skalowanie na podstawie liczby węzłów. –

+0

Nie ma prawdziwego powodu, po prostu wyobrażałem sobie, że css jest o wiele ładniejszy od czasów ładowania ui. A jak byś zrobił logikę liniową parzystą/nieparzystą, jeśli twój ui reaguje? – Puzzle84

Odpowiedz

2

Więc jeśli potrzebujesz 3 sześciokątów w rzędzie: nth-child może pomóc ustawić margines raz na 2 rzędy.

Aby zmierzyć swoje elementy, możesz użyć wartości procentowej, ale będziesz musiał użyć pseudo bez obramowań, ale zamiast tego tła i obrotu.

przykład:

#container { 
 
    max-width: 400px; 
 
    max-height: 400px; 
 
    border: solid;padding:1px; 
 
} 
 
/* demo*/ 
 
#container:hover { 
 

 
    max-width: 600px; 
 
    max-height: 600px; 
 
}/* */ 
 
.hex { 
 
    margin-top: 8%; 
 
    width: 28%; 
 
    padding: 8% 0; 
 
    background-color: #6C6; 
 
    position: relative; 
 
    margin-bottom: 3px; 
 
    margin-right: 0px; 
 
    display: inline-flex; 
 
    position: relative; 
 
    align-items: center; 
 
    justify-content: center; 
 
} 
 
.hex:after, 
 
.hex:before { 
 
    content: ""; 
 
    position: absolute; 
 
    top: 0; 
 
    left: 0; 
 
    right: 0; 
 
    bottom: 0%; 
 
    background: inherit; 
 
    transform: rotate(60deg); 
 
} 
 
.hex:after { 
 
    transform: rotate(-60deg) 
 
} 
 
.hex:nth-child(6n+1) { 
 
    margin-left: 14%; 
 
}
<div id="container"> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
    <div class=hex></div> 
 
</div>

+0

Dobra odpowiedź! Wydaje się, że nie zrozumiałem tego, co OP chciał ... – vals

+0

Prawie perfekcyjnie, ale nie skaluje się, gdy do kontenera dodanych jest więcej elementów. przepełnia, zamiast zmniejszać sześciokąty. – Puzzle84

+0

@ Puzzle84 Obawiam się, że ta część nie będzie możliwa do wykonania za pomocą CSS, ponieważ tego rodzaju zachowanie, płótno i javascript będą bardziej odpowiednie :(chyba że możesz stworzyć mieszankę vh & vw .... –

1

Nie sądzę, aby można było zastosować styl w pojemniku flex w oparciu o numer wiersza (parzysty/nieparzysty).

Tak więc ustawiłem sześciokąty zachodzące na siebie w tym samym rzędzie i upewniłem się, że w rzędzie zawsze będzie parzysta liczba sześciokątów (nawet te nie mają wymaganego miejsca z powodu ujemnych marginesów, więc zawsze będzie pasować).

Oto moje rozwiązanie. Najedź na kontener, aby zmienić szerokość.

#container { 
 
    max-width: 410px; 
 
    max-height: 400px; 
 
    display: flex; 
 
    flex-wrap: wrap; 
 
    border: solid 1px green; 
 
    transition: max-width 6s; 
 
} 
 
#container:hover { 
 
    max-width: 800px; 
 
} 
 
.hex { 
 
    margin-top: 30px; 
 
    height: 60px; 
 
    background-color: #6C6; 
 
    position: relative; 
 
    margin-bottom: 90px; 
 
    flex-shrink: 0; 
 
    flex-grow: 0; 
 
    flex-basis: 104px; 
 
} 
 
.hex:nth-child(even) { 
 
    background-color: blue; 
 
    transform: translateY(90px); 
 
    margin-left: -52px; 
 
    margin-right: -52px; 
 
} 
 
.hex:before { 
 
    content: " "; 
 
    width: 0; 
 
    height: 0; 
 
    border-bottom: 30px solid #6c6; 
 
    border-left: 52px solid transparent; 
 
    border-right: 52px solid transparent; 
 
    position: absolute; 
 
    top: -30px; 
 
    flex-shrink: 1; 
 
    flex-grow: 1; 
 
    flex-basis: 130px; 
 
} 
 
.hex:after { 
 
    content: ""; 
 
    width: 0; 
 
    position: absolute; 
 
    bottom: -30px; 
 
    border-top: 30px solid #6c6; 
 
    border-left: 52px solid transparent; 
 
    border-right: 52px solid transparent; 
 
    flex-shrink: 1; 
 
    flex-grow: 1; 
 
    flex-basis: 130px; 
 
} 
 
.hex:nth-child(even):before { 
 
    border-bottom-color: blue; 
 
} 
 
.hex:nth-child(even):after { 
 
    border-top-color: blue; 
 
}
<div id="container"> 
 
    <div class="hex"></div> 
 
    <div class="hex"></div> 
 
    <div class="hex"></div> 
 
    <div class="hex"></div> 
 
    <div class="hex"></div> 
 
    <div class="hex"></div> 
 
    <div class="hex"></div> 
 
    <div class="hex"></div> 
 
    <div class="hex"></div> 
 
    <div class="hex"></div> 
 
    <div class="hex"></div> 
 
</div>

+0

Prawie dokładnie to, co chcę z perspektywy owijania. ale nie powinno być ograniczeń na zielonym i niebieskim, aby mieć taką samą ilość elementów. Zasadniczo, druga linia bluesa powinna być pozostałymi 2 zieleniami w linii powyżej – Puzzle84