Resizer //Repositório JavaScript

Descrição

Permite redimensionar qualquer objeto bem como filtrar o redimensionamento.
Criado: 2005.11.18

Dependências

Código (Download)

//+ Jonas Raoni Soares Silva
//@ http://jsfromhell.com/dhtml/resizer [rev. #1]

Resizer = function(o){
    var $ = (($ = this).o = o, $.f = [], $),
        getHandler = function getHandler(h, v){return function(e){$.h = h, $.v = v, $.begin(e);};}
    for(var j, e, x, y, i = 3, k = -1, d = $.d = new Array(8); i;)
        for(j = (--i, 3); j; (--j != 1 || i != 1) && (d[++k] = [i, j, "",
            e = document.body.appendChild(document.createElement("div"))]),
            addEvent(e, "mousedown", getHandler(d[k][0], d[k][1])),
            e.style.position = "absolute", e.style.display = "none"
        );
}
with({p: Resizer.prototype}){
    p.h = 0, p.v = 0, p.pd = {x: 0, y: 0}, p.po = {x: 0, y: 0, h: 0, w: 0}, p.av = false;
    p.getMouse = function(e){
        var w = window, b = document.body;
        return {x: e.clientX + (w.scrollX || b.scrollLeft || b.parentNode.scrollLeft || 0),
            y: e.clientY + (w.scrollY || b.scrollTop || b.parentNode.scrollTop || 0)};
    };
    p.getOffset = function(o, s){
        for(var r = {x: o.offsetLeft, y: o.offsetTop, h: o.offsetHeight, w: o.offsetWidth};
            (o = o.offsetParent) && (!s || !/relative/i.test(o.style.position));
            r.x += o.offsetLeft, r.y += o.offsetTop);
        return r;
    };
    p.update = function(){
        var i, x, s, $ = this, d = $.d, o = $.getOffset($.o);
        for(i = d.length; i; x = d[--i], s = x[3].style, s.left = o.x + o.w * x[0] / 2 + "px",
            s.top = o.y + o.h * x[1] / 2 + "px");
    };
    p.showAnchors = function(s){
        var i, x, $ = this, d = $.d, o = $.getOffset($.o), m = ["none", "block"];
        for($.av = !!s, i = d.length; i; x = d[--i], x[3].style.display = m[+$.av]);
        $.update();
    };
    p.setAnchorClass = function(c){
        var i, d = this.d, map = {se: 0, e: 1, ne: 2, n: 3, s: 4, nw: 5, w: 6, sw: 7};
        if(typeof c == "string")
            for(i = d.length; i; d[--i][3].className = c);
        else
            for(i in c) d[map[i.toLowerCase()]][3].className = c[i];
    };
    p.addFilter = function(f){
        this.f[this.f.length] = f;
    },
    p.begin = function(e){
        var $ = this, p = $.getMouse(e);
        $.po = $.getOffset($.o, 1);
        $.pd = {x: $.po.x - p.x, y: $.po.y - p.y};
        addEvent(document, "mousemove", $.drag, $);
        addEvent(document, "mouseup", $.end, $);
        $.callEvent("onstart", e);
    };
    p.end = function(e){
        var $ = this;
        removeEvent(document, "mousemove", $.drag, $);
        removeEvent(document, "mouseup", $.end, $);
        $.callEvent("onend", e);
    };
    p.drag = function(e){
        var f, i, $ = this, p = $.getMouse(e), o = $.getOffset($.o), z = {x: 0, y: 0, w: 0, h: 0}, s = $.o.style;
        $.h != 1 ? (z.x = $.h ? $.po.x : p.x + $.pd.x, z.w = $.po.w + (p.x - $.po.x + $.pd.x) * ($.h - 1)) : (z.x = $.po.x, z.w = $.po.w);
        $.v != 1 ? (z.y = $.v ? $.po.y : p.y + $.pd.y, z.h = $.po.h + (p.y - $.po.y + $.pd.y) * ($.v - 1)) : (z.y = $.po.y, z.h = $.po.h);
        z.h < 0 && (z.y -= z.h = -z.h, $.v ^= 2, $.po.y += $.po.h, $.pd.y -= $.po.h *= -1);
        z.w < 0 && (z.x -= z.w = -z.w, $.h ^= 2, $.po.x += $.po.w, $.pd.x -= $.po.w *= -1);
        for(f = $.f, i = f.length; i; f[--i] && f[i].call(z, e, $));
        s.top = z.y + "px", s.left = z.x + "px", s.height = z.h + "px", s.width = z.w + "px";
        $.update();
        $.callEvent("onresize", e);
    };
    p.callEvent = function(e){
        return this[e] instanceof Function ? this[e].apply(this, [].slice.call(arguments, 1)) : undefined;
    };
}

Exemplo (Exemplo)

<style type="text/css">
#box, #box2, #box3{
    position: absolute;
    left: 50px;
    top: 100px;
    width: 300px;
    height: 100px;
    overflow: hidden;
    background: ;
    border: #999 solid 1px;
}
#box2{
    top: 215px;
    width: 400px;
}
#container{
    position: relative;
    top: 160px;
    width: 600px;
    height: 300px;
    overflow: hidden;
    background: #ffe;
    border: 1px solid;
}
.marker{
    font-size: 1px;
    width: 10px;
    height: 10px;
    margin-left: -5px;
    margin-top: -5px;
    border: #000 solid 1px;
    cursor: move;
}
.green{
    background: #0f0;
}
</style>

<div id="container">
    <div id="box3">
        Within a container with "position:relative"
    </div>
</div>
<div id="box">
    With max size filter and markers with different classes
</div>
<div id="box2">
    With filter to keep the 1:1 proportion when resizing by the diagonals holding the shift key 
</div>

<script type="text/javascript">
//<![CDATA[

x = new Resizer(document.getElementById("box"));
x.setAnchorClass("marker");
x.setAnchorClass({n: "marker green", s: "marker green", w: "marker green", e: "marker green"});
x.showAnchors(true);

limitSize = function(e, o){
    var x = 400, y = 200, c = this;
    c.h > y && (!o.v && (c.y += c.h - y), c.h = y);
    c.w > x && (!o.h && (c.x += c.w - x), c.w = x);
}
x.addFilter(limitSize);


y = new Resizer(document.getElementById("box2"));
y.setAnchorClass("marker");
y.showAnchors(true);

shiftResize = function(e, o){
    var c = this, d = c.w - c.h;
    e.shiftKey && o.h != 1 && o.v != 1 &&
    (d > 0 ? c.h = c.w : c.w = c.h,
    !o.v ? d > 0 ? c.y -= d : !o.h && (c.x += d)
    : !o.h && d < 0 && (c.x += d));
}
y.addFilter(shiftResize);

document.getElementById("container").style.position = "relative";
z = new Resizer(document.getElementById("box3"));
z.setAnchorClass("marker");
z.showAnchors(true);

//]]>
</script>

Ajuda

Construtor

Resizer(element: HTMLElement)
Gera uma instância de Resizer.
element
elemento que receberá suporte ao redimensionamento

Propriedades

Resizer.h: Integer
Especifica a posição horizontal do marcador que está sendo arrastado, onde: 0 = esquerda, 1 = meio, 2 = direita.
Resizer.v: Integer
Especifica a posição vertical do marcador que está sendo arrastado, onde: 0 = topo, 1 = meio, 2 = inferior.
Resizer.po: Object
Mantém as coordenadas da onde o objeto se encontrava quando o redimensionamento se iniciou, contém 4 propriedades, sendo elas: x (left), y (top), w (width) e h (height).
Resizer.o: HTMLElement
Elemento html associado ao resizer.
Resizer.f: Array
Vetor contendo os filtros de movimentação.
Resizer.av: Boolean
Informa se as âncoras de arraste estão visíveis.

Métodos

Resizer.update(void): void
Força o reposicionamento das âncoras de arraste.
Resizer.showAnchors(show: Boolean): void
Exibe/esconde os marcadores de arraste.
show
se true, exibe, caso contrário oculta os marcadores
Resizer.setAnchorClass(info: Object): void
Seta a classe CSS para todos ou apenas determinados marcadores.
info
aceita 2 tipos de entrada, se for passada uma String: a classe irá setar todos os marcadores com a String passada, a outra alternativa permite setar apenas determinados marcadores, é só passar um objeto contendo propriedades "mágicas" definidas com o nome da classe CSS (olhar exemplo), as propriedades são: se (sudoeste), e (oeste), ne (noroeste), n (norte), s (sul), nw (nordeste), w (leste), sw (sudeste)
Resizer.addFilter(handler: Function(event: Event, resizer: Resizer): void): void
Adiciona um filtro de movimentação ao resizer.
handler
função a ser adicionada, ela recebe como parâmetros o objeto de evento e a própria instância do Resizer, o escopo da função (a variável "this") te dá acesso a quatro propriedades: x (left), y (top), w (width) e h (height), alterando elas, você altera diretamente as coordenadas do objeto

Eventos

Resizer.onstart: function(event: Event): void
Este evento é chamado ao iniciar o redimensionamento.
event
objeto de evento
Resizer.onresize: function(event: Event): void
Este evento é chamado quando o objeto está sendo redimensionado.
event
objeto de evento
Resizer.onstop: function(event: Event): void
Este evento é chamado quando o redimensionamento é finalizado.
event
objeto de evento

Ranque (Votos: 31)

4.10