Browse Source

Improve Resizer with more configurations

pull/487/head
Artur Arseniev 8 years ago
parent
commit
7679b781f9
  1. 29
      index.html
  2. 31
      src/commands/view/SelectComponent.js
  3. 92
      src/utils/Resizer.js
  4. 10
      src/utils/mixins.js

29
index.html

@ -1299,6 +1299,35 @@
}, },
});*/ });*/
bm.add('b1-2', {
label: 'Flex Block',
category: 'Basic',
attributes: { class:'gjs-fonts gjs-f-b1' },
content: `
<div class="row-flex" data-columns="1" style="text-align: center" data-gjs-droppable="[data-column]" data-gjs-highlightable="false" data-gjs-resizable='{"tl":0,"tc":0,"tr":0,"cl":0,"cr":0,"bl":0,"br":0}' data-gjs-custom-name="Row">
<div class="cell-flex col1" data-column="1" style="letter-spacing: normal" data-gjs-draggable="[data-columns]" data-gjs-resizable='{"tl":0,"tc":0,"tr":0,"cl":0,"bl":0,"br":0,"bc": 0, "keyWidth": "flex-basis", "currentUnit": 0}'>
</div>
<div class="cell-flex col2" data-column="1" style="letter-spacing: normal" data-gjs-draggable="[data-columns]" data-gjs-resizable='{"tl":0,"tc":0,"tr":0,"cl":0,"bl":0,"br":0,"bc": 0, "keyWidth": "flex-basis", "currentUnit": 0}'>
</div>
</div>
<style>
.row-flex {
display: flex;
justify-content: flex-start;
align-items: stretch;
flex-wrap: nowrap;
padding: 10px;
}
.cell-flex {
min-height: 75px;
flex-grow: 1;
flex-basis: 100%;
}
</style>
`
})
var domc = editor.DomComponents; var domc = editor.DomComponents;
var defaultType = domc.getType('default'); var defaultType = domc.getType('default');
var defaultModel = defaultType.model; var defaultModel = defaultType.model;

31
src/commands/view/SelectComponent.js

@ -1,5 +1,5 @@
import {bindAll} from 'underscore'; import { bindAll } from 'underscore';
import {on, off} from 'utils/mixins'; import { on, off, getUnitFromValue} from 'utils/mixins';
const ToolbarView = require('dom_components/view/ToolbarView'); const ToolbarView = require('dom_components/view/ToolbarView');
const Toolbar = require('dom_components/model/Toolbar'); const Toolbar = require('dom_components/model/Toolbar');
@ -340,37 +340,54 @@ module.exports = {
if (editor && resizable) { if (editor && resizable) {
options = { options = {
onStart(e, opts) { // Here the resizer is updated with the current element height and width
onStart(e, opts = {}) {
const { el, config, resizer } = opts;
const { keyHeight, keyWidth, currentUnit } = config;
toggleBodyClass('add', e, opts); toggleBodyClass('add', e, opts);
modelToStyle = em.get('StyleManager').getModelToStyle(model); modelToStyle = em.get('StyleManager').getModelToStyle(model);
const computedStyle = getComputedStyle(el);
const modelStyle = modelToStyle.getStyle();
const currentWidth = modelStyle[keyWidth] || computedStyle[keyWidth];
const currentHeight = modelStyle[keyHeight] || computedStyle[keyHeight];
resizer.startDim.w = parseFloat(currentWidth);
resizer.startDim.h = parseFloat(currentHeight);
showOffsets = 0; showOffsets = 0;
if (currentUnit) {
config.unitHeight = getUnitFromValue(currentHeight);
config.unitWidth = getUnitFromValue(currentWidth);
}
}, },
// Update all positioned elements (eg. component toolbar) // Update all positioned elements (eg. component toolbar)
onMove() { onMove() {
editor.trigger('change:canvasOffset'); editor.trigger('change:canvasOffset');
}, },
onEnd(e, opts) { onEnd(e, opts) {
toggleBodyClass('remove', e, opts); toggleBodyClass('remove', e, opts);
editor.trigger('change:canvasOffset'); editor.trigger('change:canvasOffset');
showOffsets = 1; showOffsets = 1;
}, },
updateTarget(el, rect, options = {}) { updateTarget(el, rect, options = {}) {
if (!modelToStyle) { if (!modelToStyle) {
return; return;
} }
const {store, selectedHandler} = options; const { store, selectedHandler, config} = options;
const { keyHeight, keyWidth } = config;
const onlyHeight = ['tc', 'bc'].indexOf(selectedHandler) >= 0; const onlyHeight = ['tc', 'bc'].indexOf(selectedHandler) >= 0;
const onlyWidth = ['cl', 'cr'].indexOf(selectedHandler) >= 0; const onlyWidth = ['cl', 'cr'].indexOf(selectedHandler) >= 0;
const unit = 'px';
const style = modelToStyle.getStyle(); const style = modelToStyle.getStyle();
if (!onlyHeight) { if (!onlyHeight) {
style.width = rect.w + unit; style[keyWidth] = rect.w + config.unitWidth;
} }
if (!onlyWidth) { if (!onlyWidth) {
style.height = rect.h + unit; style[keyHeight] = rect.h + config.unitHeight;
} }
modelToStyle.setStyle(style, {avoidStore: 1}); modelToStyle.setStyle(style, {avoidStore: 1});

92
src/utils/Resizer.js

@ -1,7 +1,5 @@
import {bindAll, defaults} from 'underscore'; import { bindAll, defaults, isFunction } from 'underscore';
import {on, off} from 'utils/mixins'; import { on, off } from 'utils/mixins';
const $ = Backbone.$;
var defaultOpts = { var defaultOpts = {
// Function which returns custom X and Y coordinates of the mouse // Function which returns custom X and Y coordinates of the mouse
@ -14,6 +12,26 @@ var defaultOpts = {
onStart: null, onStart: null,
onMove: null, onMove: null,
onEnd: null, onEnd: null,
// Minimum dimension
minDim: 32,
// Unit used for height resizing
unitHeight: 'px',
// Unit used for width resizing
unitWidth: 'px',
// The key used for height resizing
keyHeight: 'height',
// The key used for width resizing
keyWidth: 'width',
// If true, will override unitHeight and unitWidth, on start, with units
// from the current focused element (currently used only in SelectComponent)
currentUnit: 1,
// Handlers // Handlers
tl: 1, // Top left tl: 1, // Top left
tc: 1, // Top center tc: 1, // Top center
@ -56,6 +74,16 @@ class Resizer {
return this; return this;
} }
/**
* Get current connfiguration options
* @return {Object}
*/
getConfig() {
return this.opts;
}
/** /**
* Setup options * Setup options
* @param {Object} options * @param {Object} options
@ -193,9 +221,11 @@ class Resizer {
} }
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
var opts = this.opts || {}; const el = this.el;
var attrName = 'data-' + opts.prefix + 'handler'; const resizer = this;
var rect = this.getElementPos(this.el); const config = this.opts || {};
var attrName = 'data-' + config.prefix + 'handler';
var rect = this.getElementPos(el);
this.handlerAttr = e.target.getAttribute(attrName); this.handlerAttr = e.target.getAttribute(attrName);
this.clickedHandler = e.target; this.clickedHandler = e.target;
this.startDim = { this.startDim = {
@ -221,11 +251,8 @@ class Resizer {
on(doc, 'keydown', this.handleKeyDown); on(doc, 'keydown', this.handleKeyDown);
on(doc, 'mouseup', this.stop); on(doc, 'mouseup', this.stop);
this.move(e); this.move(e);
isFunction(this.onStart) &&
// Start callback this.onStart(e, {docs: doc, config, el, resizer});
if(typeof this.onStart === 'function') {
this.onStart(e, {docs: doc});
}
} }
/** /**
@ -268,16 +295,13 @@ class Resizer {
* @param {Event} e * @param {Event} e
*/ */
stop(e) { stop(e) {
const config = this.opts;
var doc = this.getDocumentEl(); var doc = this.getDocumentEl();
off(doc, 'mousemove', this.move); off(doc, 'mousemove', this.move);
off(doc, 'keydown', this.handleKeyDown); off(doc, 'keydown', this.handleKeyDown);
off(doc, 'mouseup', this.stop); off(doc, 'mouseup', this.stop);
this.updateRect(1); this.updateRect(1);
isFunction(this.onEnd) && this.onEnd(e, {docs: doc, config});
// Stop callback
if (typeof this.onEnd === 'function') {
this.onEnd(e, {docs: doc});
}
} }
/** /**
@ -285,31 +309,34 @@ class Resizer {
*/ */
updateRect(store) { updateRect(store) {
const el = this.el; const el = this.el;
const resizer = this;
const config = this.opts;
const rect = this.rectDim; const rect = this.rectDim;
const conStyle = this.container.style; const conStyle = this.container.style;
const updateTarget = this.updateTarget; const updateTarget = this.updateTarget;
const selectedHandler = this.getSelectedHandler(); const selectedHandler = this.getSelectedHandler();
const { unitHeight, unitWidth } = config;
// Use custom updating strategy if requested // Use custom updating strategy if requested
if (typeof updateTarget === 'function') { if (isFunction(updateTarget)) {
updateTarget(el, rect, { updateTarget(el, rect, {
store, store,
selectedHandler selectedHandler,
resizer,
config
}); });
} else { } else {
const elStyle = el.style; const elStyle = el.style;
elStyle.width = rect.w + 'px'; elStyle.width = rect.w + unitWidth;
elStyle.height = rect.h + 'px'; elStyle.height = rect.h + unitHeight;
//elStyle.top = rect.top + 'px';
//elStyle.left = rect.left + 'px';
} }
const unit = 'px'; const unitRect = 'px';
const rectEl = this.getElementPos(el); const rectEl = this.getElementPos(el);
conStyle.left = rectEl.left + unit; conStyle.left = rectEl.left + unitRect;
conStyle.top = rectEl.top + unit; conStyle.top = rectEl.top + unitRect;
conStyle.width = rectEl.width + unit; conStyle.width = rectEl.width + unitRect;
conStyle.height = rectEl.height + unit; conStyle.height = rectEl.height + unitRect;
} }
/** /**
@ -362,6 +389,7 @@ class Resizer {
calc(data) { calc(data) {
var opts = this.opts || {}; var opts = this.opts || {};
var startDim = this.startDim; var startDim = this.startDim;
var minDim = opts.minDim;
var box = { var box = {
t: 0, t: 0,
l: 0, l: 0,
@ -374,16 +402,16 @@ class Resizer {
var attr = data.handlerAttr; var attr = data.handlerAttr;
if (~attr.indexOf('r')) { if (~attr.indexOf('r')) {
box.w = Math.max(32, startDim.w + data.delta.x); box.w = Math.max(minDim, startDim.w + data.delta.x);
} }
if (~attr.indexOf('b')) { if (~attr.indexOf('b')) {
box.h = Math.max(32, startDim.h + data.delta.y); box.h = Math.max(minDim, startDim.h + data.delta.y);
} }
if (~attr.indexOf('l')) { if (~attr.indexOf('l')) {
box.w = Math.max(32, startDim.w - data.delta.x); box.w = Math.max(minDim, startDim.w - data.delta.x);
} }
if (~attr.indexOf('t')) { if (~attr.indexOf('t')) {
box.h = Math.max(32, startDim.h - data.delta.y); box.h = Math.max(minDim, startDim.h - data.delta.y);
} }
// Enforce aspect ratio (unless shift key is being held) // Enforce aspect ratio (unless shift key is being held)

10
src/utils/mixins.js

@ -16,4 +16,12 @@ const off = (el, ev, fn) => {
} }
} }
export {on, off} const getUnitFromValue = (value) => {
return value.replace(parseFloat(value), '');
}
export {
on,
off,
getUnitFromValue
}

Loading…
Cancel
Save