Вход

Просмотр полной версии : Овальный элемент для выбора части фотки.


Snipe
12.11.2008, 17:38
Интересно узнать Ваши мысли, как примерно реализовать такое:
загружается фотка, на ней появляется овал, который можно перемещать по фотке и менять этому овалу масштаб.

Ну и потом координаты отправляются на сервер и из фотки по овалу вырезается что надо. /* это уже не моя головная боль */

Пока не приступал, просто думаю, как лучше?
Первая мысль (самая простая на мой взгляд) - сделать прозрачный овал GIF или PNG, вставить в прямоугольный див и его уже ресайзить.
Но вроде некоторые браузеры фигово меняют размеры картинок - некрасиво получается.

Вторая - взять какую-нибудь библиотеку.
Если правильно понимаю, большинство библиотек рисуют фигуры точками (дивами) - не будет ли все это тормозить при перемещении?
Ну и собственно какие есть подобные библиотеки я пока тоже не смотрел...


В общем интересно узнать мнение специалистов. Какой из предложенных вариантов лучше или м.б. Ваш вариант?
Сам скрипт писать не надо, просто мысль. =)

ZoNT
12.11.2008, 17:58
svg(+vml для ИЕ). Там есть фигура "овал".

Octane
12.11.2008, 18:42
Raphaël (http://raphaeljs.com/)

ZoNT
12.11.2008, 18:48
Это и есть svg + vml
нафиг вешать нехилую библиотеку, если можно самостоятельно написать всего пару десятков строк кода?

Octane
12.11.2008, 18:53
Если не ошибаюсь, Canvas + VML. Ну а спор о том применять библиотеки или фреймвоки или писать самостоятельно бесполезен.

ZoNT
12.11.2008, 18:55
"Raphaël uses SVG and VML as a base for graphics creation."
ошибаешся: svg+vml

ZoNT
12.11.2008, 18:56
нет, не бесполезен... Любой спор приближает человека к истине...

Octane
12.11.2008, 19:13
Да точно, прочитал что SVG, значит перепутал с какой-то, ещё точно есть что-то похожее с <canvas>.

Snipe
13.11.2008, 08:42
Спасибо, посмотрю.
А в каких браузерах работать будет?
Ну т.е. без вариантов надо чтоб работало в IE6, 7; FF3; Opera9.25-9.6; Safari - будет?

Посмотрел, вроде то что нужно! Тока если будет норм во всех браузерах работать.

ZoNT
13.11.2008, 09:37
vml будет в ИЕ6+ точно, svg в FF2+, Опере, Сафари, Хроме..

Snipe
13.11.2008, 11:54
Ну а спор о том применять библиотеки или фреймвоки или писать самостоятельно бесполезен.

В данном случае лучше изучить и написать самому - тем самым подняв свою стоимость (ИМХО).
Где тут смайлик с баксами в глазах? :D

А вообще читаю сейчас - технология супер, жаль только IE как всегда жопу показывает.

Snipe
13.11.2008, 16:15
Так. Первый стоп.
Есть у меня эллипс. Если я embed вставляю с шириной 100 и высотой 200 - тогда все ок, но при любых других соотношениях сторон эллипс либо заходит за края embed либо не достает до них.

Как возможно сделать чтоб при любых размерах embed, эллипс всегда касался краев этого embed'a?


<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="svgCSS.css" type="text/css"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 100 200" onmouseup="top.window.cuEllMouseDown = false;" xmlns="http://www.w3.org/2000/svg" version="1.1">
<g>
<ellipse cx="50" cy="50" rx="48%" ry="98%" id="cuEllW" stroke="white"/>
<ellipse cx="50" cy="50" rx="49%" ry="99%" id="cuEllB" stroke="black"/>
<polyline points="40 47 47 47 47 40 53 40 53 47 60 47 60 53 53 53 53 60 47 60 47 53 40 53 40 47" stroke="black" stroke-width="1" fill="white" style="cursor: pointer" onmousedown="top.window.cuEllMouseDown = true;"/>
</g>
</svg>

ZoNT
13.11.2008, 16:50
Для отрисовки svg не обязательно использовать xml.
Вот примерчик (не смотри на некоторые функции: выдирал из большого проекта, не стал убирать кое-что ненужное).

Главное - понять принцип :)

<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<script type="text/javascript" src="script.js"></script>
</body>
</html>

var SVG = function(o){
this.AS = 'auto';
var t = this;

function A(e,a,v){e.setAttribute(a,v)}
function C(i){var e = document.createElementNS('http://www.w3.org/2000/svg',i); A(e, 'shape-rendering', t.AS); return e}

if (document.createElementNS&&C('svg').x!=null){
this.Holder = o.appendChild(C('svg'));

this.createPolyline = function(w, p, f, c){
var o = C('polyline');

o.addPoint = function(x,y){
var z = C('polyline');
A(z, 'points', x+','+y);
this.points.appendItem(z.points.getItem(0));
z = null
}
o.setColor = function(C){A(this, 'stroke', C)};
o.setFill = function(C){A(this, 'fill', C)};
o.setPoints = function(C){A(this, 'points', C)};
o.setWidth = function(C){A(this, 'stroke-width', C+'px')};

o.setWidth(w);
o.setPoints(p);
if (f) o.setFill(f);
if (c) o.setColor(c);

t.Holder.appendChild(o);
return o
}
}
else if (document.createStyleSheet) {
this.Holder = o;

document.namespaces.add('v', 'urn:schemas-microsoft-com:vml');
var style = document.createStyleSheet();
style.addRule('v\\:*', 'behavior: url(#default#VML);');
style.addRule('v\\:*', 'antialias: '+t.AS+';');

function C(i){return document.createElement(i)}

this.createPolyline = function(w, p, f, c){
var o = C('v:polyline');

o.addPoint = function(x,y){
t.Holder.removeChild(this);
if (this.left>x) {
this.left = x;
this.style.left = this.left+'px';
}
if (this.top>y) {
this.top = y;
this.style.top = this.top+'px';
}
this.P = this.P+' '+x+','+y;
this.points = this.P;
t.Holder.appendChild(this);
}
o.setColor = function(C){this.strokecolor = C};
o.setFill = function(C){
if (C&&C!='none') {
o.filled = true;
o.fillcolor = C
}
else o.filled = false;
};
o.setPoints = function(C){this.points = C; this.P = C};
o.setWidth = function(C){this.strokeweight = C+'px'};

o.setWidth(w);
o.setFill(f);
o.setPoints(p);
/(\d*),(\d*)/.test(p);
o.style.position = 'absolute';
o.left = RegExp.$1;
o.style.left = o.left+'px';
o.top = RegExp.$2;
o.style.top = o.top+'px';
if (c) o.setColor(c);

t.Holder.appendChild(o);
return o
}
}
}

function getElementPosition(elem) {
if (null==elem) return {"left":0, "top":0, "width": 0, "height":0,"x":0, "y":0, "xSize": 0, "ySize":0};

var w = elem.offsetWidth;
var h = elem.offsetHeight;

var l = 0;
var t = 0;

while (elem) {
l += elem.offsetLeft-elem.scrollLeft;
t += elem.offsetTop-elem.scrollTop;
elem = elem.offsetParent;
}

var xCentr = l + Math.round(w/2);
var yCentr = t + Math.round(h/2);

return {"left":l, "top":t, "width": w, "height":h,"x":l, "y":t, "xSize": w, "ySize":h,"xCentr":xCentr,"yCentr":yCentr};
}
function PreventDefault(e) {
if(e.preventDefault) e.preventDefault();
else e.returnValue = false;
}

var div = document.createElement('div');
div.style.background = '#675';
div.style.height = '100%';

var svg = new SVG(div);
if (svg.Holder) {
svg.Holder.style.height = '100%';

div.onmousemove = function(e){
if (typeof window.Line == 'undefined'||!Line) return;

var pos = getElementPosition(this);
Line.addPoint(e.clientX-pos.x,e.clientY-pos.y);
}
div.onmousedown = function(e){
e=e||event;
PreventDefault(e);
var pos = getElementPosition(this);
pos.x = e.clientX - pos.x;
pos.y = e.clientY - pos.y;
Line = svg.createPolyline( 3, pos.x+','+pos.y+' '+pos.x+','+pos.y, 'none', '#eee');
}
div.onmouseup = function(){Line=null}
}

document.body.appendChild(div);

ZoNT
13.11.2008, 16:55
забыл в div.onmousemove дописать e=e||event; для ИЕ :)

Snipe
17.11.2008, 10:47
ZoNT, огромное спасибо, очень помог.

SVG часть сделал - работает отлично.
По ходу обнаружил в Safari багу - если окружность перемещать по картинке, то от краев, где окружность заходит за "рамку" (только в Сафари такая рамка ограничивает svg-рисунок) остается шлейф. Решил проблему, сделав прозрачную окружность с большим радиусом.

Сейчас буду vml мучить.
Еще раз спасибо - выглядит на порядок лучше, чем с растягиванием GIF. =)

Snipe
17.11.2008, 18:15
Хм. А как картинку вставить JS-ом например в группу (<g> </g>) в SVG?
В частности как задать путь к рисунку?

ZoNT
17.11.2008, 18:37
таким не интересовался... А зачем тебе вставлять картинки методами svg, если можно просто вставить методами DOM?

Snipe
17.11.2008, 18:43
Хотелось все сделать "по правилам". =)

Самое главное картинка вставляется, но она прозрачная. =(

ZoNT
17.11.2008, 18:58
ну так почитай на w3c что там про картинки пишут... Там всё хорошо про svg написано...