Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Как правильно сверстать интерфейс подбора рамок для фотографий (https://javascript.ru/forum/dom-window/27129-kak-pravilno-sverstat-interfejjs-podbora-ramok-dlya-fotografijj.html)

Natali_RnD 03.04.2012 18:08

Как правильно сверстать интерфейс подбора рамок для фотографий
 
стала задача разработать интерфейс аналогичный вот этому http://www.mir-ramok.bel31.ru/bin-release/mirramok.html только без флеша и внутри должна находиться фотография,а не пустой белый квадрат. Получается у нас есть фото, вокруг него идет две рамки из текстуры(паспарту называется) и самая внешняя рамка это багет. Смысл интерфейса в том, что пользователь может менять как размеры всей конструкции так и отдельных её частей, может выбрать другую рамку или другую текстуру. Я изначально подумала что нужно сделать несколько вложенных перекрывающих друг друга блоков. Т.е. самый внутренний div это фото, он находится внутри текстурной рамки и самый верхний блок это багет. Пускай багет это слой1, текстурная рамка - слой2 и фото - слой3. По идее каждый следующий слой имеет возрастающий z-index, что обеспечивает перекрывание блоков. Тут встаёт вопрос как правильно спозиционировать блоки и заполнить изображением? слой1(багет) заполнить через background repeat скорее всего не получится, потому что это не однородная текстура, а рисунок рамки. как с ним быть, может быть можно собрать background из четырёх частей или нужно использовать готовый рисунок всей рамки в качестве фона? далее слой2(текстурная рамка) я подумала что её нужно делать через repeat и остаётся слой3(фото), которое тоже то ли надо в background поместить, то ли оставить в виде img. К тому же я вообще не знаю можно ли перекрывать по-разному заданные background'ы, они нормально друг на друга наложатся? Как сверстать так чтобы можно было: 1) увеличить/уменьшать размер всей конструкции в целом и ничего никуда не съезжало 2) изменять визуальную(т.е. ту часть которая видна) ширину слоя2 и слоя1?

Маэстро 04.04.2012 11:26

Это можно делать двумя способами:
1. Использовать таблицу <table> с несколькими рядами и столбцами.
2. Использовать несколько DIV_ов, наложенных один поверх другого.
И в первом и во втором случае придется использовать стиль position:absolute, задавать left/top/width/height и изменять их при воздействии пользователем. В <table> можно использовать position:relative.

Илья Кантор 04.04.2012 11:46

Может, делать это не дивами, а просто перекрытыми изображениями?

Скажем, рамка хранится 800x600, а делается IMG 400x300 (или сколько нужно). Он отмасштабируется автоматически. На него сверху другой IMG. Другое дело - красиво ли это будет?

То есть, скажем, на рамке 5 завитушек. При увеличении ширины 6я завитушка не появится.

Маэстро 04.04.2012 11:58

Цитата:

Сообщение от Илья Кантор (Сообщение 166960)
Может, делать это не дивами, а просто перекрытыми изображениями?

Перекрытыми изображениями делать можно, но появятся проблемы:
1. В одном из контейнеров может отсутствовать картинка, а просто присутствовать какой-то цвет (девушки часто полюбляют всё размещать в нежно-розовом цвете).
2. При прямом использовании тегов <img> появляются всякие негативные эффекты в виде выделения картинок ("засинивания") и перетаскивания их мышью, что пытаются делать браузеры по-умолчанию. Если автор захочет добавить функции раздвижения рамок с помощью мыши, то все эти эффекты полезут наружу. Поэтому картинки лучше использовать в качестве фона контейнера background-image:url('...')

Илья Кантор 04.04.2012 12:12

1) Цветом можно все залить, добавив розовый DIV с z-index, а поверх него картинку с рамкой. Розовый должен быть чуть меньше по размеру, чем рамка, чтобы розовый не вылезал наружу.

2) На самом внешнем контейнере onmousedown = return false, onselectstart = return false, ondragstart = return false

P.S. Масштабировать фон, кстати, тоже можно в CSS3, но пока не все браузеры это умеют

Natali_RnD 04.04.2012 12:18

попробую сделать через div'ы с position:absolute и background'ом в виде картинок или заливки цветом

Маэстро 04.04.2012 12:22

Цитата:

Сообщение от Илья Кантор (Сообщение 166970)
1) Цветом можно все залить, добавив розовый DIV с z-index, а поверх него картинку с рамкой. Розовый должен быть чуть меньше по размеру, чем рамка, чтобы розовый не вылезал наружу.

2) На самом внешнем контейнере onmousedown = return false, onselectstart = return false, ondragstart = return false

1. Я же и говорю, что контейнеры всё-равно надо будет использовать, но не 1, а несколько, т.к. вместо любой картинки может быть не картинка, а ординарный цвет.
2. Этого недостаточно. Некоторым браузерам не хватает onmousedown = return false, им надо еще скармливать e.stopPropagation и e.preventDefault... А Fire Fox вообще игнорирует всё это, пока ему не задашь его родное '-moz-user-select:none'.

Natali_RnD 04.04.2012 16:37

так получилось следующее http://learn.javascript.ru/play/tNZcYb
остаётся проблема с внешней рамкой, если допустим мне нужно увеличить ширину этой рамки в два раза, при этом размер внутренних блоков не должен меняться, я это сделать не могу, потому что картинка рамки тянется только вся и соответственно увеличивается расстояние внутри рамки, а это неправильно... как бы из этой картинки сделать замощённый блок(типа background repeat картинка), чтобы можно было просто увеличить блок и остальные относительно него подвинуть?

Маэстро 04.04.2012 17:14

"увеличить ширину этой рамки в два раза"
Наверное Вы имеете ввиду, что при этом "толщина багета" НЕ должна измениться? Речь не о масштабировании всего объекта? Тогда для показа багета надо использовать таблицу из 3х3 строк/столбцов, а картинку багета разрезать на 8 частей. По углам таблицы должны быть вставлены картинки фиксированно (background-repeat:no-repeat), а в остальных секциях фон должен повторяться (background-repeat:repeat-x или background-repeat:repeat-y). В этом случае координаты left и top всех других (внутренних) div и img останутся без изменений.
Если Вы вообще не хотите применять javascript и сделать объект "резиновым", то тогда все div_ы надо вставить во внутреннюю центральную секцию таблицы и задать им width:100%;height:100%

Natali_RnD 04.04.2012 17:25

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

Natali_RnD 12.04.2012 14:07

час от часу не легче, оказалось что фотография должна быть под слоями паспарту, т.е. у меня сейчас три слоя паспарту и сама фотка, он нижнего слоя к фотке нарастает z-index, таким образом они перекрываются и создаётся видимость слоев с фиксированной шириной. Оказывается нужно чтобы фотография была самым нижним слоем и паспарту накладывались на неё, т.о. что каждый слой скрывает из виду часть фотки на которую он наложен, но остается видна центральная часть. Вопрос: возможно ли такое реализовать? т.е. у фотки выбранная область центральная должна быть видимой

Маэстро 12.04.2012 17:01

Цитата:

Сообщение от Natali_RnD (Сообщение 168552)
... каждый слой скрывает из виду часть фотки на которую он наложен, но остается видна центральная часть

1. Как я уже писал, можно картинку паспарту разделить на 8 частей (сделать из них периметр прямоугольника), тогда в центре будет пусто.
2. Можно попробовать сделать картинку паспарту на базе png-файла таким образом, чтобы внутренний прямоугольник был полностью прозрачен (тогда сквозь него будет видно центральное фото)

Natali_RnD 13.04.2012 11:02

Спасибо, ещё вопрос. Паспарту может быть прямоугольником и овалом соответственно. Я из прямоугольника делаю овал с помощью border-radius 50%, допустим у меня средний слой превращается в овал, необходимо, чтобы внутренний слой прямоугольный не выходил за рамки овала, т.е. его нужно вписать в овал. Вопрос: как по начальным размерам прямоугольника(который пользователь видит как овал) узнать максимальные размеры прямоугольника, который можно в писать в этот овал?
надеюсь понятно объяснила...

Маэстро 13.04.2012 12:50

ууу... Натали, это уже не javascript. это уже математика/геометрия.
всё определяется Пифагором и его теоремой о катетах...
Сделаю упрощенную программу для круга (не для овала).
<html>
<body>
<script>
var kv1 = 500; // ширина внешнего квадрата
var r1 = 250; // параметр скругления квадрата (в пикселях)
  
// расчет радиуса круга, вписанного во внешний квадрат. я его здесь поставил готовый - вычислите самостоятельно(на основании параметра скругления)
var r2 = 250;
  
// расчет стороны внутреннего квадрата, вписанного в круг
var kv2 = parseInt(2 * Math.sqrt(r2*r2/2));  
var x = parseInt((kv1 - kv2)/2); // координата left внутреннего квадрата, вписанного в круг
  
  
var k1=document.createElement('DIV');
k1.style.cssText = 'position:absolute; left:0px; top:0px; width:'+kv1+'px; height:'+kv1+'px; border:solid 1px #FF0000; border-radius:'+r1+'px';
document.body.appendChild(k1);

var k2=document.createElement('DIV');
k2.style.cssText = 'position:absolute; left:'+ x +'px; top:'+ x +'px; width:'+kv2+'px; height:'+kv2+'px; border:solid 1px #0000FF';
document.body.appendChild(k2);
</script>
</body>
</html>

Natali_RnD 13.04.2012 16:36

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

<html>
<body>
<script>
    var w1 = 245; // ширина внешнего прямоугольника
    var h1 = 355; // высота внешнего прямоугольника
    var r1 = parseFloat(w1/2); // параметр скругления по ширине (в пикселях)
    var r2 = parseFloat(h1/2); // параметр скругления по высоте (в пикселях)

    // расчет сторон внутреннего прямоугольника, вписанного в эллипс
    var w2 = parseInt(2 * Math.sqrt(r1*r1/2));
    var h2 = parseInt(2 * Math.sqrt(r2*r2/2));

    var y = parseInt((h1 - h2)/2); // координата top внутреннего прямоугольника, вписанного в эллипс
    var x = parseInt((w1 - w2)/2); // координата left внутреннего прямоугольника, вписанного в эллипс

    var k1=document.createElement('DIV');
    k1.style.cssText = 'position:absolute; left:0px; top:0px; width:'+w1+'px; height:'+h1+'px; border:solid 1px #FF0000; border-radius:'+r1+'px/'+r2+'px;';
    document.body.appendChild(k1);

    var k2=document.createElement('DIV');
    k2.style.cssText = 'position:absolute; left:'+ x +'px; top:'+ y +'px; width:'+w2+'px; height:'+h2+'px; border:solid 1px #0000FF';
    document.body.appendChild(k2);
</script>
  </body>
</html>

Маэстро 13.04.2012 17:05

Пожалуйста. Вот только мне интересно, как Вы это сделаете в IE8 (скругление).


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