Как посчитать модуль числа в CSS
могу ли я посчитать модуль через CSS?
У меня есть такое выражение y = -34 * abs(x - 0.5) + 17 (x изменяется от 0 до 1)
Вот график такой функции, можно посмотреть: https://www.desmos.com/calculator/4zdruwvikn?lang=ru
Я бы хотел это вычислить в CSS, это возможно?
const blockNode = document.querySelector('.block');
const y = blockNode.computedStyleMap().get('transform')[0].y;
document.write(`${y.value}${y.unit}`);
.block {
--x: 0;
--y: calc(1px + 2px);
transform: translate(0px, var(--y));
background-color: red;
width: 50px;
height: 50px;
margin-bottom: 20px;
}
<div class="block">
</div>
Ответы (2 шт):
Я сделал: оказывается, функция max в CSS работает, can i use
Зачем я использовал max - чтобы найти модуль числа, необходимо сравнить
само число и его аддитивную инверсию(если проще -> умноженное на -1) и выбрать большее
const blockNode = document.querySelector('.block');
const y = blockNode.computedStyleMap().get('transform')[0].y
document.write(`${y.value}${y.unit}`);
@property {}
.block {
--x: 0.5;
--xPx: var(--x) * 1px;
--leftAbsX: calc( 1 * (var(--xPx) - 0.5px) );
--rightAbsX: calc( -1 * (var(--xPx) - 0.5px) );
--abs: max( var(--leftAbsX), var(--rightAbsX) );
--y: calc(-1 * 34 * var(--abs) + 17px);
transform: translate(0px, var(--y));
background-color: red;
width: 50px;
height: 50px;
margin-bottom: 20px;
}
<div class="block">
</div>
Зачем это всё делалось, пример с анимацией:
const blockNode = document.querySelector('.block');
const infoNode = document.querySelector('.info');
requestAnimationFrame(anim);
function anim(time) {
const angle = blockNode.computedStyleMap().get('transform')[0].angle;
infoNode.textContent = `${Math.round(angle.value)}${angle.unit}`;
requestAnimationFrame(anim);
}
@property --x {
syntax: '<number>';
inherits: false;
initial-value: 0;
}
.block {
--x: 0;
--leftAbsX: calc( 1 * (var(--x) - 0.5) );
--rightAbsX: calc( -1 * (var(--x) - 0.5) );
--abs: max( var(--leftAbsX), var(--rightAbsX) );
--deg: 17deg;
--rotate: calc(-2 * var(--deg) * var(--abs) + var(--deg));
transform: rotate(var(--rotate));
animation: anim 2s linear infinite alternate-reverse;
background-color: red;
width: 50px;
height: 50px;
margin-bottom: 20px;
display: grid;
place-items: center;
color: white;
font-size: 20px;
}
@keyframes anim {
0% {
--x: 0;
background-color: red;
}
100% {
--x: 1;
background-color: black;
}
}
<div class="block"></div>
<div class="info"></div>
Все нужные функции уже добавили в css, а дальше можно так:
/**************** ВЫЧИСЛЕНИЕ ****************/
/* переменные */
@property --x { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --y { syntax: "<number>"; inherits: true; initial-value: 0; }
body {
--x: -2;
--y: calc(-34 * abs(var(--x) - 0.5) + 17);
animation: x 60s steps(1024) infinite;
font-family: monospace;
}
@keyframes x {
from { --x: -2 }
to { --x: 2 }
}
/**************** ВЫВОД ****************/
/* умноженные на 1000 и округлённые */
@property --rx { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --ry { syntax: "<number>"; inherits: true; initial-value: 0; }
/* 3 цифры после точки */
@property --dx { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --dy { syntax: "<number>"; inherits: true; initial-value: 0; }
/* количество лидирующих нулей у дробной части */
@property --zx { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --zy { syntax: "<number>"; inherits: true; initial-value: 0; }
/* -1 если округлённое число отрицательное, иначе само число */
@property --nx { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --ny { syntax: "<number>"; inherits: true; initial-value: 0; }
body::before {
--rx: round(var(--x) * 1000);
--ry: round(var(--y) * 1000);
--dx: rem(abs(var(--rx)), 1000);
--dy: rem(abs(var(--ry)), 1000);
--zx: calc(
2
- min(round(to-zero, var(--dx) / 10), 1)
- min(round(to-zero, var(--dx) / 100), 1)
);
--zy: calc(
2
- min(round(to-zero, var(--dy) / 10), 1)
- min(round(to-zero, var(--dy) / 100), 1)
);
--nx: max(var(--rx), -1);
--ny: max(var(--ry), -1);
counter-reset:
x abs(round(to-zero, var(--rx) / 1000))
xxx var(--dx)
y abs(round(to-zero, var(--ry) / 1000))
yyy var(--dy);
content:
"f("
if(style(--nx: -1): "-"; else: "")
counter(x)
"."
if(style(--zx: 2): "00"; style(--zx: 1): "0"; else: "")
counter(xxx)
") = "
if(style(--ny: -1): "-"; else: "")
counter(y)
"."
if(style(--zy: 2): "00"; style(--zy: 1): "0"; else: "")
counter(yyy);
}
PS: Самая новая функция тут if - сейчас поддерживается только в Chrome 137+. В FF и Сафари пока не поддерживается.