Logische Bewerkingen met CSS Variabelen

0
6

Heel vaak tijdens het gebruik van switch-variabelen (een variabele die is 0 of 1, een concept dat is uitgelegd in meer detail in op deze post), ik wou dat ik kon uitvoeren logische operaties op hen. We hebben geen functies zoals het niet(var(–i)) of en(var(–i), var(–k)) in CSS, maar we kunnen emuleren deze en meer met rekenkundige bewerkingen in een calc() functie.

Dit artikel zal u tonen wat calc() formules die we nodig hebben om te gebruiken voor elke logische bediening en uitleggen hoe en waarom ze worden gebruikt met een paar van de use cases die leiden tot het schrijven van dit artikel.

Hoe: de formules

niet

Dit is een vrij eenvoudig: trek de schakelaar variabele (laten we het noemen –j) 1:

–notj: calc(1 – var(–j))

Als –j 0 is, dan is –notj is 1 (1 – 0). Als j 1, dan –notj is 0 (1 – 1).

en

Nu, als u ooit hebt genomen elektronica klassen (in het bijzonder iets als Geprogrammeerde Logica Systemen of Geïntegreerde Schakelingen), dan weet je al welke formule we moeten hier gebruik van. Maar laten we niet meteen in.

De twee operanden geldt als en slechts als beide waar zijn. De twee operanden in ons geval twee-schakelaar variabelen (we noemen hen –k –en ik). Elk van hen kan worden, hetzij 0 of 1 zijn, onafhankelijk van de andere. Dit betekent dat we kunnen worden in één van de vier mogelijke scenario ‘ s:

  • –k: 0, –i: 0
  • –k: 0, –i: 1
  • –k: 1, –i: 0
  • –k: 1, –i: 1

Het resultaat van de operatie is 1 als beide onze switch variabelen 1 en 0 anders. Kijkend naar de andere kant, dit resultaat is 0 als minstens één van de twee schakelaar variabelen is 0.

Nu moet u denken aan het op deze manier: het resultaat van wat rekenkundige bewerking is 0 als minstens één van de twee operanden is 0? Dat is vermenigvuldiging, vermenigvuldigen iets door de 0 geeft het ons een 0!

Dus, –en de formule is:

–en: calc(var(–k)*var(–i))

Gezien elk van onze vier mogelijke scenario ‘ s, we hebben:

  • voor –k: 0, –ik: 0, hebben we dat-en is 0 (0*0)
  • voor –k: 0, –i: 1, hebben we dat-en is 0 (0*1)
  • voor –k: 1, –ik: 0, hebben we dat-en is 0 (1*0)
  • voor –k: 1, –i: 1, hebben we dat-en is 1 (1*1)

nand

Sinds nand is het niet en moeten we vervangen de –j in de formule met de formule en:

–nand: calc(1 – var(–k)*var(–i))

Voor elk van onze vier mogelijke scenario ‘ s, krijgen we:

  • voor –k: 0, –ik: 0, hebben we dat –nand is 1 (1 – 0*0 = 1 – 0)
  • voor –k: 0, –i: 1, hebben we dat –nand is 1 (1 – 0*1 = 1 – 0)
  • voor –k: 1, –ik: 0, hebben we dat –nand is 1 (1 – 1*0 = 1 – 0)
  • voor –k: 1, –i: 1, hebben we dat –nand is 0 (1 – 1*1 = 1 – 1)

of

Het resultaat van de operatie is 1 als ten minste één van onze switch variabelen 1 en 0 anders (als zowel van hen zijn 0).

De eerste instinct hier is om te gaan voor optellen, maar terwijl dat geeft 0 als beide –k –en ik zijn 0 en 1 als een 0 is en de andere is 1, het geeft ons 2 als zowel van hen zijn 1. Dus dat werkt niet echt.

Maar we kunnen gebruik maken van de goede oude wetten van De Morgan, een van die staten:

(A of B) = (not A) and (not B)

Dit betekent dat het resultaat van de operatie is de negatie van de samenwerking tussen de ontkenning van –k –en ik. Om dit in CSS, we hebben:

–of: calc(1 – (1 – var(–k))*(1 – var(–i)))

Voor elk scenario, krijgen we:

  • voor –k: 0, –ik: 0, hebben we dat –of is 0 (1 – (1 – 0)*(1 – 0) = 1 – 1*1 = 1 – 1)
  • voor –k: 0, –i: 1, dat wij dat hebben –of is 1 (1 – (1 – 0)*(1 – 1) = 1 – 1*0 = 1 – 0)
  • voor –k: 1, –ik: 0, hebben we dat –of is 1 (1 – (1 – 1)*(1 – 0) = 1 – 0*1 = 1 – 0)
  • voor –k: 1, –i: 1, dat wij dat hebben –of is 1 (1 – (1 – 1)*(1 – 1) = 1 – 0*0 = 1 – 0)

noch

Sinds noch is niet of, we hebben:

–noch: calc((1 – var(–k))*(1 – var(–i)))

Voor elk van onze vier mogelijke scenario ‘ s, krijgen we:

  • voor –k: 0, –ik: 0, hebben we dat –noch is 1 ((1 – 0)*(1 – 0) = 1*1)
  • voor –k: 0, –i: 1, hebben we dat –noch is 0 ((1 – 0)*(1 – 1) = 1*0)
  • voor –k: 1, –ik: 0, hebben we dat –noch is 0 ((1 – 1)*(1 – 0) = 0*1)
  • voor –k: 1, –i: 1, hebben we dat –noch is 0 ((1 – 1)*(1 – 1) = 0*0)

xor

Het resultaat van de xor-operatie is 1 wanneer een van de twee operanden is 1 en de andere is 0. Dit voelt lastiger op het eerste, maar als we denken dat we dit betekent dat de twee operanden moeten afwijken van het resultaat op 1 (anders 0), wij struikelen op de juiste rekenkundige bewerking te gebruiken in calc(): aftrekken!

Als –k –en ik zijn gelijk, dan worden afgetrokken –i –k geeft ons 0. Anders, als we het hebben –k: 0, –i: 1, het resultaat van dezelfde aftrekken -1; als we –k: 1, –i: 0 is, is het resultaat 1.

Dichtbij, maar niet helemaal! Krijgen We het resultaat dat we willen in drie van de vier scenario ‘ s, maar we nodig hebben om 1 -1 in de –k: 0, –i: 1 scenario.

Er is echter één ding dat -1, 0 en 1 gemeen hebben, is dat te vermenigvuldigen ze met zichzelf geeft ons de absolute waarde (dat is 1 voor zowel de -1 en 1). Dus de werkelijke oplossing is om te vermenigvuldig het verschil met zelf:

–xor: calc (((var–k) – var(–i))*(var(–k) – var(–i)))

Het testen van elk van onze vier mogelijke scenario ‘ s, we hebben:

  • voor –k: 0, –ik: 0, hebben we dat –xor is 0 ((0 – 0)*(0 – 0) = 0*0)
  • voor –k: 0, –i: 1, hebben we dat –xor is 1 ((0 – 1)*(0 – 1) = -1*-1)
  • voor –k: 1, –ik: 0, hebben we dat –xor is 1 ((1 – 0)*(1 – 0) = 1*1)
  • voor –k: 1, –i: 1, hebben we dat –xor is 0 ((1 – 1)*(1 – 1) = 0*0)

Waarom: Use-cases

Laten we eens kijken een paar van de voorbeelden die gebruik maken van logische operaties in CSS. Merk op dat ik niet in detail andere aspecten van deze demo ‘ s als ze buiten de scope van dit specifieke artikel.

Verbergen uitgeschakeld paneel alleen op kleine schermen

Dit is een use case kwam ik tijdens het werken aan een interactieve demo waarmee gebruikers controleren verschillende parameters te wijzigen van een visuele resultaat. Voor meer ervaren gebruikers is er ook een panel van geavanceerde besturingselementen, dat is standaard uitgeschakeld. Het kan echter wel zijn ingeschakeld in om toegang te krijgen tot handmatig regelen van nog meer parameters.

Sinds deze demo wordt verondersteld te reageren, de lay-out verandert met de viewport. We willen ook niet de dingen te krijgen gepropt op kleinere schermen als we dat kunnen vermijden, dus er is geen punt in het tonen van de geavanceerde besturing als ze zijn uitgeschakeld en we zijn in het smalle scherm het geval.

De screenshot collage hieronder toont de resultaten krijgen we voor elk van de vier scenario ‘ s mogelijk.

Collage van de mogelijke gevallen.

Dus laten we zien wat dit betekent in termen van CSS!

Ten eerste, op de <body>, maken we gebruik van een schakelaar die gaat van 0 in het smalle scherm zaak 1 in het brede scherm van het geval. We veranderen ook de flex-richting deze manier (als u wilt dat een meer gedetailleerde uitleg van hoe dit werkt, lees mijn tweede artikel over de DROGE schakelen met CSS variabelen).

body {
–k: var(–breed, 0);
display: flex;
flex-richting: var(–breed, kolom);

@media (oriëntatie: landschap) { –breed: 1 }
}

Wij hebben dan een tweede schakelaar aan de geavanceerde knoppen paneel. Deze tweede schakelaar is 0 als het selectievakje is uitgeschakeld en 1 als de checkbox is :aangevinkt. Met behulp van deze schakelaar, we geven onze geavanceerde bediening paneel met een handicap te kijken (via een filter keten) en we hebben ook uitschakelen (via aanwijzer-evenementen). Hier, niet handig, als we willen om het contrast te verlagen en de transparantie in de gehandicaptenzorg geval:

.geavanceerde {
–ik: var(–enabled, 0);
–noti: calc(1 – var(–i));
filter:
contrast(calc(1 – var(–noti)*.9))
dekking(calc(1 – var(–noti)*.7));
pointer-evenementen: var(–enabled, geen);

[id= “toggle”]: gecontroleerd ~ & { –enabled: 1 }
}

We willen de geavanceerde controles van het paneel om te verblijven uitgebreid als we in het brede scherm van het geval (dus als –k 1), ongeacht of het selectievakje is :aangevinkt of niet, of als het selectievakje is :gecontroleerd (dus als –ik is 1), ongeacht of we nu in het brede scherm het geval is of niet.

Dit is precies of de werking!

Zo berekenen we een –of variabele:

.geavanceerde {
/* hetzelfde als voorheen */
–of: calc(1 – (1 – var(–k))*(1 – var(–i)));
}

Als dit –of variabele is 0, dit betekent dat we in het smalle scherm case en onze selectievakje niet is aangevinkt, dus willen we naar nul, wordt de hoogte van de geavanceerde controles van het panel en ook de verticale marge:

.geavanceerde {
/* hetzelfde als voorheen */
marge: calc(var(–of)*#{$mv}) 0;
hoogte: calc(var(–of)*#{$h});
}

Dit geeft ons het gewenste resultaat (live demo).

Dezelfde formules gebruiken om de positie van meerdere vlakken van een 3D-vorm

Dit is een use case kwam ik tijdens het werken aan de persoonlijke project van CSS-ing Johnson vaste stoffen van deze zomer.

Laten we een kijkje nemen bij één van deze vormen, bijvoorbeeld de gyroelongated vijfhoekige rotunda (J25), om te zien hoe de logische operaties zijn nuttig hier.

De vorm die we willen krijgen.

Deze vorm is opgebouwd uit een vijfhoekige rotonde zonder de grote decagonal basis en een decagonal antiprism zonder de top decagon. De interactieve demo hieronder laat zien hoe deze twee componenten kunnen worden gebouwd door het vouwen van hun netten van gezichten in 3D en sloot zich vervolgens aan ons te geven in de vorm die we willen.

Zie de Pen door thebabydino (@thebabydino) op CodePen.

Zoals hierboven te zien is, de gezichten zijn een deel van de antiprism of een deel van de rotonde. Dit is waar we introduceren onze eerste schakelaar met variabele –ik. Dit is 0 voor de gezichten die een deel van de antiprism en 1 voor de gezichten die een deel van de rotonde. De antiprism gezichten een klas .medio omdat we het kunnen toevoegen van een andere rotonde naar de andere antiprism base en vervolgens de antiprism in het midden. De rotunda gezichten een klas .beker omdat dit deel lijkt een kopje koffie… zonder een handvat!

De rotonde ziet er uit als een omgekeerd kop zonder een handvat.

.medio { –i: 0 }
.kopje { –i: 1 }

De nadruk alleen op de laterale gezichten, deze kunnen een hoekpunt omhoog of omlaag. Dit is waar we introduceren onze tweede variabele-k). Deze is 0 als ze een hoekpunt omhoog wijst (zoals gezichten hebben .dir-klasse) en 1 als ze omgedraaid en hebben een hoekpunt naar beneden (deze gezichten een klas .rev)

.dir { –k: 0 }
.rev { –k: 1 }

De antiprism heeft 10 laterale gezichten (alle driehoeken) naar boven wijst, ieder aan een zijde van de decagonal base dat is ook een basis voor de samengestelde vorm. Het heeft ook 10 laterale gezichten (alle driehoeken als het goed is) naar beneden, ieder aan een zijde van de andere decagonal base (dat is ook de decagonal basis van de rotonde en is derhalve geen basis voor de samengestelde vorm).

De rotonde heeft 10 laterale gezichten naar boven wijzen, afwisselende driehoekjes en pentagon, ieder aan de decagonal base dat is ook een basis voor de antiprism (dus het is niet een basis voor de samengestelde vorm). Het heeft ook 5 laterale gezichten, alle driehoeken, omlaag, ieder aan een zijde van de vijfhoekige basis.

De interactieve demo hieronder laat ons toe om beter te zien van elk van deze vier groepen van gezichten door de aandacht te vestigen op een. U kunt gebruik maken van de pijlen onderaan het scherm om te kiezen welke groep geconfronteerd wordt gemarkeerd. U kunt ook de rotatie rond de y-as en de vorm van de kanteling.

Zie de Pen door thebabydino (@thebabydino) op CodePen.

Zoals eerder vermeld, de laterale worden de gezichten van beide driehoeken of vijfhoeken:

.s3gon { –p: 0 }
.s5gon { –p: 1 }

Omdat al hun laterale gezicht.lat) van zowel de antiprism en de rotunda heeft een rand gemeen met één van de twee basis gezichten van elke vorm noemen we deze gemeenschappelijke randen van de basis van de randen van het laterale gezichten.

De interactieve demo hieronder hoogtepunten van deze randen, hun eindpunt en hun mid punten en maakt het bekijken van de vormen uit verschillende hoeken dankzij de auto-rotaties om de y-as, die kan worden gestart/ onderbroken op elk moment en in de handleiding van rotaties om de x-as, die kan worden bestuurd via de schuifregelaars.

Zie de Pen door thebabydino (@thebabydino) op CodePen.

Om dingen makkelijker te maken voor onszelf, zetten we de transformatie-oorsprong van de .lat gezichten op het midden van de basis van de randen (onderste horizontale randen).

Aandacht voor de basis en randen, en hun middelpunten (live).

We ook zorgen dat we deze positie gezichten zoals deze middelpunten dood in het midden van de scène element dat ons hele 3D-vorm.

Met de transformatie-oorsprong samenvalt met het middelpunt van de base edge betekent dat een rotatie die we uitvoeren op een gezicht gaat gebeuren rond het middelpunt van de basis rand, zoals wordt geïllustreerd door de interactieve demo hieronder:

Zie de Pen door thebabydino (@thebabydino) op CodePen.

We plaatsen onze zijdelingse vlakken waar we willen dat ze worden in vier stappen:

  1. We roteren rond de y-as zodanig dat hun basis randen zijn nu parallel aan hun uiteindelijke positie. (Deze draait ook hun lokale systeem van coördinaten — de z-as van een element wijst altijd in de richting van dat element gezichten.)
  2. We vertalen ze zodanig dat hun basis randen samenvallen met hun uiteindelijke positie (langs de randen van de basis gezichten van de twee componenten).
  3. Als ze nodig hebben om een hoekpunt naar beneden, we draaien rond de z-as met een halve draai.
  4. We roteren rond de x-as in hun uiteindelijke positie

Deze stappen worden geïllustreerd door de interactieve demo hieronder, waar u kunt gaan door middel van hen, en ook draaien de hele vorm (met behulp van de play/pause toets voor de y-as rotatie en de schuifregelaar voor de x-as rotatie).

Zie de Pen door thebabydino (@thebabydino) op CodePen.

De y-as rotatie waarde is vooral gebaseerd op de nominale indices en minder op onze switch variabelen, hoewel het afhankelijk is van deze ook.

De structuur is als volgt:

– var n = 5; //- aantal randen/ hoeken van kleine basis

sectie.scene
//- 3D-vorm-element
.s3d
//- de gezichten, die elk een 2D-shape element.s2d)

//- laterale (.lat) antiprism (.mid) gezichten,
//- de eerste helft omhoog wijst (.dir), anderen omlaag (.rev)
//- alle van hen wordt driehoeken (.s3gon)
– for(var j = 0; j < 4*n; j++)
.s2d.mid.lat.s3gon(class=j < 2*n ? ‘dir’ : ‘rev’)

//- laterale (.lat) rotunda (.cup) gezichten die omhoog wijzen (.dir),
//- beide driehoeken (.s3gon) en vijfhoeken (.s5gon)
– for(var j = 0; j < n; j++)
.s2d.cup.lat.s3gon.dir
.s2d.cup.lat.s5gon.dir
//- laterale (.lat) rotunda (.cup) gezichten die punt omlaag (.rev)
/ / alle driehoeken (.s3gon)
– for(var j = 0; j < n; j++)
.s2d.cup.lat.s3gon.rev

//- base gezichten,
//- een voor de antiprism (.mid),
//- de andere voor de rotonde (.beker)
.s2d.mid.base class=`s${2*n}gon`)
.s2d.cup.base class=`s${n}gon`)

Dat geeft ons de volgende HTML-code:

<section class=”scene”>
<div class=”s3d”>
<!– LATERALE gezichten –>
<div class=”s2d midden van de lat s3gon dir”></div>
<!– 9 meer identieke gezichten,
we hebben dus 10 laterale antiprism gezichten naar boven –>

<div class=”s2d midden van de lat s3gon rev”></div>
<!– 9 meer identieke gezichten,
we hebben dus 10 laterale antiprism gezichten naar beneden –>

<div class=”s2d cup lat s3gon dir”></div>
<div class=”s2d cup lat s5gon dir”></div>
<!– 4 meer identieke paren,
we hebben dus 10 laterale rotunda gezichten naar boven –>

<div class=”s2d cup lat s3gon rev”></div>
<!– 4 meer identieke gezichten,
dus we hebben 5 laterale rotunda gezichten naar beneden –>

<!– BASE gezichten –>
<div class=”s2d midden van de basis s10gon”></div>
<div class=”s2d cup base s5gon”></div>
</div>
</section>

Dit betekent gezichten 0… 9 van de 10 laterale antiprism gezichten naar boven wijzen, faces 10… 19 zijn de 10 laterale antiprism gezichten naar beneden wijst, gezichten 20… 29 zijn de 10 laterale rotunda gezichten naar boven en gezichten 30… 34 zijn de 5 laterale rotunda gezichten naar beneden.

Dus wat we hier doen is een index –idx op de laterale gezichten.

$n: 5; // aantal randen/ hoeken van kleine basis

.lat {
@voor $ik van 0 tot 2*$n {
&:nth-child(#{2*$n}n + #{$i + 1}) { –idx: #{$i} }
}
}

Deze index begint bij 0 voor elke groep van gezichten, wat betekent dat de indices voor gezichten 0… 9, 10… 19 en 20… 29 van 0 tot en met 9, terwijl de indices voor gezichten 30… 34 van 0 tot en met 4. Geweldig, maar als we vermenigvuldigen deze indices met basis hoek1 van de gemeenschappelijke decagon om de y-as rotatie we willen bij deze stap:

–ay: calc(var(–idx)*#{$ba10gon});

transformeren: rotatey(var(–ay))

…dan krijgen we het volgende resultaat. Ik ben resultaat het uiteindelijke resultaat hier, want het is een beetje moeilijk om te zien wat er mis is door te kijken naar het tussenresultaat krijgen we na het toepassen van de rotatie rond de y-as.

Zie de Pen door thebabydino (@thebabydino) op CodePen.

Dit is niet helemaal wat we van plan waren voor!

Dus laten we zien wat problemen met het bovenstaande resultaat is en hoe ze op te lossen met de hulp van onze switch variabelen en booleaanse operaties op hen.

Het eerste probleem is dat de laterale antiprism gezichten naar boven moeten worden gecompenseerd door de helft van een reguliere decagon basis hoek. Dit betekent dat het toevoegen of aftrekken van .5 uit –idx voordat vermenigvuldigen met de base hoek, maar alleen voor deze gezichten.

Zie de Pen door thebabydino (@thebabydino) op CodePen.

De gezichten die we willen richten zijn de gezichten die aan beide –ik –en k zijn 0, dus wat we moeten hier is vermenigvuldigen het resultaat van hun noch met .5:

–noch: calc((1 – var(–k))*(1 – var(–i)));
–j: calc(var(–idx) + var (- noch)*.5);
–ay: calc(var(–j)*#{$ba10gon});

transformeren: rotatey(var(–ay));

Het tweede probleem is dat de laterale rotunda gezichten naar beneden worden niet verdeeld zoals ze zouden moeten zijn, zodanig dat elk van hen heeft een basis rand gemeen met de basis van het pentagon en het hoekpunt tegenover de base gemeen met de driehoekige rotunda gezichten naar boven wijzen. Dit betekent vermenigvuldigen –idx door 2, maar alleen voor deze gezichten.

Zie de Pen door thebabydino (@thebabydino) op CodePen.

Wat we targeting nu zijn de gezichten die zowel aan –en –k 1 (dus de gezichten voor dat het resultaat van de operatie is 1), wat we dus nodig hebben is om te vermenigvuldigen –idx met 1 plus hun en:

–en: calc(var(–k)*var(–i));
–noch: calc((1 – var(–k))*(1 – var(–i)));
–j: calc((1 + var(–en))*var(–idx) + var (- noch)*.5);
–ay: calc(var(–j)*#{$ba10gon});

transformeren: rotatey(var(–ay));

De volgende stap is de vertaling die we gebruiken translate3d(). We bewegen niet elk van onze gezichten naar links of rechts, zodat de waarde langs de x-as is altijd 0. We verplaatsen ze echter verticaal (langs de y-as) en vooruit (langs de z-as)

Verticaal, willen we de beker gezichten die later zal krijgen gedraaid naar de punt naar beneden naar hun basis rand in het vlak van de klein (vierkant) basis van de beker (en van de samengestelde vorm). Dit betekent dat de gezichten die –ik is 1 en –k-1 is verplaatst tot (negatieve richting) door de helft van de totale hoogte van de samengestelde vorm (een totale hoogte die we hebben berekend op $h). We moeten dus de en bediening hier.

// hetzelfde als voorheen,
–en: calc(var(–i)*var(–k));
–y: calc(var(–en)*#{-.5*$h});

transformeren: rotatey(var(–ay))
translate3d(0, var(–y, 0), var(–z, 0));

We willen ook alle andere cup gezichten en de antiprism gezichten die uiteindelijk naar beneden wijzen naar hun basis rand in de gemeenschappelijke vliegtuig tussen de kop en de antiprism. Dit betekent dat de gezichten die –ik is 1 en –k is 0 als de gezichten die aan –0 –k-1 vertaald naar beneden (positieve richting) door de helft van de hoogte van de samengestelde vorm en vervolgens een back-up van (negatieve richting) door de hoogte van de antiprism ($h-mid). En wat weet je, dit is de xor operatie!

// hetzelfde als voorheen,
–xor: calc (((var–k) – var(–i))*(var(–k) – var(–i)));
–en: calc(var(–i)*var(–k));
–y: calc(var(–xor)*#{.5*$h $h-mid} –
var(–en)*#{.5*$h});

transformeren: rotatey(var(–ay))
translate3d(0, var(–y, 0), var(–z, 0));

Tot slot willen we de antiprism gezichten die blijft wijzen tot in de bodem vlak van de samengestelde vorm (en van de antiprism). Dit betekent dat de gezichten die aan –0 –k) 0 vertaald naar beneden (positieve richting) door de helft van de totale hoogte van de samengestelde vorm. Dus wat we hier gebruiken, is het noch de bediening!

// hetzelfde als voorheen,
–noch: calc((1 – var(–k))*(1 – var(–i)));
–xor: calc (((var–k) – var(–i))*(var(–k) – var(–i)));
–en: calc(var(–i)*var(–k));

–y: calc(var (- noch)*#{.5*$h} +
var(–xor)*#{.5*$h $h-mid} –
var(–en)*#{.5*$h});

transformeren: rotatey(var(–ay))
translate3d(0, var(–y, 0), var(–z, 0));

Zie de Pen door thebabydino (@thebabydino) op CodePen.

Langs de z-richting, we willen verder de gezichten zodanig dat hun basis randen samenvallen met de randen van de basis gezichten van de samengestelde vorm of de randen van de gemeenschappelijke basis (dat is niet het gezicht van de samengestelde vorm) gedeeld door de twee 3D-onderdelen. Voor de top gezichten van de beker (die we later draaien naar de punt naar beneden), wordt de plaatsing op de hoeken van een vijfhoek, terwijl voor alle andere gezichten van de samengestelde vorm, de plaatsing is aan de randen van een decagon.

Dit betekent dat de gezichten die –ik is 1 en –k-1 vertaald naar voren door de inradius van de vijfhoekige basis terwijl alle andere gezichten krijgen vertaald naar voren door de inradius van een decagonal base. Dus de activiteiten die we hier zijn en en nand!

// hetzelfde als voorheen,
–en: calc(var(–i)*var(–k));
–nand: calc(1 – var(–en));
–z: calc(var(–en)*#{$ri5gon} + var(–nand)*#{$ri10gon});

transformeren: rotatey(var(–ay))
translate3d(0, var(–y, 0), var(–z, 0));

Zie de Pen door thebabydino (@thebabydino) op CodePen.

Vervolgens willen we allemaal .rev (waarvoor –k 1) gezichten punt naar beneden. Dit is vrij eenvoudig en vereist geen logische bediening, we moeten gewoon het toevoegen van een halve draai rotatie rond de z-as naar de transformatie keten, maar alleen voor de gezichten waarvoor –k 1:

// hetzelfde als voorheen,
–az: calc(var(–k)*.5turn);

transformeren: rotatey(var(–ay))
translate3d(0, var(–y), var(–z))
draaien(var(–az));

Zie de Pen door thebabydino (@thebabydino) op CodePen.

De vijfhoekige vlakken (waarvoor –p 1) zijn dan alle roteren rond de x-as door een bepaalde hoek:

–ax: calc(var (- p)*#{$ax5});

In het geval van de driehoekige vlakken (waarvoor –p is 0, wat betekent dat we moeten gebruiken –notp), we hebben een zekere hoekverdraaiing van de gezichten van de antiprism ($ax3-mid), de andere hoek voor de gezichten van de rotonde die omhoog wijzen ($ax3-cup-dir) en nog een andere invalshoek voor de rotonde gezichten naar beneden ($ax3-cup-red).

De antiprism gezichten die –ik is 0, dus moeten we vermenigvuldigen met de bijbehorende waarde voor de hoek met –noti hier. De rotunda gezichten die –ik is 1, en uit deze, degenen die naar boven wijzen die –k is 0 en de trappen naar beneden die –k is 1.

–notk: calc(1 – var(–k));
–noti: calc(1 – var(–i));
–notp: calc(1 – var (- p));

–ax: calc(var(–notp)*(var(–noti)*#{$ax3-mid} +
var(–i)*(var(–notk)*#{$ax3-cup-dir} + var(–k)*#{$ax3-cup-rev})) +
var (- p)*#{$ax5});

transformeren: rotatey(var(–ay))
translate3d(0, var(–y), var(–z))
draaien(var(–az))
rotatex(var(–ax));

Dit geeft ons het uiteindelijke resultaat!

Zie de Pen door thebabydino (@thebabydino) op CodePen.

1 Voor elke regelmatige veelhoek (zoals een van de gezichten van onze vormen), de arc overeenkomt met één van de rand, als de hoek tussen de circumradii aan deze van de rand van de uiteinden (onze basis-hoek) is een volledige cirkel (360°) in de randen. In het geval van een gelijkzijdige driehoek, de hoek is 360°/3 = 120°. Voor een regelmatige vijfhoek, de hoek is 360°/5 = 72°. Voor een regelmatige decagon de hoek van de 360°/10 = 36°. ↪️

Zie de Pen door thebabydino (@thebabydino) op CodePen.