Javascript 向角度视图中的图元添加调整大小功能
我在代码笔示例之后添加了一个调整大小功能 在评论中提到使用MARGIN=4(这里我无法添加codepen链接) 代码笔是我能找到的最好的工作示例 在长方体的所有4条边上添加了4个元素 我已经在pointerdown、pointermove和pointerup中添加了hostlisteners,但我一直在执行Resizeable指令中的animate()函数 在指令中,代码主要有3个函数执行所有计算onDown(),calc(e),animate()Javascript 向角度视图中的图元添加调整大小功能,javascript,html,css,angular,Javascript,Html,Css,Angular,我在代码笔示例之后添加了一个调整大小功能 在评论中提到使用MARGIN=4(这里我无法添加codepen链接) 代码笔是我能找到的最好的工作示例 在长方体的所有4条边上添加了4个元素 我已经在pointerdown、pointermove和pointerup中添加了hostlisteners,但我一直在执行Resizeable指令中的animate()函数 在指令中,代码主要有3个函数执行所有计算onDown(),calc(e),animate() import { Directive,
import { Directive,
ElementRef,
HostListener } from '@angular/core';
import { DraggableDirective } from './draggable.directive';
@Directive({
selector: '[appResizable]' // Attribute selector
})
export class ResizableDirective extends DraggableDirective{
constructor(public element:ElementRef){
super(element);
}
minWidth = 60;
minHeight = 40;
// Thresholds
MARGINS = 4;
//End Of whats configurable
clicked = null;
public onRightEdge; onBottomEdge; onLeftEdge; onTopEdge;
public b; x; y;
redraw = false;
e;
clickedDragging = false;
ngOnInit(){
this.animate()
}
@HostListener('dragStart', ['$event'])
onDragStart(e:PointerEvent): void{
this.clickedDragging = true;
this.onDown(e);
e.preventDefault();
}
@HostListener('dragMove', ['$event'])
onDragMove(ee): void{
if (!this.dragging || ee.pointerId !== this.pointerId) {
return;
}
if((<HTMLElement>event.srcElement).id === ('side-top')){
this.onMove(ee);
ee.preventDefault();
}
}
@HostListener('dragEnd', ['$event'])
ondragend(ev): void{
this.onUp(ev);
}
onMove(ee){
if (!this.dragging || ee.pointerId !== this.pointerId) {
return;
}
if(this.clickedDragging){
this.calc(ee);
this.e = ee;
this.redraw = true;
}
}
onDown(e){
this.calc(e);
let isResizing = this.onRightEdge || this.onBottomEdge ||
this.onLeftEdge || this.onTopEdge;
this.clicked = {
x: this.x,
y: this.y,
cx: e.clientX,
cy: e.clientY,
w: this.b.width,
h: this.b.height,
isResizing: isResizing,
onRightEdge: this.onRightEdge,
onBottomEdge: this.onBottomEdge,
onLeftEdge: this.onLeftEdge,
onTopEdge: this.onTopEdge,
}
}
calc(e){
this.b = this.element.nativeElement.getBoundingClientRect();
this.x = e.clientX - this.b.left;
this.y = e.clientY - this.b.top;
this.onRightEdge = this.x >= this.b.width - this.MARGINS;
this.onBottomEdge = this.y >= this.b.height - this.MARGINS;
this.onLeftEdge = this.x < this.MARGINS;
this.onTopEdge = this.y < this.MARGINS;
}
animate(){
requestAnimationFrame(this.animate);
if(!this.redraw)return;
this.redraw = false;
if(this.clicked && this.clicked.isResizing){
if(this.clicked.onRightEdge){
this.element.nativeElement.style.width = Math.max(this.x,
this.minWidth) + 'px';
}
if(this.clicked.onBottomEdge){
this.element.nativeElement.style.height = Math.max(this.y,
this.minHeight) + 'px';
}
if(this.clicked.onLeftEdge){
let currentWidth = Math.max(this.clicked.cx -
this.e.clientX + this.clicked.w, this.minWidth);
if(currentWidth > this.minWidth){
this.element.nativeElement.style.width = currentWidth + 'px';
this.element.nativeElement.style.left = this.e.clientX + 'px';
}
}
if (this.clicked.onTopEdge) {
var currentHeight = Math.max(this.clicked.cy -
this.e.clientY +
this.clicked.h, this.minHeight);
if (currentHeight > this.minHeight) {
this.element.nativeElement.style.height = currentHeight + 'px';
this.element.nativeElement.style.top = this.e.clientY + 'px';
}
}
return;
}
}
onUp(ev) {
this.calc(ev);
this.clicked = null;
}
}
整个元素都被采用了,我也必须这样做,在我的例子中,我有指令所在的边界
我附加了一个工作stackblitz。可调整大小的指令存在于可拖动文件夹中,用于hello组件
在pointerdown的stackblitz控制台日志中,还可以看到pointermove
控制台动画中未定义的错误
请参考注释中的代码笔示例
更新
很抱歉,我无法修复您的代码,因为它太乱了,您完全错了,您在一个代码中使用了我建议的两种方法。此外,您正在泄漏指令外部的resize内部,div需要隐藏,在指令外部,您只应使用
resize
属性,所有内容都应在指令内部创建
在这里,这是从一个顶部开始的:
@Directive({
selector: '[resize]'
})
class Resizable implements OnInit, OnDestroy {
private nodes: HtmlElement[] = [];
private data: {x: number, y: number, rect: ClientRect, direction: string};
constructor(@Inject(ElementRef) private element: ElementRef) {
this.mousemove = this.mousemove.bind(this);
this.mouseup = this.mouseup.bind(this);
}
mousemove(e) {
if (this.data) {
switch(this.data.direction) {
case 'top':
var offset = this.data.y - e.clientY;
var height = this.data.rect.height;
var top = this.data.rect.top;
var style = this.element.nativeElement.style;
style.height = height + offset + 'px';
style.top = top - offset + 'px';
break;
}
}
}
ngOnInit() {
var node = document.createElement('div');
node.classList.add('border-top', 'border');
this.element.nativeElement.appendChild(node);
this.nodes.push(node);
window.addEventListener('mousemove', this.mousemove);
window.addEventListener('mouseup', this.mouseup);
}
@HostListener('mousedown', ['$event'])
mousedown(e) {
if (e.target.classList.contains('border')) {
var rect = this.element.nativeElement.getBoundingClientRect();
this.data = {
x: e.clientX,
y: e.clientY,
rect,
direction: e.target.className.match(/border-([^ ]+)/)[1]
};
e.preventDefault();
} else {
delete this.data;
}
}
mouseup(e) {
delete this.data;
}
ngOnDestroy() {
this.nodes.forEach(n => n.remove());
window.removeEventListener('mousemove', this.mousemove);
window.removeEventListener('mouseup', this.mouseup);
}
}
这里是很抱歉,我无法修复您的代码,因为它太乱了,您完全错了,您在一个代码中使用了我建议的两种方法。此外,您正在泄漏指令外部的resize内部,div需要隐藏,在指令外部,您只应使用
resize
属性,所有内容都应在指令内部创建
在这里,这是从一个顶部开始的:
@Directive({
selector: '[resize]'
})
class Resizable implements OnInit, OnDestroy {
private nodes: HtmlElement[] = [];
private data: {x: number, y: number, rect: ClientRect, direction: string};
constructor(@Inject(ElementRef) private element: ElementRef) {
this.mousemove = this.mousemove.bind(this);
this.mouseup = this.mouseup.bind(this);
}
mousemove(e) {
if (this.data) {
switch(this.data.direction) {
case 'top':
var offset = this.data.y - e.clientY;
var height = this.data.rect.height;
var top = this.data.rect.top;
var style = this.element.nativeElement.style;
style.height = height + offset + 'px';
style.top = top - offset + 'px';
break;
}
}
}
ngOnInit() {
var node = document.createElement('div');
node.classList.add('border-top', 'border');
this.element.nativeElement.appendChild(node);
this.nodes.push(node);
window.addEventListener('mousemove', this.mousemove);
window.addEventListener('mouseup', this.mouseup);
}
@HostListener('mousedown', ['$event'])
mousedown(e) {
if (e.target.classList.contains('border')) {
var rect = this.element.nativeElement.getBoundingClientRect();
this.data = {
x: e.clientX,
y: e.clientY,
rect,
direction: e.target.className.match(/border-([^ ]+)/)[1]
};
e.preventDefault();
} else {
delete this.data;
}
}
mouseup(e) {
delete this.data;
}
ngOnDestroy() {
this.nodes.forEach(n => n.remove());
window.removeEventListener('mousemove', this.mousemove);
window.removeEventListener('mouseup', this.mouseup);
}
}
这是codepen链接您是否尝试过使用angular animations api?codepen链接您是否尝试过使用angular animations api?非常感谢,我如何将此应用于其余3个应用程序sides@Enthu您需要为每一侧创建div(类边框为xxx)创建CSS,将元素移动到一边,并在
开关(this.data.direction)内执行类似的计算{
,底部
,右侧
和左侧
非常感谢您,我会实施,如果有任何问题,我会问您,谢谢alot@Enthu如果您只想更改一侧,则必须将其拖动。当您通过拖动“顶部”和“左侧”来调整大小时,需要更改“左侧”和“顶部”。让我们来看看。非常感谢,我如何应用此功能给其余的三个人sides@Enthu您需要为每一侧创建div(带有类边框xxx)创建CSS,将元素移动到一侧,并在开关(this.data.direction)内执行类似的计算{
,底部
,右侧
和左侧
非常感谢您,我会实施,如果有任何问题,我会问您,谢谢alot@Enthu如果您只想更改一侧,则必须将其拖动。当您通过拖动顶部和左侧来调整大小时,需要更改左侧和顶部。让我们来看看。
@Directive({
selector: '[resize]'
})
class Resizable implements OnInit, OnDestroy {
private nodes: HtmlElement[] = [];
private data: {x: number, y: number, rect: ClientRect, direction: string};
constructor(@Inject(ElementRef) private element: ElementRef) {
this.mousemove = this.mousemove.bind(this);
this.mouseup = this.mouseup.bind(this);
}
mousemove(e) {
if (this.data) {
switch(this.data.direction) {
case 'top':
var offset = this.data.y - e.clientY;
var height = this.data.rect.height;
var top = this.data.rect.top;
var style = this.element.nativeElement.style;
style.height = height + offset + 'px';
style.top = top - offset + 'px';
break;
}
}
}
ngOnInit() {
var node = document.createElement('div');
node.classList.add('border-top', 'border');
this.element.nativeElement.appendChild(node);
this.nodes.push(node);
window.addEventListener('mousemove', this.mousemove);
window.addEventListener('mouseup', this.mouseup);
}
@HostListener('mousedown', ['$event'])
mousedown(e) {
if (e.target.classList.contains('border')) {
var rect = this.element.nativeElement.getBoundingClientRect();
this.data = {
x: e.clientX,
y: e.clientY,
rect,
direction: e.target.className.match(/border-([^ ]+)/)[1]
};
e.preventDefault();
} else {
delete this.data;
}
}
mouseup(e) {
delete this.data;
}
ngOnDestroy() {
this.nodes.forEach(n => n.remove());
window.removeEventListener('mousemove', this.mousemove);
window.removeEventListener('mouseup', this.mouseup);
}
}