Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Как при масштабировании сохранять пропорции у квадрата? (https://javascript.ru/forum/dom-window/82032-kak-pri-masshtabirovanii-sokhranyat-proporcii-u-kvadrata.html)

LADYX 04.03.2021 02:15

Как при масштабировании сохранять пропорции у квадрата?
 
Здравствуйте.

Есть родительских блок. С помощью ползунков я могу менять его ширину и высоту. Как при этом сохранять пропорции квадрата у дочернего блока, не меняя разметку html и css? Помогите, пожалуйста, не могу самостоятельно решить эту задачу. Благодарю!

<style>
#parent {width: 300px; height: 300px; padding: 10px; border: 5px solid red;}

#children {width: 300px; height: 300px; background: green;}
</style>

<p>height: <input id="parent_range_H" type="range" min="10" max="300" value="300" step="1" name="parent_h" oninput="parentH()">

width: <input id="parent_range_W" type="range" min="10" max="300" value="300" step="1" name="parent_w" oninput="parentW()"></p>

<div id="parent"><div id="children"></div></div>


function parentH() {
 parent_range = document.getElementById('parent_range_H');
 parent = document.getElementById('parent');
 parent.style.height = parent_range.value+'px';
 parent.height= 'px';
}
function parentW() {
 parent_range = document.getElementById('parent_range_W');
 parent = document.getElementById('parent');
 parent.style.width = parent_range.value+'px';
 parent.width= 'px';
}

рони 04.03.2021 08:14

LADYX,
у вас есть строка 4, что мешает написать такую же для children, и выкинуть строку 5.

у вас есть строка 10, что мешает написать такую же для children, и выкинуть строку 11.

LADYX 04.03.2021 12:57

рони,
приветствую вас!

Вот смотрите, если я делаю так:

<style>
#parent {width: 300px; height: 300px; padding: 10px; border: 5px solid red;}
#children {width: 300px; height: 300px; background: green;}
</style>

<p>height: <input id="parent_range_H" type="range" min="10" max="300" value="300" step="1" name="parent_h" oninput="parentH()">

width: <input id="parent_range_W" type="range" min="10" max="300" value="300" step="1" name="parent_w" oninput="parentW()"></p>

<div id="parent"><div id="children"></div></div>

<script>
parent = document.getElementById('parent');
 children = document.getElementById('children');
function parentH() {
 parent_range = document.getElementById('parent_range_H');
 parent.style.height = parent_range.value+'px';
 children.style.height = parent_range.value+'px';
 children.style.width = parent_range.value+'px';
 //parent.height= 'px';
}
function parentW() {
 parent_range = document.getElementById('parent_range_W');
 parent.style.width = parent_range.value+'px';
 children.style.height = parent_range.value+'px';
 children.style.width = parent_range.value+'px';
 //parent.width= 'px';
}
</script>


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

Но получаются глюки. А именно, если например мы сначала меняем высоту родительского элемента, то дочерний элемент сохраняет свои пропорции внутри родительского, что правильно. Но как только сразу после этого мы начинаем менять ширину родительского элемента, то дочерний элемент моментально оказывается за пределами своего родителя, а потом подстраивается в его размеры. То есть как бы на мгновение "выпрыгивает" из родителя. То же самое и наоборот: если сначала меняем ширину, а потом начинаем менять ширину, такое же поведение.

Вот как можно этого избежать? Помогите, пожалуйста, это уже, я так полагаю, сверх моих знаний))

И еще у меня такой вопрос: как можно здесь на сайте добавить воспроизводимый пример, чтобы при клике на кнопку "Посмотреть!" можно было его воспроизвести. Я вот html и css добавляю в теги html (кнопка - <>), а js в отдельном теге. В какой тег всё это завернуть, чтобы получился воспроизводимый пример? Что-то я не могу найти это в справке. Спасибо!

рони 04.03.2021 14:05

LADYX,
Пожалуйста, отформатируйте свой код!

Для этого его можно заключить в специальные теги: js/css/html и т.п., например:
[html run]
... минимальный код страницы с вашей проблемой
[/html]

О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting.

рони 04.03.2021 14:19

Цитата:

Сообщение от LADYX
Вот смотрите, если я делаю так:

не судьба сделать так
Цитата:

Сообщение от рони
LADYX,
у вас есть строка 4, что мешает написать такую же для children, и выкинуть строку 5.

у вас есть строка 10, что мешает написать такую же для children, и выкинуть строку 11.

<!DOCTYPE html>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        #parent {
            width: 300px;
            height: 300px;
            padding: 10px;
            border: 5px solid red;
        }

        #children {
            width: 300px;
            height: 300px;
            background: green;
        }
    </style>
    <script>
        function parentH() {
            let height = document.querySelector('#parent_range_H').value + 'px';
            document.querySelector('#parent').style.height = height;
            document.querySelector('#children').style.height = height;
        }

        function parentW() {
            let width = document.querySelector('#parent_range_W').value + 'px';
            document.querySelector('#parent').style.width = width;
            document.querySelector('#children').style.width = width;
        }
    </script>
</head>

<body>
    <p>height: <input id="parent_range_H" type="range" min="10" max="300" value="300" step="1" name="parent_h" oninput="parentH()">
        width: <input id="parent_range_W" type="range" min="10" max="300" value="300" step="1" name="parent_w" oninput="parentW()"></p>
    <div id="parent">
        <div id="children"></div>
    </div>
</body>

</html>

LADYX 04.03.2021 16:51

рони,
Цитата:

Сообщение от рони
Пожалуйста, отформатируйте свой код!

Да, отформатировал.

Цитата:

Сообщение от рони
не судьба сделать так

В смысле не судьба?))

Рони, смотрите, в вашем ответе дочерний блок (зеленый квадрат) не сохраняет свои пропорции, когда мы меняем размеры родительского блока.

В моем ответе пропорции квадрата сохраняются, что и должно быть. Но получается так, что квадрат "выпрыгивает" из своего родителя при изменении размеров родителя. Вот как этого избежать?

Или хорошо, если сделать по-другому? Например, дочернему блоку (зеленому квадрату) указать не жесткие размеры (в px), а указать проценты: и ширину, и высоту 100%. Вот пример:

<style>
#parent {width: 300px; height: 300px; padding: 10px; border: 5px solid red;}
#children {width: 100%; height: 100%; background: green;}
</style>

<p>height: <input id="parent_range_H" type="range" min="10" max="300" value="300" step="1" name="parent_h" oninput="parentH()">

width: <input id="parent_range_W" type="range" min="10" max="300" value="300" step="1" name="parent_w" oninput="parentW()"></p>

<div id="parent"><div id="children"></div></div>

<script>
parent = document.getElementById('parent');
 children = document.getElementById('children');
function parentH() {
 parent_range = document.getElementById('parent_range_H');
 parent.style.height = parent_range.value+'px';
}
function parentW() {
 parent_range = document.getElementById('parent_range_W');
 parent.style.width = parent_range.value+'px';
}
</script>


Если так, то как сделать, чтобы при любых изменениях размеров ширины или высоты родительского элемента, дочерний элемент (зеленый квадрат) не менял свои пропорции, то есть всегда оставался квадратом, при этом в пределах своего родительского элемента?

Вот эту задачу мне и нужно решить, но я понять не могу, как это сделать. Вот и прошу помощи.

рони 04.03.2021 17:32

Цитата:

Сообщение от LADYX
то есть всегда оставался квадратом, при этом в пределах своего родительского элемента?

<!DOCTYPE html>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        #parent {
            width: 300px;
            height: 300px;
            padding: 10px;
            border: 5px solid red;
            display: flex;
            justify-content: center;
            flex-direction: column;
        }

        #children {
            width: var(--size, 100%);
            height: var(--size, 100%);
            background: green;
            margin: 0 auto;
        }
    </style>
    <script>
        function parentH() {
            let height = document.querySelector('#parent_range_H').value;
            let width = document.querySelector('#parent_range_W').value;
            document.querySelector('#parent').style.height = height + 'px';
            document.querySelector('#children').style.setProperty('--size', `${Math.min(height,width)}px`);
        }

        function parentW() {
            let height = document.querySelector('#parent_range_H').value;
            let width = document.querySelector('#parent_range_W').value;
            document.querySelector('#parent').style.width = width + 'px';
            document.querySelector('#children').style.setProperty('--size', `${Math.min(height,width)}px`);
        }
    </script>
</head>

<body>
    <p>height: <input id="parent_range_H" type="range" min="10" max="300" value="300" step="1" name="parent_h" oninput="parentH()">
        width: <input id="parent_range_W" type="range" min="10" max="300" value="300" step="1" name="parent_w" oninput="parentW()"></p>
    <div id="parent">
        <div id="children"></div>
    </div>
</body>

</html>

LADYX 04.03.2021 18:24

рони,
да, точно! Посмотрел, изучил, кажется понял как вы это сделали. Для меня это новое. Спасибо вам за помощь, крепко вас обнимаю! :)

рони 04.03.2021 19:22

LADYX,
ещё вариант ...
<!DOCTYPE html>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style>
        #parent {
            width: 300px;
            height: 300px;
            padding: 10px;
            border: 5px solid red;
            position: relative;
        }

        #children {
            position: absolute;
            width: 300px;
            height: 300px;
            background: green;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            margin: auto;
        }
    </style>
    <script>
        function parentH() {
            let height = document.querySelector('#parent_range_H').valueAsNumber;
            let width = document.querySelector('#parent_range_W').valueAsNumber;
            document.querySelector('#parent').style.height = height + 'px';
            let style = document.querySelector('#children').style;
            height <= width && (style.height = style.width = height + 'px');
        }

        function parentW() {
            let height = document.querySelector('#parent_range_H').valueAsNumber;
            let width = document.querySelector('#parent_range_W').valueAsNumber;
            document.querySelector('#parent').style.width = width + 'px';
            let style = document.querySelector('#children').style;
            height >= width && (style.height = style.width = width + 'px');
        }
    </script>
</head>

<body>
    <p>height: <input id="parent_range_H" type="range" min="10" max="300" value="300" step="1" name="parent_h" oninput="parentH()">
        width: <input id="parent_range_W" type="range" min="10" max="300" value="300" step="1" name="parent_w" oninput="parentW()"></p>
    <div id="parent">
        <div id="children"></div>
    </div>
</body>

</html>

LADYX 05.03.2021 11:42

рони,
спасибо и за этот вариант. Да, я посмотрел, вроде бы разобрался и понял что и как. Я вам очень благодарен!

Сейчас пытаюсь решить еще одну аналогичную задачу. Похожая на эту, но гораздо сложнее на мой взгляд. Возможно буду задавать новый вопрос, но сначала попробую решить самостоятельно)


Часовой пояс GMT +3, время: 10:07.