2015-10-19 1 views
14

У меня есть квадратная решетка SVG, наклоненная под углом 45 градусов. На отдельных гексах я хотел бы разместить изображения (представленные красными прямоугольниками), которые кажутся стоящими вертикально, соответствующими плоскости сетки. Изображения/прямоугольники не обязательно должны быть на уровне 90 градусов, но у меня есть труднее всего заставить их иметь любую перспективу, которая даже немного отличается от плоскости.Настройка правильной перспективы для дочерних элементов на 3d-плоскости в CSS

Есть ли способ отменить перспективу для дочерних элементов или переделать CSS-преобразования так или иначе, чтобы это выглядело правильно?

Код

.display { 
 
    animation: displayFlicker 100ms cubic-bezier(.37, 0, .41, 1.74) 100ms 1 normal forwards; 
 
    -webkit-animation: displayFlicker 100ms cubic-bezier(.37, 0, .41, 1.74) 100ms 1 normal forwards; 
 
    background: #000; 
 
    display: block; 
 
    border-left: 0.25rem solid #000; 
 
    border-right: 0.25rem solid #000; 
 
    box-sizing: border-box; 
 
    -moz-box-sizing: border-box; 
 
    height: 480px; 
 
    overflow: hidden; 
 
    width: 1096px; 
 
} 
 
#hexGrid { 
 
    box-sizing: border-box; 
 
    -moz-box-sizing: border-box;  
 
    display: block; 
 
    height: 100%; 
 
    -webkit-transform: perspective(44vw) rotateX(45deg) scale3d(1.6, 1.6, 1.6); 
 
    -moz-transform: perspective(44vw) rotateX(45deg) scale3d(1.6, 1.6, 1.6);  
 
    -ms-transform: perspective(44vw) rotateX(45deg) scale3d(1.6, 1.6, 1.6); 
 
    -o-transform: perspective(44vw) rotateX(45deg) scale3d(1.6, 1.6, 1.6); 
 
    transform: perspective(44vw) rotateX(45deg) scale3d(1.6, 1.6, 1.6); 
 
    transform-style: preserve-3d; 
 
    width: 100%; 
 
} 
 
.hexContainer { 
 
    outline: none; 
 
    transform-style: preserve-3d; 
 
} 
 
.hex { 
 
    box-sizing: border-box; 
 
    -moz-box-sizing: border-box; 
 
    display: inline-block; 
 
    height: 4.4vmin; 
 
    opacity: 1; 
 
    outline: none; 
 
    position: relative; 
 
    stroke: #0CF; 
 
    stroke-width: 0.0625rem; 
 
    transform: scale3d(1, 1, 1); 
 
    transition: all linear 300ms; 
 
    width: 8vmin; 
 
} 
 
.hex.open { 
 
    fill: rgba(0, 204, 255, 0.3); 
 
} 
 
.hex.blocked { 
 
    fill: url(#blockedHexPattern); 
 
    fill-opacity: 0.3; 
 
} 
 
.hexContainer:focus .open, .hexContainer:hover .open { 
 
    cursor: pointer; 
 
    fill: rgba(0, 204, 255, 0.8); 
 
    outline: none; 
 
} 
 
.hexContainer:focus .blocked, .hexContainer:hover .blocked { 
 
    cursor: pointer; 
 
    fill: url(#blockedHexPattern); 
 
    fill-opacity: 1; 
 
    outline: none; 
 
} 
 
.hexContainer:focus .occupied, .hexContainer:hover .occupied { 
 
    cursor: pointer; 
 
    fill: rgba(50, 50, 50, 0.8); 
 
    outline: none; 
 
} 
 
.hexContainer:focus .open, .hexContainer:focus .open.unblock { 
 
    transform-origin: 50% 0%; 
 
} 
 
.hexContainer:focus .blocked { 
 
    opacity: 1; 
 
    transform-origin: 50% 0%; 
 
} 
 
.hexContainer.active .open { 
 
    fill: rgba(0, 204, 255, 0.8); 
 
    opacity: 1; 
 
} 
 
#blockedHexPattern line { 
 
    stroke: #0CF; 
 
    stroke-width: 0.0625rem; 
 
} 
 
#hexGrid .rect { 
 
    transform: rotateX(0deg); 
 
}
<div id="stationMap" class="display"> 
 
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="55 -30 360 360" id="hexGrid"> 
 
    <defs> 
 
     <pattern x="0" y="0" height="10" width="10" patternUnits="userSpaceOnUse" id="blockedHexPattern"> 
 
      <line x1="0" y1="10" x2="10" y2="0"></line> 
 
     </pattern> 
 
    </defs> 
 
    <a id="hex0-0" class="hexContainer"> 
 
     <polygon class="hex open" points="81.96152422706632,45 55.98076211353316,60 30,45 30.000000000000004,14.999999999999996 55.98076211353315,0 81.96152422706632,14.999999999999986"></polygon> 
 
    </a> 
 
    <a id="hex0-2" class="hexContainer"> 
 
     <polygon class="hex blocked" points="185.88457268119896,45 159.9038105676658,60 133.92304845413264,45 133.92304845413264,14.999999999999996 159.9038105676658,0 185.88457268119896,14.999999999999986" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
    <a id="hex0-6" class="hexContainer"> 
 
     <polygon class="hex blocked" points="393.7306695894642,45 367.749907475931,60 341.76914536239786,45 341.76914536239786,14.999999999999996 367.749907475931,0 393.7306695894642,14.999999999999986" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
    <a id="hex0-7" class="hexContainer"> 
 
     <polygon class="hex blocked" points="445.6921938165305,45 419.71143170299734,60 393.7306695894642,45 393.7306695894642,14.999999999999996 419.71143170299734,0 445.6921938165305,14.999999999999986" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
    <a id="hex1-0" class="hexContainer"> 
 
     <polygon class="hex open" points="55.98076211353316,90 30.000000000000004,105 4.01923788646684,90 4.019237886466843,60 29.999999999999993,45 55.98076211353315,59.999999999999986"></polygon> 
 
     <rect class="rect" fill="red" x="5" y="67.5" width="50" height="40"/> 
 
    </a> 
 
    <a id="hex1-3" class="hexContainer"> 
 
     <polygon class="hex blocked" points="211.8653347947321,90 185.88457268119893,105 159.90381056766577,90 159.90381056766577,60 185.88457268119893,45 211.8653347947321,59.999999999999986" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
    <a id="hex1-4" class="hexContainer"> 
 
     <polygon class="hex open" points="263.82685902179844,90 237.84609690826525,105 211.8653347947321,90 211.8653347947321,60 237.84609690826525,45 263.8268590217984,59.999999999999986"></polygon> 
 
    </a> 
 
    <a id="hex1-5" class="hexContainer"> 
 
     <polygon class="hex open" points="315.7883832488647,90 289.80762113533154,105 263.8268590217984,90 263.8268590217984,60 289.80762113533154,45 315.7883832488647,59.999999999999986"></polygon> 
 
    </a> 
 
    <a id="hex1-6" class="hexContainer"> 
 
     <polygon class="hex open" points="367.749907475931,90 341.76914536239786,105 315.7883832488647,90 315.7883832488647,60 341.76914536239786,45 367.749907475931,59.999999999999986"></polygon> 
 
    </a> 
 
    <a id="hex1-7" class="hexContainer"> 
 
     <polygon class="hex open" points="419.71143170299734,90 393.7306695894642,105 367.749907475931,90 367.749907475931,60 393.7306695894642,45 419.71143170299734,59.999999999999986"></polygon> 
 
     <rect class="rect" fill="red" x="369" y="67.5" width="50" height="40"/> 
 
    </a> 
 
    <a id="hex2-0" class="hexContainer"> 
 
     <polygon class="hex open" points="81.96152422706632,134.99999999999997 55.98076211353316,150 30,134.99999999999997 30.000000000000004,104.99999999999999 55.98076211353315,89.99999999999999 81.96152422706632,104.99999999999997"></polygon> 
 
    </a> 
 
    <a id="hex2-2" class="hexContainer"> 
 
     <polygon class="hex blocked" points="185.88457268119896,134.99999999999997 159.9038105676658,150 133.92304845413264,134.99999999999997 133.92304845413264,104.99999999999999 159.9038105676658,89.99999999999999 185.88457268119896,104.99999999999997" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
    <a id="hex2-3" class="hexContainer"> 
 
     <polygon class="hex open" points="237.84609690826525,134.99999999999997 211.8653347947321,150 185.88457268119893,134.99999999999997 185.88457268119893,104.99999999999999 211.8653347947321,89.99999999999999 237.84609690826525,104.99999999999997"></polygon> 
 
    </a> 
 
    <a id="hex2-4" class="hexContainer"> 
 
     <polygon class="hex open" points="289.80762113533154,134.99999999999997 263.8268590217984,150 237.84609690826522,134.99999999999997 237.84609690826522,104.99999999999999 263.8268590217984,89.99999999999999 289.80762113533154,104.99999999999997"></polygon> 
 
    </a> 
 
    <a id="hex2-5" class="hexContainer"> 
 
     <polygon class="hex open" points="341.76914536239786,134.99999999999997 315.7883832488647,150 289.80762113533154,134.99999999999997 289.80762113533154,104.99999999999999 315.7883832488647,89.99999999999999 341.76914536239786,104.99999999999997"></polygon> 
 
    </a> 
 
    <a id="hex2-6" class="hexContainer"> 
 
     <polygon class="hex open" points="393.7306695894642,134.99999999999997 367.749907475931,150 341.76914536239786,134.99999999999997 341.76914536239786,104.99999999999999 367.749907475931,89.99999999999999 393.7306695894642,104.99999999999997"></polygon> 
 
    </a> 
 
    <a id="hex2-7" class="hexContainer"> 
 
     <polygon class="hex open" points="445.6921938165305,134.99999999999997 419.71143170299734,150 393.7306695894642,134.99999999999997 393.7306695894642,104.99999999999999 419.71143170299734,89.99999999999999 445.6921938165305,104.99999999999997"></polygon> 
 
    </a> 
 
    <a id="hex3-0" class="hexContainer"> 
 
     <polygon class="hex open" points="55.98076211353316,179.99999999999997 30.000000000000004,194.99999999999997 4.01923788646684,179.99999999999997 4.019237886466843,149.99999999999997 29.999999999999993,134.99999999999997 55.98076211353315,149.99999999999994"></polygon> 
 
    </a> 
 
    <a id="hex3-3" class="hexContainer"> 
 
     <polygon class="hex blocked" points="211.8653347947321,179.99999999999997 185.88457268119893,194.99999999999997 159.90381056766577,179.99999999999997 159.90381056766577,149.99999999999997 185.88457268119893,134.99999999999997 211.8653347947321,149.99999999999994" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
    <a id="hex3-5" class="hexContainer"> 
 
     <polygon class="hex blocked" points="315.7883832488647,179.99999999999997 289.80762113533154,194.99999999999997 263.8268590217984,179.99999999999997 263.8268590217984,149.99999999999997 289.80762113533154,134.99999999999997 315.7883832488647,149.99999999999994" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
    <a id="hex3-7" class="hexContainer"> 
 
     <polygon class="hex blocked" points="419.71143170299734,179.99999999999997 393.7306695894642,194.99999999999997 367.749907475931,179.99999999999997 367.749907475931,149.99999999999997 393.7306695894642,134.99999999999997 419.71143170299734,149.99999999999994" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
    <a id="hex4-0" class="hexContainer"> 
 
     <polygon class="hex open" points="81.96152422706632,224.99999999999997 55.98076211353316,239.99999999999997 30,224.99999999999997 30.000000000000004,194.99999999999997 55.98076211353315,179.99999999999997 81.96152422706632,194.99999999999994"></polygon> 
 
    </a> 
 
    <a id="hex4-1" class="hexContainer"> 
 
     <polygon class="hex blocked" points="133.92304845413264,224.99999999999997 107.94228634059948,239.99999999999997 81.96152422706632,224.99999999999997 81.96152422706632,194.99999999999997 107.94228634059948,179.99999999999997 133.92304845413264,194.99999999999994" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
    <a id="hex4-2" class="hexContainer"> 
 
     <polygon class="hex blocked" points="185.88457268119896,224.99999999999997 159.9038105676658,239.99999999999997 133.92304845413264,224.99999999999997 133.92304845413264,194.99999999999997 159.9038105676658,179.99999999999997 185.88457268119896,194.99999999999994" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
    <a id="hex4-3" class="hexContainer"> 
 
     <polygon class="hex blocked" points="237.84609690826525,224.99999999999997 211.8653347947321,239.99999999999997 185.88457268119893,224.99999999999997 185.88457268119893,194.99999999999997 211.8653347947321,179.99999999999997 237.84609690826525,194.99999999999994" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
    <a id="hex4-4" class="hexContainer"> 
 
     <polygon class="hex open" points="289.80762113533154,224.99999999999997 263.8268590217984,239.99999999999997 237.84609690826522,224.99999999999997 237.84609690826522,194.99999999999997 263.8268590217984,179.99999999999997 289.80762113533154,194.99999999999994"></polygon> 
 
    </a> 
 
    <a id="hex4-5" class="hexContainer"> 
 
     <polygon class="hex open" points="341.76914536239786,224.99999999999997 315.7883832488647,239.99999999999997 289.80762113533154,224.99999999999997 289.80762113533154,194.99999999999997 315.7883832488647,179.99999999999997 341.76914536239786,194.99999999999994"></polygon> 
 
    </a> 
 
    <a id="hex4-6" class="hexContainer"> 
 
     <polygon class="hex open" points="393.7306695894642,224.99999999999997 367.749907475931,239.99999999999997 341.76914536239786,224.99999999999997 341.76914536239786,194.99999999999997 367.749907475931,179.99999999999997 393.7306695894642,194.99999999999994"></polygon> 
 
    </a> 
 
</svg> 
 
</div>

+1

К сожалению, нет (простого) способа сброса дочерних элементов. Когда вы трансформируете svg, вы также преобразуете всю систему координат. Возможно, вы сможете выполнить математическую математику, чтобы отменить преобразование системы координат для красных квадратов, но затем они больше не выстраиваются в линию. Может быть какое-то продвинутое преобразование матрицы, которое вы могли бы сделать, но в определенный момент может быть проще использовать настоящий 3d-движок, такой как three.js (http://threejs.org/), который построен для того, чтобы делать то, что вы хотите , –

+0

@RobLouie Я «своего рода» исправляю его прямо сейчас, используя CSS-преобразования для дочерних элементов, в частности skewX и translate, но это очень обидно, для каждого браузера требуются разные преобразования, и я должен настроить контент для каждого шестнадцатеричного индивидуально глазом. В идеале, я хотел бы кое-что немного более уверенно, но, боюсь, вы можете быть правы. – VirtuosiMedia

ответ

0

SVG еще не поддерживает 3D-преобразования; даже если вы можете преобразовать элемент svg (который все еще находится в контексте html и поэтому принимает 3D-преобразование), его содержимое будет располагаться внутри него, нет transform-style, который изменит это поведение.

Лучше всего иметь каждый шестиугольник как свой собственный элемент SVG, чтобы они могли быть преобразованы в 3D отдельно. Что-то вроде:

<div class="hexGrid" style="{3d transform}"> 
    <svg class="hex" style="{reversed 3d transform}"> 
     <polygon /> 
     <rect /> 
    </svg> 
    <svg class="hex"> 
     ... 
    </svg> 
</div> 

Вы также смешивание HTML-теги с SVG теги: <a> не существует в SVG. Вы можете использовать атрибут xlink:href для любого элемента.

+0

К сожалению, я не думаю, что конкретный подход будет работать, поскольку мне нужен прямоугольник, чтобы иметь другое преобразование из многоугольника. Шестиугольник многоугольника не обязательно должен иметь обратное преобразование, просто прямоугольник/изображение. Для чего это стоит, - это тег SVG, по крайней мере, согласно mozilla: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/a – VirtuosiMedia

5

Поскольку 3d-преобразования не могут быть обработаны должным образом на элементах SVG, я бы предложил другой подход для сетки шестиугольников. Это может быть достигнуто с помощью простых html и css, как показано в этом вопросе: Responsive grid of hexagons.

Это позволяет делать 3d-преобразования на дочерних элементах с помощью transform-style property.

адаптированного к вашему прецеденту, он может выглядеть следующим образом:

DEMO

body{ 
 
    background:rgb(123, 158, 158); 
 
    perspective:500px; 
 
} 
 
#categories{ 
 
    width:70%; 
 
    margin:0 auto; 
 
    transform:rotateX(45deg); 
 
    transform-style: preserve-3d; 
 
} 
 
#categories:after{ 
 
    content:""; 
 
    display:block; 
 
    clear:both; 
 
} 
 
#categories li{ 
 
    position:relative; 
 
    list-style-type:none; 
 
    width:17.364%; /* = (100-4.5)/5.5 */ 
 
    padding-bottom: 20.05%; /* = width /0.866 */ 
 
    float:left; 
 
    overflow:hidden; 
 
    visibility:hidden; 
 
    transform: rotate(-60deg) skewY(30deg); 
 
} 
 

 
#categories li:nth-child(10n+6), #categories li:nth-child(10n+7), #categories li:nth-child(10n+8), #categories li:nth-child(10n+9), #categories li:nth-child(10n+10) { 
 
    margin-top: -4.2%; 
 
    margin-bottom: -4.2%; 
 
    transform: translateX(50%) rotate(-60deg) skewY(30deg); 
 
    } 
 
#categories li:nth-child(10n+6){ 
 
    margin-left:0.5%; 
 
    } 
 
    #categories li:nth-child(5n+2) { 
 
    margin-left:1%; 
 
    margin-right:1%; 
 
    } 
 
    #categories li:nth-child(5n+3),#categories li:nth-child(5n+4){ 
 
    margin-right:1%; 
 
    } 
 

 
#categories li div{ 
 
    position:absolute; 
 
    visibility:visible; 
 
    width:100%; height:100%; 
 
    text-align:center; 
 
    color:#fff; 
 
    overflow:hidden; 
 
    transform: skewY(-30deg) rotate(60deg); 
 
    background-color:rgba(0,0,0,.2); 
 
    transition:background-color .3s; 
 
    border-left:2px solid #000; 
 
    border-right:2px solid #000; 
 
    box-sizing:border-box; 
 
    -webkit-backface-visibility:hidden; 
 
} 
 
#categories li div:hover, #categories .up:hover span:after{ 
 
    background-color:rgba(0,0,0,.5); 
 
} 
 
#categories li div:before, #categories li div:after{ 
 
    content:''; 
 
    position:absolute; 
 
    width:100%;height:49.6%; 
 
    left:-2px;top:25.5%; 
 
    
 
    border-left:2px solid #000; 
 
    border-right:2px solid #000; 
 
    transform:rotate(60deg); 
 
    visibility:visible; 
 
} 
 
#categories li div:before{ 
 
    transform:rotate(-60deg); 
 
} 
 

 
#categories li img{ 
 
    display:block; 
 
    left:-100%; right:-100%; 
 
    width: auto; height:100%; 
 
    margin:0 auto; 
 
    visibility:visible; 
 
} 
 
#categories .up, #categories .up div{ 
 
    transform-style:preserve-3d; 
 
    overflow:visible; 
 
    visibility:hidden; 
 
    background-color:transparent; 
 
} 
 
#categories .up span{ 
 
    display:block; 
 
    width:100%;height:100%; 
 
    position:absolute; 
 
    top:0; left:0; 
 
    overflow:hidden; 
 
} 
 
#categories .up span:after{ 
 
    content:''; 
 
    position:absolute; 
 
    left:0;top:0; 
 
    width:100%;height:100%; 
 
    border-left:2px solid #000; 
 
    border-right:2px solid #000; 
 
    box-sizing:border-box; 
 
    background-color:rgba(0,0,0,.2); 
 
    transform: skewY(-30deg) rotate(60deg); 
 
    transition:background-color .3s; 
 
    visibility:visible; 
 
} 
 

 
#categories .up img{ 
 
    width:100%; height:auto; 
 
    position:absolute; 
 
    transform-origin: 50% 100%; 
 
    transform: rotateX(-45deg); 
 
    z-index:1; 
 
}
<ul id="categories" class="clr"> 
 
\t <li><div></div></li> 
 
    <li class="up"><span></span><div><img src="https://farm9.staticflickr.com/8461/8048823381_0fbc2d8efb.jpg" alt=""/></div></li> 
 
    <li><div></div></li> 
 
    <li><div></div></li> 
 
    <li class="up"><span></span><div><img src="https://farm7.staticflickr.com/6217/6216951796_e50778255c.jpg" alt=""/></div></li> 
 
    <li class="pusher"></li> 
 
    <li class="pusher"></li> 
 
    <li class="pusher"></li> 
 
    <li><div></div></li> 
 
    <li class="pusher"></li> 
 
    <li><div></div></li> 
 
    <li><div></div></li> 
 
    <li><div></div></li> 
 
    <li class="pusher"></li> 
 
    <li><div></div></li> 
 
    <li class="up"><span></span><div><img src="https://farm5.staticflickr.com/4144/5053682635_b348b24698.jpg" alt=""/></div></li> 
 
    <li class="pusher"></li> 
 
    <li><div></div></li> 
 
    <li><div></div></li> 
 
</ul>

Эта сетка из шестиугольников может быть адаптирована к нескольким прецедентам (количество шестиугольников в ряд, расположение шестигранников ...) еще примеры в этой коллекции: Responsive grids of hexagons

+0

К сожалению, это не работает для моего использования дело. Мне нужны шестиугольники, чтобы они выглядели так, как в моем примере с границей, и мне также нужны изображения, чтобы встать из угловой плоскости (ваши параллельны с плоскостью). – VirtuosiMedia

+0

@ VirtuosiMedia Я понимаю, что вы имеете в виду. Я изменил ответ, и изображения теперь встают с угловой панели. Если это вам подходит, я найду решение для шестиугольников. –

+0

Это ближе, но я не могу сказать в вашем примере, если перспектива такая же, что и строк или столбцов недостаточно. Кроме того, изображения должны быть внутри того же контейнера, что и шестнадцатеричный, причем оба они появляются одновременно. – VirtuosiMedia

1

Поскольку обработка 3d-преобразования на SVGElements является проблемой, решение может создать другой перекрывающийся элемент для добавления преобразованных элементов;

Самое сложное в этом решении - найти значения для оптимального рендеринга;

кроме удаления перспективы в #hexGrid свойство преобразования (CSS) разметка должна быть такой же, как в исходном вопросе, вся работа выполняется через JS.

//function for checking transform property in css 
 
function checkCSS(selector,prop){ 
 
    var sel; 
 
    [].slice.call(document.styleSheets).forEach(function(x){ 
 
     sel= [].slice.call(x.rules).filter(function(rule){ 
 
      return rule.selectorText=='#hexGrid'; 
 
     }) 
 
     return sel 
 
    }) 
 
    return sel[sel.length-1].style[prop] 
 
    
 
} 
 
//store transform property 
 
var storeTrans = checkCSS('#hexGrid','transform'); 
 

 
//straighten svg 
 
var hexGrid = document.getElementById('hexGrid'); 
 
hexGrid.style.transform = 'rotateX(0)'; 
 

 
//get the position/dimensions for perfectly tilted red squares 
 
var rects=document.querySelectorAll('rect'); 
 
var coorArray = [].slice.call(rects).map(function(x){return x.getBoundingClientRect()}) 
 

 

 

 
var stationMap = document.getElementById('stationMap'); 
 
//create element for creating an layer and append 
 
var container = document.createElement('div'); 
 
container.className='container'; 
 
container.style.perspective='33vW';//reduced for simulating foreground 
 
container.style.height=container.style.width = '100%'; 
 
container.style.transform='translateY(-100%) rotateX(45deg) scale(1.6)'; 
 
stationMap.appendChild(container); 
 

 
//create perfectly tilted red squares 
 
coorArray.forEach(function(x){ 
 
    
 
var el = document.createElement('div') 
 
el.style.position='absolute'; 
 
el.style.top= x.top+'px'; 
 
el.style.left=x.left+'px'; 
 
el.style.width= x.width+'px'; 
 
el.style.height= x.height+'px'; 
 
el.style.background= 'tomato'; 
 
el.style.transform='perspective(12vw) rotateX(130deg) translate3d(-15%, 50%,0)'; 
 

 
container.appendChild(el) 
 
}) 
 

 

 

 
//set prosperctive and transform-style on common parent node 
 
stationMap.style.transformStyle='preserve-3d'; 
 
stationMap.style.perspective='44vw'; 
 
//set transform value back and rip out old rect 
 
hexGrid.style.transform = storeTrans; 
 
Array.prototype.slice.call(rects).forEach(function(n){ 
 
    n.parentNode.removeChild(n) 
 
})
.display { 
 
    animation: displayFlicker 100ms cubic-bezier(.37, 0, .41, 1.74) 100ms 1 normal forwards; 
 
    -webkit-animation: displayFlicker 100ms cubic-bezier(.37, 0, .41, 1.74) 100ms 1 normal forwards; 
 
    background: #000; 
 
    display: block; 
 
    border-left: 0.25rem solid #000; 
 
    border-right: 0.25rem solid #000; 
 
    box-sizing: border-box; 
 
    -moz-box-sizing: border-box; 
 
    height: 480px; 
 
    overflow: hidden; 
 
    width: 1096px; 
 
} 
 
#hexGrid { 
 
    box-sizing: border-box; 
 
    -moz-box-sizing: border-box;  
 
    display: block; 
 
    height: 100%; 
 
    -webkit-transform: rotateX(45deg) scale3d(1.6, 1.6, 1.6); /*add perspective to parent*/ 
 
    -moz-transform: rotateX(45deg) scale3d(1.6, 1.6, 1.6);  
 
    -ms-transform: rotateX(45deg) scale3d(1.6, 1.6, 1.6); 
 
    -o-transform:rotateX(45deg) scale3d(1.6, 1.6, 1.6); 
 
    transform: rotateX(45deg) scale3d(1.6, 1.6, 1.6); 
 
    transform-style: preserve-3d; 
 
    width: 100%; 
 
} 
 
.hexContainer { 
 
    outline: none; 
 
    transform-style: preserve-3d; 
 
} 
 
.hex { 
 
    box-sizing: border-box; 
 
    -moz-box-sizing: border-box; 
 
    display: inline-block; 
 
    height: 4.4vmin; 
 
    opacity: 1; 
 
    outline: none; 
 
    position: relative; 
 
    stroke: #0CF; 
 
    stroke-width: 0.0625rem; 
 
    transform: scale3d(1, 1, 1); 
 
    transition: all linear 300ms; 
 
    width: 8vmin; 
 
} 
 
.hex.open { 
 
    fill: rgba(0, 204, 255, 0.3); 
 
} 
 
.hex.blocked { 
 
    fill: url(#blockedHexPattern); 
 
    fill-opacity: 0.3; 
 
} 
 
.hexContainer:focus .open, .hexContainer:hover .open { 
 
    cursor: pointer; 
 
    fill: rgba(0, 204, 255, 0.8); 
 
    outline: none; 
 
} 
 
.hexContainer:focus .blocked, .hexContainer:hover .blocked { 
 
    cursor: pointer; 
 
    fill: url(#blockedHexPattern); 
 
    fill-opacity: 1; 
 
    outline: none; 
 
} 
 
.hexContainer:focus .occupied, .hexContainer:hover .occupied { 
 
    cursor: pointer; 
 
    fill: rgba(50, 50, 50, 0.8); 
 
    outline: none; 
 
} 
 
.hexContainer:focus .open, .hexContainer:focus .open.unblock { 
 
    transform-origin: 50% 0%; 
 
} 
 
.hexContainer:focus .blocked { 
 
    opacity: 1; 
 
    transform-origin: 50% 0%; 
 
} 
 
.hexContainer.active .open { 
 
    fill: rgba(0, 204, 255, 0.8); 
 
    opacity: 1; 
 
} 
 
#blockedHexPattern line { 
 
    stroke: #0CF; 
 
    stroke-width: 0.0625rem; 
 
} 
 
#hexGrid .rect { 
 
    transform: rotateX(0deg); 
 
}
<div id="stationMap" class="display"> 
 
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="55 -30 360 360" id="hexGrid"> 
 
     <defs> 
 
      <pattern x="0" y="0" height="10" width="10" patternUnits="userSpaceOnUse" id="blockedHexPattern"> 
 
       <line x1="0" y1="10" x2="10" y2="0"></line> 
 
      </pattern> 
 
     </defs> <a id="hex0-0" class="hexContainer"> 
 
     <polygon class="hex open" points="81.96152422706632,45 55.98076211353316,60 30,45 30.000000000000004,14.999999999999996 55.98076211353315,0 81.96152422706632,14.999999999999986"></polygon> 
 
    </a> 
 
<a id="hex0-2" class="hexContainer"> 
 
     <polygon class="hex blocked" points="185.88457268119896,45 159.9038105676658,60 133.92304845413264,45 133.92304845413264,14.999999999999996 159.9038105676658,0 185.88457268119896,14.999999999999986" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
<a id="hex0-6" class="hexContainer"> 
 
     <polygon class="hex blocked" points="393.7306695894642,45 367.749907475931,60 341.76914536239786,45 341.76914536239786,14.999999999999996 367.749907475931,0 393.7306695894642,14.999999999999986" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
<a id="hex0-7" class="hexContainer"> 
 
     <polygon class="hex blocked" points="445.6921938165305,45 419.71143170299734,60 393.7306695894642,45 393.7306695894642,14.999999999999996 419.71143170299734,0 445.6921938165305,14.999999999999986" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
<a id="hex1-0" class="hexContainer"> 
 
     <polygon class="hex open" points="55.98076211353316,90 30.000000000000004,105 4.01923788646684,90 4.019237886466843,60 29.999999999999993,45 55.98076211353315,59.999999999999986"></polygon> 
 
     <rect class="rect" fill="red" x="5" y="67.5" width="50" height="40"/> 
 
    </a> 
 
<a id="hex1-3" class="hexContainer"> 
 
     <polygon class="hex blocked" points="211.8653347947321,90 185.88457268119893,105 159.90381056766577,90 159.90381056766577,60 185.88457268119893,45 211.8653347947321,59.999999999999986" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
<a id="hex1-4" class="hexContainer"> 
 
     <polygon class="hex open" points="263.82685902179844,90 237.84609690826525,105 211.8653347947321,90 211.8653347947321,60 237.84609690826525,45 263.8268590217984,59.999999999999986"></polygon> 
 
    </a> 
 
<a id="hex1-5" class="hexContainer"> 
 
     <polygon class="hex open" points="315.7883832488647,90 289.80762113533154,105 263.8268590217984,90 263.8268590217984,60 289.80762113533154,45 315.7883832488647,59.999999999999986"></polygon> 
 
    </a> 
 
<a id="hex1-6" class="hexContainer"> 
 
     <polygon class="hex open" points="367.749907475931,90 341.76914536239786,105 315.7883832488647,90 315.7883832488647,60 341.76914536239786,45 367.749907475931,59.999999999999986"></polygon> 
 
    </a> 
 
<a id="hex1-7" class="hexContainer"> 
 
     <polygon class="hex open" points="419.71143170299734,90 393.7306695894642,105 367.749907475931,90 367.749907475931,60 393.7306695894642,45 419.71143170299734,59.999999999999986"></polygon> 
 
     <rect class="rect" fill="red" x="369" y="67.5" width="50" height="40"/> 
 
    </a> 
 
<a id="hex2-0" class="hexContainer"> 
 
     <polygon class="hex open" points="81.96152422706632,134.99999999999997 55.98076211353316,150 30,134.99999999999997 30.000000000000004,104.99999999999999 55.98076211353315,89.99999999999999 81.96152422706632,104.99999999999997"></polygon> 
 
    </a> 
 
<a id="hex2-2" class="hexContainer"> 
 
     <polygon class="hex blocked" points="185.88457268119896,134.99999999999997 159.9038105676658,150 133.92304845413264,134.99999999999997 133.92304845413264,104.99999999999999 159.9038105676658,89.99999999999999 185.88457268119896,104.99999999999997" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
<a id="hex2-3" class="hexContainer"> 
 
     <polygon class="hex open" points="237.84609690826525,134.99999999999997 211.8653347947321,150 185.88457268119893,134.99999999999997 185.88457268119893,104.99999999999999 211.8653347947321,89.99999999999999 237.84609690826525,104.99999999999997"></polygon> 
 
    </a> 
 
<a id="hex2-4" class="hexContainer"> 
 
     <polygon class="hex open" points="289.80762113533154,134.99999999999997 263.8268590217984,150 237.84609690826522,134.99999999999997 237.84609690826522,104.99999999999999 263.8268590217984,89.99999999999999 289.80762113533154,104.99999999999997"></polygon> 
 
    </a> 
 
<a id="hex2-5" class="hexContainer"> 
 
     <polygon class="hex open" points="341.76914536239786,134.99999999999997 315.7883832488647,150 289.80762113533154,134.99999999999997 289.80762113533154,104.99999999999999 315.7883832488647,89.99999999999999 341.76914536239786,104.99999999999997"></polygon> 
 
    </a> 
 
<a id="hex2-6" class="hexContainer"> 
 
     <polygon class="hex open" points="393.7306695894642,134.99999999999997 367.749907475931,150 341.76914536239786,134.99999999999997 341.76914536239786,104.99999999999999 367.749907475931,89.99999999999999 393.7306695894642,104.99999999999997"></polygon> 
 
    </a> 
 
<a id="hex2-7" class="hexContainer"> 
 
     <polygon class="hex open" points="445.6921938165305,134.99999999999997 419.71143170299734,150 393.7306695894642,134.99999999999997 393.7306695894642,104.99999999999999 419.71143170299734,89.99999999999999 445.6921938165305,104.99999999999997"></polygon> 
 
    </a> 
 
<a id="hex3-0" class="hexContainer"> 
 
     <polygon class="hex open" points="55.98076211353316,179.99999999999997 30.000000000000004,194.99999999999997 4.01923788646684,179.99999999999997 4.019237886466843,149.99999999999997 29.999999999999993,134.99999999999997 55.98076211353315,149.99999999999994"></polygon> 
 
    </a> 
 
<a id="hex3-3" class="hexContainer"> 
 
     <polygon class="hex blocked" points="211.8653347947321,179.99999999999997 185.88457268119893,194.99999999999997 159.90381056766577,179.99999999999997 159.90381056766577,149.99999999999997 185.88457268119893,134.99999999999997 211.8653347947321,149.99999999999994" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
<a id="hex3-5" class="hexContainer"> 
 
     <polygon class="hex blocked" points="315.7883832488647,179.99999999999997 289.80762113533154,194.99999999999997 263.8268590217984,179.99999999999997 263.8268590217984,149.99999999999997 289.80762113533154,134.99999999999997 315.7883832488647,149.99999999999994" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
<a id="hex3-7" class="hexContainer"> 
 
     <polygon class="hex blocked" points="419.71143170299734,179.99999999999997 393.7306695894642,194.99999999999997 367.749907475931,179.99999999999997 367.749907475931,149.99999999999997 393.7306695894642,134.99999999999997 419.71143170299734,149.99999999999994" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
<a id="hex4-0" class="hexContainer"> 
 
     <polygon class="hex open" points="81.96152422706632,224.99999999999997 55.98076211353316,239.99999999999997 30,224.99999999999997 30.000000000000004,194.99999999999997 55.98076211353315,179.99999999999997 81.96152422706632,194.99999999999994"></polygon> 
 
    </a> 
 
<a id="hex4-1" class="hexContainer"> 
 
     <polygon class="hex blocked" points="133.92304845413264,224.99999999999997 107.94228634059948,239.99999999999997 81.96152422706632,224.99999999999997 81.96152422706632,194.99999999999997 107.94228634059948,179.99999999999997 133.92304845413264,194.99999999999994" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
<a id="hex4-2" class="hexContainer"> 
 
     <polygon class="hex blocked" points="185.88457268119896,224.99999999999997 159.9038105676658,239.99999999999997 133.92304845413264,224.99999999999997 133.92304845413264,194.99999999999997 159.9038105676658,179.99999999999997 185.88457268119896,194.99999999999994" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
<a id="hex4-3" class="hexContainer"> 
 
     <polygon class="hex blocked" points="237.84609690826525,224.99999999999997 211.8653347947321,239.99999999999997 185.88457268119893,224.99999999999997 185.88457268119893,194.99999999999997 211.8653347947321,179.99999999999997 237.84609690826525,194.99999999999994" fill="url(#blockedHexPattern)"></polygon> 
 
    </a> 
 
<a id="hex4-4" class="hexContainer"> 
 
     <polygon class="hex open" points="289.80762113533154,224.99999999999997 263.8268590217984,239.99999999999997 237.84609690826522,224.99999999999997 237.84609690826522,194.99999999999997 263.8268590217984,179.99999999999997 289.80762113533154,194.99999999999994"></polygon> 
 
    </a> 
 
<a id="hex4-5" class="hexContainer"> 
 
     <polygon class="hex open" points="341.76914536239786,224.99999999999997 315.7883832488647,239.99999999999997 289.80762113533154,224.99999999999997 289.80762113533154,194.99999999999997 315.7883832488647,179.99999999999997 341.76914536239786,194.99999999999994"></polygon> 
 
    </a> 
 
<a id="hex4-6" class="hexContainer"> 
 
     <polygon class="hex open" points="393.7306695894642,224.99999999999997 367.749907475931,239.99999999999997 341.76914536239786,224.99999999999997 341.76914536239786,194.99999999999997 367.749907475931,179.99999999999997 393.7306695894642,194.99999999999994"></polygon> 
 
    </a> 
 

 
    </svg> 
 
</div>

fiddle

Сведение:

  1. мы наклонить SVG-элемент, это нормальное положение;

  2. получить координаты места размещения изображений/ящиков в сценарии без преобразования;

  3. создать новый элемент тех же размеров, который прилагается под слоем svg;

  4. создавать элементы для замены ящиков изображений на новый элемент (используя координаты, взятые из пункта 2);

  5. преобразовать новый элемент, добавив translateY(-100%) в качестве первого значения, чтобы он перекрывал svg;

  6. преобразовать элемент svg в то же значение добавленного элемента (явно без translateY(-100%)).


Чтобы сохранить эффект парения на SVG элементов, которые мы могли бы играть с укладкой содержимое (но оно ограничено - example).

Протестировано только на последнем хроме - отсутствует какая-либо другая поддержка браузера.