Issue #1368✓ ResueltoAbierto el 16 de agosto de 2018por shlomokoReacciones 2

Redimensionar el lienzo

Respuesta rápidapor jvillena2

@artf y @shlomoko, iré explicando el paso poco a poco. Primero, necesito usar Jquery, pero puedes usar otra librería o integrarte dentro del motor GrapesJS. En mi caso quería que fuera transparente al motor. 1) Tengo dos elementos de div ocultos en el HTML del índice principal fuera del iframe que GrapesJS genera en t...

Lee la respuesta completa abajo ↓

Pregunta

¿Hay alguna forma de que el lienzo redimensione de forma dinámica? es decir, no usar el Administrador de dispositivos, sino arrastrar y soltar el ancho, similar a lo que puedes hacer con paneles o componentes?

Gracias

Respuestas (3)

👍 Muy útiljvillena7 de noviembre de 2018

@artf y @shlomoko, iré explicando el paso poco a poco. Primero, necesito usar Jquery, pero puedes usar otra librería o integrarte dentro del motor GrapesJS. En mi caso quería que fuera transparente al motor.

  1. Tengo dos elementos de div ocultos en el HTML del índice principal fuera del iframe que GrapesJS genera en tiempo de ejecución:
<!-- CONSEJOS DE RESOLUCIÓN DEL DISPOSITIVO-->
<div class="device-resolution hidden">
    <div class="dr-type">Phone - Paisaje</div>
    <div class="dr-measure">Afecta a 767px y inferiores"</div>
</div>

<div class="iframe-handle-contenedor oculto">
    <div class="handle right-handle">
         <div class="canaleta-manilla"></div>
         <div class="tab-handle"></div>
         <div class="dim-indicator"></div>
         <div class="js-mobile-list mobile-wrapper">
              .....
        </div>

</div>
    <div class="handle left-handle"></div>

</div>
  • El primer div llamado "device-resolution" mostrará la resolución del dispositivo compatible con este tamaño de pantalla.
  • La segunda div contiene: -- La cuneta -- La barra vertical izquierda y derecha que envuelve el cuerpo cuando se presiona la canaleta

El siguiente fragmento de código es la hoja de estilos utilizada:

/* VOLVIENDO A HACER SONIDO DE SONIDO */
.iframe-handle-container .handle {
    posición: absoluta;
    arriba: 0;
    abajo: 0;
    índice z: 14;
}
.iframe-handle-container .handle:before {
    contenido: "";
    posición: absoluta;
    arriba: 0;
    izquierda: -3px;
    ancho: 4px;
    altura: 100%;
    Antecedentes: #178df7;
    pantalla: ninguna;
}
.iframe-handle-container .right-handle {
    izquierda: -1px;
    ancho: 14px;
}
.iframe-handle-container .left-handle {
    izquierda: -1px;
    ancho: 3px;
    Eventos de puntería: todos;
    cursor: redimensionamiento de col;
}
.iframe-handle-container .tab-handle {
    posición: absoluta;
    arriba: 50%;
    ancho: 14px;
    altura: 38px;
    Margen arriba: -19px;
    antecedentes: #808080;
    cursor: redimensionamiento de col;
    Eventos de puntería: todos;
    Radio de borde superior derecho: 3px;
    Radio de borde inferior derecho: 3px;
}
.iframe-handle-container .tab-handle:before,
.iframe-handle-container .tab-handle:after {
    contenido: "";
    posición: absoluta;
    arriba: 8px;
    abajo: 8 px;
    ancho: 1px;
    Antecedentes: #a6a6a6;
}
.iframe-handle-container .tab-handle:before {
    izquierda: 5px;
}
.iframe-handle-container .tab-handle:after {
    izquierda: 8px;
}
.iframe-handle-container .tab-handle:hover {
    Antecedentes: #178df7;
}
.iframe-handle-container .tab-handle:hover:before,
.iframe-handle-container .tab-handle:hover:after {
    Antecedentes: #48a5f9;
}
.iframe-handle-container .gutter-handle {
    posición: absoluta;
    arriba: 0;
    izquierda: -3px;
    ancho: 4px;
    altura: 100%;
    cursor: redimensionamiento de col;
    Eventos de puntería: todos;
}
.iframe-handle-container:hover .handle:before {
    pantalla: bloqueo;
}
.iframe-handle-container:pasa el cursor .tab-handle {
    Antecedentes: #178df7;
    color del borde: #178df7;
}
.iframe-handle-container:pasa el cursor .tab-handle:before,
.iframe-handle-container:pasa el cursor .tab-handle:after {
    Antecedentes: #48a5f9;
}

.dim-indicator {
    posición: absoluta;
    arriba: 10%;
    Altura: 24px;
    margen izquierda: 22px;
    Eventos de puntería: todos;
    tamaño de fuente: 14px;
    pantalla: ninguna;
    relleno: 2px 9px;
    Radio de frontera: 4px !importante;
    color: #ffffff;
    /* peso de fuente: negrita; */
    ancho: 156px;
    Color de fondo: RGB(0, 0, 0);
}

.mobile-wrapper{
    posición: absoluta;
    arriba: 15%;
    margen-izquierda: -30px;
    Eventos de puntería: todos;
    color: #ffffff;
    Ancho: 340px;
    relleno: 14px;
}

.mobile-list li{
    antecedentes: #808080;
    Relleno: 3px;
    Radio de frontera: 4px !importante;
    margen inferior: 5px;
    tipo de lista: ninguno;
    relleno-izquierda: 11px;
}
  1. Cuando el usuario hace clic en un icono de pantalla de dispositivo, le muestro al manejador que redimensione el lienzo. --- Para ello, creé un método llamado "initDeviceEventHandle", que se encarga de inicializar el manejador de canalones, y otro método llamado "showDeviceResolution", que crea una copia clon de los dos DIVs que explicamos antes.
 editor. Commands.add('set-device-tablet', {
                run: function(editor, sender)
                {
                 .....
                },
                stop: función stop(editor, sender) {
                  
var device = deviceManager.get('Tablet High Resolution');               
                    showDeviceResolution("tablet_portrait", dispositivo);
                    initDeviceEventHandle(dispositivo);

}
            });

/**
     * Esta función recibirá un tipo de pantalla y mostrará la descripción en el lado izquierdo del lienzo.
     *
     * @param tipo
     * @param dispositivo
     */
    var showDeviceResolution = function (type, device){
        Nombre y descripción de la var;
        var width = device.attributes.widthMedia;

Para reducir un poco el ancho y así poder mover el mango hasta este tamaño
        var reduceWidth = width - maxReduceScreenPreviewSize;
        $(".gjs-frame").width(reduceWidth);

interruptor (tipo) {
            Caso "mobile_portrait":
                nombre = "Teléfono - Retrato";
                descripción = "Afecta - " + ancho + " y por debajo";

pausa;
            Caso "mobile_landscape":
                nombre = "Teléfono - Paisaje";
                descripción = "Afecta - " + ancho +" y por debajo";

pausa;
            Caso "tablet_portrait":
                nombre = "Tableta - Retrato";
                descripción = "Afecta - " + ancho +" y por debajo";

}

const deviceResolution = $(document).find(".gjs-cv-canvas").find(".device-resolution");

si (deviceResolution.length > 0){
            deviceResolution.addClass("hidden");
            deviceResolution.find(".dr-type").html(nombre);
            deviceResolution.find(".dr-measure").html(descripción);

} else {

var copyDeviceResolution = $(document).find(".device-resolution").clone(true,true);
            copyDeviceResolution.find(".dr-type").html(nombre);
            copyDeviceResolution.find(".dr-measure").html(descripción);
            $(document).find(".gjs-cv-canvas").prepend(copyDeviceResolution);

}

const glutterResize = $(document).find(".gjs-cv-canvas").find(".iframe-handle-container");

si (glutterResize.length > 0){
            glutterResize.addClass("oculto");

} else {
           Si el div aún no se ha creado dentro del iframe, entonces lo incluimos.
            var copyGlutterResize = $(document).find(".iframe-handle-container").clone(true,true);
            $(".gjs-frame").before(copyGlutterResize);

}

Obligamos a actualizar la pantalla porque entonces actualizaremos todas las dimensiones
        setTimeout(función () {
            $(ventana).trigger('redimensionar');
        }, 600);

};

/**
     * Esta función inicializa el control de gutters del dispositivo
     *
     */
    var initDeviceEventHandle = function (device) {

try {
              
var maxDeviceSize = parseInt(device.attributes.widthMedia,10);

Para reducir un poco el ancho y así poder mover el mango hasta este tamaño
                var reduceWidth = maxDeviceSize - maxReduceScreenPreviewSize;
                $(".gjs-frame").width(reduceWidth);

var widthIframe = 0; Ancho actual del iframe
                var maxLeftPos = 0;
                var finalwidth = 0;

$(".manilla-derecha").arrastrable({
                    Eje: "X",
                    start: function(event, ui) {
                        widthIframe = $(".gjs-frame").width();

},
                    arrastrar: función(evento, ui) {
                      
try {

si ( $(".gjs-cv-canvas").find(".handle-mask").length == 0 ){
                               Necesitamos crear una máscara para evitar que en el momento en que arrastremos el puntero sobre el iframe y pierdas entonces el control del redimensionamiento.
                                $(".gjs-cv-canvas").append('<div class="handle-mask" style="position: absolute; z-index: 2; left: 0; top: 0; right: 0; bottom: 0;"></div>');
                            }

Necesitamos cambiar dinámicamente el ancho del iframe
                            const total = ui.posición.izquierda - ui.posiciónOriginal.izquierda;
                            ancho var = ancho Iframe + 2*total;
                            
$('.js-lista-móvil').find(".móvil-item").addClass("hidden");
 
if(width > maxDeviceSize || width < minReduceScreenPreviewSize){
                                ui.position.left = maxLeftPos;

} else {
                                Establece el ancho del iframe
                                maxLeftPos = ui.position.left;
                                $(".gjs-frame").width(width);
                                ancho final = ancho;

Coloca la posición a la izquierda del mango izquierdo
                                var left = $(".gjs-frame")[0].offsetLeft;
                                $(".manilla-izquierda").css("izquierda", izquierda);
                                
var leftDesc = left - 162; 162 = el ancho del panel derecho
                                $(".device-resolution").css("izquierda", izquierdaDesc);
                                $('.dim-indicator').html('Tamaño de pantalla' + ancho + 'px').fadeIn('lento');

}
                           Después de arrastrar, necesitamos refrescar el editor para recalcular el borde de resaltado en el elemento seleccionado.
                            editor.refresh();

} captura (err) {
                            consola.error(err);
                        }
                    },
                    stop: function(event, ui) {
                      
try {
                            $(".handle-mask").remove();
                            
} captura (err) {
                            consola.error(err);
                        }
                    }

});

} captura (err) {
            consola.error(err);
        }
    };
  1. Este punto es importante porque cuando redimensionamos la pantalla también necesitamos controlar la canaleta. Así que en el método de "cargar" del editor, incluyo una nueva función para comprobar si el usuario está redimensionando el lienzo o el tamaño de la pantalla. Esto se llama "getWindowDims".
editor.on('load', function() {
 Controla que el tamaño de la pantalla no sea demasiado pequeño
            getWindowDims();
}

/**
     * Función para determinar el tamaño del visor
     */
    var getWindowDims = function() {
        var doc = documento, w = ventana;
        var docEl = (doc.compatMode & & doc.compatMode === 'CSS1Compat')?
            doc.documentElement: doc.body;

var width = docEl.clientWidth;
        var height = docEl.clientHeight;

¿Móvil ha hecho zoom?
        si ( w.anchoInterno && ancho > w.AnchoInterno ) {
            ancho = ancho interior (ancho interior);
            altura = alturaInterior;
        }

IMPORTANTE!!!
        Información sobre el GutterHandle
        var glutterHandleObj = $(document).find(".gjs-cv-canvas").find(".iframe-handle-container");
        si (glutterHandleObj.length > 0){

var leftGlutterHandleBar = glutterHandleObj.find(".left-handle");
            var rightGlutterHandleBar = glutterHandleObj.find(".right-handle");

var leftOffset = $('.gjs-frame')[0].offsetLeft;
            var rightOffset = $('.gjs-frame')[0].offsetLeft + $('.gjs-frame').width();

leftGlutterHandleBar.css("cssText", "left: " + leftOffset + "px !important");
            rightGlutterHandleBar.css("cssText", "left: " + rightOffset + "px !important");
            glutterHandleObj.removeClass("hidden");

}

devolver {ancho: ancho, alto: alto};
    };

Espero que esto te sea útil. No dudes en hacerme dudas. Enlace de la demo: http://recordit.co/RTEaUphDZ6

artf21 de agosto de 2018

No @shlomoko, el lienzo no es redimensionable pero me encantaría ver un reparador permanente para eso (posiblemente con la misma lógica que se usa en los paneles).

jvillena24 de octubre de 2018

Hola @artf, acabo de implementar una barra de lienzo para redimensionar, pero no sé si existe alguna forma de refrescar la posición de los bordes de los resaltos. Echa un vistazo al vídeo, por favor: http://recordit.co/jKlppYg2dD GJS-Badge GJS-toolbar Un saludo cordial.

Preguntas y respuestas relacionadas

Continúa investigando con debates sobre temas similares.

Plugins de pago que cumplen con este problema

Seleccionado por temas clave y relevancia de etiquetas para ayudarte a enviar más rápido.

Ver todos los plugins

Cargando recomendaciones de plugins de pago...

Opción gratuita

Consulta los plugins de código abierto de GrapesJS en GitHub O haz una búsqueda rápida en nuestro catálogo gratuito.

Explora plugins gratuitos →
Opción premium

Los plugins premium incluyen soporte, actualizaciones regulares y funciones listas para producción — ahorrando días de trabajo de integración.

Explora plugins premium →

Tutoriales relacionados

Guías detalladas sobre el mismo tema.

Todos los tutoriales →

Explorar categorías de plugins

Ve directamente a las páginas de categorías de plugins en el marketplace.