SVG 纹理平铺平面

问题描述 投票:0回答:1

我正在尝试在 SVG 中平铺飞机,但不幸的是我无法使用 css3 透视作为其在 safari 中的越野车。我尝试了使用固定透视图块的 skewX。它有点有效,但我认为数学是错误的?有人有在 CSS 中平铺飞机的数学经验吗?

我希望镜子瓷砖能够保持对齐,但在 5 列之后它们似乎没有对齐。

:root {
  --baseWidth: 97;
  --baseFactor: calc(5/8);
}

#sRows use:nth-child(even) {
  --f1: #ff0;
  --f2: #000;
  --col: var(--f1);
}

#sRows use:nth-child(odd) {
  --f1: #000;
  --f2: #ff0;
  --col: var(--f1);
}

#mCol use:nth-child(even) {
  --f: var(--f1);
}

#mCol use:nth-child(odd) {
  --f: var(--f2);
}

#mCol use {
  --x: calc(var(--baseWidth) * var(--i));
  --s: calc(89 - calc(30 / var(--i)));
}

#mCol use:first-child {
  --s: calc(91 - calc(30 / var(--i)));
}

#mirrorLeft {
  transform: skewX(calc( var(--s) * -1deg)) translate(calc(var(--x) * -1px));
}

#mirrorRight {
  transform: skewX(calc( var(--s) * 1deg)) translate(calc(var(--x) * 1px));
}

#sRows use {
  --rx: calc(240 - calc(204 * pow(var(--baseFactor), calc( var(--ri) + 1))));
  --ry: calc(88 + calc( 90 * pow( var(--baseFactor), var(--ri))));
  --rz: calc( var(--baseWidth) * pow(var(--baseFactor), var(--ri)));
  transform: translate(calc(var(--rx)*1px), calc( var(--ry) * 1px)) scale(calc(var(--rz)*1.66%));
}
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="180">
   <defs>
      <symbol id="tileTemplate" overflow="hidden" >
         <path style="fill:var(--f)" d="M 31.5 0 H 127.5 L 160 35 H 0 Z" opacity=".5" />
         <?ignore
         <g >
            <path style="fill:var(--f)" d="M 31.5 0 H 128.5 L 160 35 H 0 Z" opacity=".25"/>
            <g opacity=".5" >
               <path d="m 79 23.3471 l -0.208 11.433 m 30.182 -20.888 l 3.75 8.6 m -64.112 -8.6 l -4.063 8.6 m 100.9347 1.3838 l 9.1319 9.852 M 130 6.5311 l 6.003 7.031 M 79 6.5311 L 78.873 13.5621 m 24.23 -13.135 l 2.435 5.585 M 54.971 0.4271 L 52.333 6.0121" style="stroke:#fff;stroke-width:2"/>
               <path d="m 147.571,22.984 10.177,11 M 81,22.984 81.208,34.417 m 30.18,-20.888 4.063,8.6 m -64.425,-8.6 -3.75,8.6 m 85.327,-15.961 6.003,7.031 M 81,6.168 l 0.127,7.031 m 23.902,-13.135 2.638,5.585 M 56.897,0.064 54.462,5.649" style="stroke:#000000;stroke-width:2" />
               <path d="m 0.665,33.984 h 158.67 M 11.44,22.554 H 148.56 M 20.063,13.2 H 140.189 M 26.6,5.907 h 106.88" style="stroke:#000000;stroke-width:2"/>
            </g>
         </g>
         ?>
      </symbol>
      <symbol id="tRow" overflow="visible">
         <use href="#tileTemplate" style="--f:var(--col)" />
         <use href="#mCol" />
      </symbol> 
      <symbol id="mSkew" overflow="visible" >
         <use id="mirrorRight" href="#tileTemplate"   />
         <use id="mirrorLeft"  href="#tileTemplate"  />
      </symbol>
      <symbol id="mCol" overflow="visible" >
         <use href="#mSkew" style="--i:1"  />
         <use href="#mSkew" style="--i:2 " />
         <use href="#mSkew" style="--i:3 " />
         <use href="#mSkew" style="--i:4 " />
         <use href="#mSkew" style="--i:5 " />
         <use href="#mSkew" style="--i:6 " />
         <use href="#mSkew" style="--i:7 " />
         <use href="#mSkew" style="--i:8 " />
         <use href="#mSkew" style="--i:9 " />
         <use href="#mSkew" style="--i:10" />
         <use href="#mSkew" style="--i:11" />
         <use href="#mSkew" style="--i:12" />
         <use href="#mSkew" style="--i:13" />
         <use href="#mSkew" style="--i:14" />
         <use href="#mSkew" style="--i:15" />
         <use href="#mSkew" style="--i:16" />
         <use href="#mSkew" style="--i:17" />
         <use href="#mSkew" style="--i:18" />
         <use href="#mSkew" style="--i:19" />
         <use href="#mSkew" style="--i:20" />
         <use href="#mSkew" style="--i:21" />
         <use href="#mSkew" style="--i:22" />
         <use href="#mSkew" style="--i:23" />
         <use href="#mSkew" style="--i:24" />
         <use href="#mSkew" style="--i:25" />
         <use href="#mSkew" style="--i:26" />
         <use href="#mSkew" style="--i:27" />
         <use href="#mSkew" style="--i:28" />
         <use href="#mSkew" style="--i:29" />
         <use href="#mSkew" style="--i:30" />
         <use href="#mSkew" style="--i:31" />
         <use href="#mSkew" style="--i:32" />
      </symbol>  
   </defs>
   <g id="sRows" class="scaleRows" >
      <use href="#tRow" style="--ri:1;"/>
      <use href="#tRow" style="--ri:2;" />
      <use href="#tRow" style="--ri:3;" />
      <use href="#tRow" style="--ri:4;" />
      <use href="#tRow" style="--ri:5;" />
      <use href="#tRow" style="--ri:6;" />
      <use href="#tRow" style="--ri:7;" />
      <use href="#tRow" style="--ri:8;" />
   </g>
   <g transform="translate(240)" display="inline" opacity=".5" >
      <path d="M 0,0 -80,180 M 0,0 80,180" style="stroke:#888;stroke-width:0.5"/>
      <path d="M -240,145 H 240" style="stroke:#0f0;stroke-width:.5;stroke-dasharray:1, 1" />
      <path d="M 0,90 -80,180 M 0,90 80,180" style="stroke:#00f;stroke-width:.5;stroke-dasharray:1, 1"  />
   </g>
</svg>

css svg tile
1个回答
0
投票

为了使计算尽可能简单,您的焦点应位于用户坐标系的

[0, 0]
处。然后,当你绘制了一个基础图块后,需要两个特征数字:

--width: x distance between the two lower corners / y value of the lower corners
--height: y value of the upper corners / y value of the lower corners

对于我的示例,我分别选择它们为

0.2
0.9

然后,每行的倾斜图块可以计算为

transform: skewX(atan(var(--width) * [0, 1, 2,...]));

每行的缩放比例为

transform: scale(pow(var(--height), [0, 1, 2,...]));

您可以添加负数以从基础图块沿相反方向继续,而不是显式镜像。对于水平和垂直平铺都是如此。

:root {
  --width: 0.2;
  --height: 0.9;
}

use[href="#tile"] {
  fill: none;
  transform: skewX(atan(var(--width, 0) * var(--x)));
}

use[href="#row"] {
  transform: scale(pow(var(--height), var(--y)));
}

use[href="#row"]:nth-child(even) {
  --even: red;
  --odd: darkgreen;
}

use[href="#row"]:nth-child(odd) {
  --even: darkgreen;
  --odd: red;
}

use[href="#tile"]:nth-child(even) {
  stroke: var(--even);
}

use[href="#tile"]:nth-child(odd) {
  stroke: var(--odd);
}

use#base {
  stroke: black;
}
<svg viewBox="-100 50 200 100">
  <defs>
    <path id="tile" d="M -9.4,90 H 8.6 M -9.25,92.4 H 8.75 L 9,94.8 M -9.5,94.8 H 9.5 M -9.75,97.4 H 9.25 L 9.5,100 M -4.5,90 -4.625,92.4 M -4.75,94.8 -4.875,97.4 M 4.5,90 4.625,92.5 M 4.75,94.8 4.875,97.4 M 0,92.5 V 94.8 M 0,97.4 V 99.5"/>
    <g id="row">
      <use href="#tile" style="--x:-10"/>
      <use href="#tile" style="--x:-9"/>
      <use href="#tile" style="--x:-8"/>
      <use href="#tile" style="--x:-7"/>
      <use href="#tile" style="--x:-6"/>
      <use href="#tile" style="--x:-5"/>
      <use href="#tile" style="--x:-4"/>
      <use href="#tile" style="--x:-3"/>
      <use href="#tile" style="--x:-2"/>
      <use href="#tile" style="--x:-1"/>
      <use href="#tile" style="--x:0"/>
      <use href="#tile" style="--x:1"/>
      <use href="#tile" style="--x:2"/>
      <use href="#tile" style="--x:3"/>
      <use href="#tile" style="--x:4"/>
      <use href="#tile" style="--x:5"/>
      <use href="#tile" style="--x:6"/>
      <use href="#tile" style="--x:7"/>
      <use href="#tile" style="--x:8"/>
      <use href="#tile" style="--x:9"/>
      <use href="#tile" style="--x:10"/>
    </g>
  </defs>
  <use href="#row" style="--y:-4"/>
  <use href="#row" style="--y:-3"/>
  <use href="#row" style="--y:-2"/>
  <use href="#row" style="--y:-1"/>
  <use href="#row" style="--y:0"/>
  <use href="#row" style="--y:1"/>
  <use href="#row" style="--y:2"/>
  <use href="#row" style="--y:3"/>
  <use href="#row" style="--y:4"/>
  <use href="#row" style="--y:5"/>
  <use href="#row" style="--y:6"/>
  <use href="#row" style="--y:7"/>
  <use href="#row" style="--y:8"/>
  <!-- repeat the base tile just to mark its position -->
  <use id="base" href="#tile"/>
</svg>

© www.soinside.com 2019 - 2024. All rights reserved.