Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 50 additions & 11 deletions demo/transform.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,25 @@
<body>
<div class="container-fluid">
<h1>Transform Parent demo</h1>
<p>example where the grid parent has a translate(50px, 100px) <s>scale(0.5, 0.5)</s> (scale not working yet see #1275)</p>
<p>example where the grid parent has a translate(50px, 100px) and a scale(<span id="scale-x"></span>, <span id="scale-y"></span>)</p>
<div>
<a class="btn btn-primary" onClick="addNewWidget()" href="#">Add Widget</a>
<!-- <a class="btn btn-primary" onClick="zoomIn()" href="#">Zoom in</a>
<a class="btn btn-primary" onClick="zoomOut()" href="#">Zoom out</a> -->
<a class="btn btn-primary" onClick="zoomIn()" href="#">Zoom in</a>
<a class="btn btn-primary" onClick="zoomOut()" href="#">Zoom out</a>
<a class="btn btn-primary" onClick="increaseScaleX()" href="#">Increase Scale X</a>
<a class="btn btn-primary" onClick="decreaseScaleX()" href="#">Decrease Scale X</a>
<a class="btn btn-primary" onClick="increaseScaleY()" href="#">Increase Scale Y</a>
<a class="btn btn-primary" onClick="decreaseScaleY()" href="#">Decrease Scale Y</a>
</div>
<br><br>
<!-- <div style="transform: translate(50px, 100px) scale(var(--global-scale), var(--global-scale)); transform-origin: 0 0;"> -->
<div style="transform: translate(50px, 100px)">
<div style="transform: translate(50px, 100px) scale(var(--global-scale-x), var(--global-scale-y)); transform-origin: 0 0;">
<div class="grid-stack"></div>
</div>
</div>
<script src="events.js"></script>
<script type="text/javascript">
let scale = 0.5;
let scaleX = 0.5;
let scaleY = 0.5;

let grid = GridStack.init({float: true});
addEvents(grid);
Expand Down Expand Up @@ -57,20 +61,55 @@ <h1>Transform Parent demo</h1>
};

const updateScaleCssVariable = () => {
document.body.style.setProperty('--global-scale', `${scale}`);
document.body.style.setProperty('--global-scale-x', `${scaleX}`);
document.body.style.setProperty('--global-scale-y', `${scaleY}`);
document.getElementById("scale-x").textContent = scaleX.toFixed(2);
document.getElementById("scale-y").textContent = scaleY.toFixed(2);
}

zoomIn = function() {
const scaleStep = scale < 1 ? 0.05 : 0.1;
scale += scaleStep;
const scaleStep = scaleX < 1 ? 0.05 : 0.1;
scaleX += scaleStep;
scaleY += scaleStep;
updateScaleCssVariable();
}

zoomOut = function() {
const scaleStep = scale < 1 ? 0.05 : 0.1;
scale -= scaleStep;
if(scaleX >= 0.2 && scaleY >= 0.2) {
const scaleStep = scaleX < 1 ? 0.05 : 0.1;
scaleX -= scaleStep;
scaleY -= scaleStep;
updateScaleCssVariable();
}
}

increaseScaleX = function() {
const scaleStep = scaleX < 1 ? 0.05 : 0.1;
scaleX += scaleStep;
updateScaleCssVariable();
}

decreaseScaleX = function() {
if(scaleX >= 0.2) {
const scaleStep = scaleX < 1 ? 0.05 : 0.1;
scaleX -= scaleStep;
updateScaleCssVariable();
}
}

increaseScaleY = function() {
const scaleStep = scaleX < 1 ? 0.05 : 0.1;
scaleY += scaleStep;
updateScaleCssVariable();
}

decreaseScaleY = function() {
if(scaleY >= 0.2) {
const scaleStep = scaleX < 1 ? 0.05 : 0.1;
scaleY -= scaleStep;
updateScaleCssVariable();
}
}

updateScaleCssVariable();

Expand Down
24 changes: 17 additions & 7 deletions src/dd-draggable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ interface DragOffset {
offsetTop: number;
}

interface DragScaleReciprocal {
x: number;
y: number;
}

type DDDragEvent = 'drag' | 'dragstart' | 'dragstop';

// make sure we are not clicking on known object that handles mouseDown
Expand All @@ -50,6 +55,8 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
/** @internal */
protected dragOffset: DragOffset;
/** @internal */
protected dragScale: DragScaleReciprocal = { x: 1, y: 1 };
/** @internal */
protected dragElementOriginStyle: Array<string>;
/** @internal */
protected dragEl: HTMLElement;
Expand Down Expand Up @@ -329,8 +336,8 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
// }
const style = this.helper.style;
const offset = this.dragOffset;
style.left = e.clientX + offset.offsetLeft - containmentRect.left + 'px';
style.top = e.clientY + offset.offsetTop - containmentRect.top + 'px';
style.left = (e.clientX + offset.offsetLeft - containmentRect.left) * this.dragScale.x + 'px';
style.top = (e.clientY + offset.offsetTop - containmentRect.top) * this.dragScale.y + 'px';
}

/** @internal */
Expand Down Expand Up @@ -367,7 +374,10 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
parent.removeChild(testEl);
xformOffsetX = testElPosition.left;
xformOffsetY = testElPosition.top;
// TODO: scale ?
this.dragScale = {
x: 1 / testElPosition.width,
y: 1 / testElPosition.height
};
}

const targetOffset = el.getBoundingClientRect();
Expand All @@ -376,8 +386,8 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
top: targetOffset.top,
offsetLeft: - event.clientX + targetOffset.left - xformOffsetX,
offsetTop: - event.clientY + targetOffset.top - xformOffsetY,
width: targetOffset.width,
height: targetOffset.height
width: targetOffset.width * this.dragScale.x,
height: targetOffset.height * this.dragScale.y
};
}

Expand All @@ -388,8 +398,8 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
const offset = this.helper.getBoundingClientRect();
return {
position: { //Current CSS position of the helper as { top, left } object
top: offset.top - containmentRect.top,
left: offset.left - containmentRect.left
top: (offset.top - containmentRect.top) * this.dragScale.y,
left: (offset.left - containmentRect.left) * this.dragScale.x
}
/* not used by GridStack for now...
helper: [this.helper], //The object arr representing the helper that's being dragged.
Expand Down
42 changes: 35 additions & 7 deletions src/dd-resizable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ export interface DDResizableOpt {
resize?: (event: Event, ui: DDUIData) => void;
}

interface RectScaleReciprocal {
x: number;
y: number;
}

export class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt<DDResizableOpt> {

// have to be public else complains for HTMLElementExtendOpt ?
Expand All @@ -35,6 +40,8 @@ export class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt
/** @internal */
protected originalRect: Rect;
/** @internal */
protected rectScale: RectScaleReciprocal = { x: 1, y: 1 };
/** @internal */
protected temporalRect: Rect;
/** @internal */
protected scrollY: number;
Expand Down Expand Up @@ -217,6 +224,26 @@ export class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt
protected _setupHelper(): DDResizable {
this.elOriginStyleVal = DDResizable._originStyleProp.map(prop => this.el.style[prop]);
this.parentOriginStylePosition = this.el.parentElement.style.position;

const parent = this.el.parentElement;
const testEl = document.createElement('div');
Utils.addElStyles(testEl, {
opacity: '0',
position: 'fixed',
top: 0 + 'px',
left: 0 + 'px',
width: '1px',
height: '1px',
zIndex: '-999999',
});
parent.appendChild(testEl);
const testElPosition = testEl.getBoundingClientRect();
parent.removeChild(testEl);
this.rectScale = {
x: 1 / testElPosition.width,
y: 1 / testElPosition.height
};

if (getComputedStyle(this.el.parentElement).position.match(/static/)) {
this.el.parentElement.style.position = 'relative';
}
Expand Down Expand Up @@ -278,9 +305,9 @@ export class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt
/** @internal constrain the size to the set min/max values */
protected _constrainSize(oWidth: number, oHeight: number): Size {
const maxWidth = this.option.maxWidth || Number.MAX_SAFE_INTEGER;
const minWidth = this.option.minWidth || oWidth;
const minWidth = this.option.minWidth / this.rectScale.x || oWidth;
const maxHeight = this.option.maxHeight || Number.MAX_SAFE_INTEGER;
const minHeight = this.option.minHeight || oHeight;
const minHeight = this.option.minHeight / this.rectScale.y || oHeight;
const width = Math.min(maxWidth, Math.max(minWidth, oWidth));
const height = Math.min(maxHeight, Math.max(minHeight, oHeight));
return { width, height };
Expand All @@ -297,7 +324,8 @@ export class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt
if (!this.temporalRect) return this;
Object.keys(this.temporalRect).forEach(key => {
const value = this.temporalRect[key];
this.el.style[key] = value - containmentRect[key] + 'px';
const scaleReciprocal = key === 'width' || key === 'left' ? this.rectScale.x : key === 'height' || key === 'top' ? this.rectScale.y : 1;
this.el.style[key] = (value - containmentRect[key]) * scaleReciprocal + 'px';
});
return this;
}
Expand All @@ -322,12 +350,12 @@ export class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt
const rect = this.temporalRect || newRect;
return {
position: {
left: rect.left - containmentRect.left,
top: rect.top - containmentRect.top
left: (rect.left - containmentRect.left) * this.rectScale.x,
top: (rect.top - containmentRect.top) * this.rectScale.y
},
size: {
width: rect.width,
height: rect.height
width: rect.width * this.rectScale.x,
height: rect.height * this.rectScale.y
}
/* Gridstack ONLY needs position set above... keep around in case.
element: [this.el], // The object representing the element to be resized
Expand Down