Commit c5ea2600 authored by liujiangnan's avatar liujiangnan

feat: 添加拖拽

parent ea7c40a1
<div class="d-flex">
<div class="d-flex" (drop)="handle_drop($event)" (dragover)="handle_dragover($event)">
<div class="p-btn-record d-flex">
<div class="btn-clear" style="cursor: pointer" (click)="onBtnClearAudio()" *ngIf="withRmBtn && (audioUrl || audioBlob)">
<fa-icon icon="times"></fa-icon>
......
......@@ -276,6 +276,39 @@ export class AudioRecorderComponent implements OnInit, OnChanges, OnDestroy {
this.progress = Math.floor(p * 100);
}
linkInputed (url, name) {
url = url.substring(0, url.lastIndexOf(".")) + "_l.mp3";
this.audioUrl = url;
this.audioUploaded.emit({url});
this.audioName.emit(name);
}
handle_dragover(e) {
e.preventDefault();
}
handle_drop(e) {
const dt = e.dataTransfer.getData("text/plain");
console.log("handle_drop===", dt);
if (!dt) {
return;
}
try {
const {url, name} = JSON.parse(dt);
if (url.indexOf("teach")<0 || url.indexOf("cdn")<0) {
return;
}
const white = [".mp3"];
if (!white.includes(url.substr(url.lastIndexOf(".")))) {
return;
}
this.linkInputed(url, name);
} catch (error) {
console.warn("handle_drop拖拽在线音频传递参数不合法,应该是{url:'', name:''}");
}
}
}
enum Type {
......
......@@ -329,6 +329,7 @@ export class MySprite extends Sprite {
this.scaleX = this.scaleY = value;
}
getBoundingBox() {
const getParentData = (item) => {
......@@ -1956,6 +1957,10 @@ export class HotZoneItem extends MySprite {
audio_url;
pic_url;
text;
gIdx;
isAnimaStyle = false;
private _itemType;
private shapeRect: ShapeRect;
......@@ -2056,7 +2061,10 @@ export class HotZoneItem extends MySprite {
this.hideLabel();
}
setAnimaStyle(isAnimaStyle) {
this.isAnimaStyle = isAnimaStyle;
console.log('in setAnimaStyle ')
}
drawArrow() {
if (!this.arrow) { return; }
......@@ -2068,13 +2076,16 @@ export class HotZoneItem extends MySprite {
this.arrow.update();
this.arrowTop.x = rect.x + rect.width / 2;
this.arrowTop.y = rect.y;
this.arrowTop.update();
this.arrowRight.x = rect.x + rect.width;
this.arrowRight.y = rect.y + rect.height / 2;
this.arrowRight.update();
if (!this.isAnimaStyle) {
this.arrowTop.x = rect.x + rect.width / 2;
this.arrowTop.y = rect.y;
this.arrowTop.update();
this.arrowRight.x = rect.x + rect.width;
this.arrowRight.y = rect.y + rect.height / 2;
this.arrowRight.update();
}
}
drawFrame() {
......@@ -2197,10 +2208,155 @@ export class HotZoneLabel extends Label {
this.drawFrame();
}
getLabelRect() {
const rect = this.getBoundingBox();
const width = rect.width / this.scaleX;
const height = this.height * this.scaleY;
const x = this.x - width / 2;
const y = this.y - height / 2;
return {width, height, x, y};
}
}
export class HotZoneAction extends MySprite {
}
export class DragItem extends MySprite {
lineDashFlag = true;
item;
init() {
this.anchorX = 0.5;
this.anchorY = 0.5;
this.initCenterCircle();
}
setSize(w, h) {
this.anchorX = 0.5;
this.anchorY = 0.5;
this.width = w;
this.height = h;
// const rect = new ShapeRect(this.ctx);
// rect.x = -w / 2;
// rect.y = -h / 2;
// rect.setSize(w, h);
// rect.fillColor = '#000000';
// rect.alpha = 0.1;
// this.addChild(rect);
}
initCenterCircle() {
const circle = new ShapeCircle(this.ctx);
circle.setRadius(10);
circle.fillColor = '#ffa568'
this.addChild(circle);
this.width = circle.width;
this.height = circle.height;
}
getPosition() {
return {x: this.x, y: this.y};
}
drawLine() {
if (!this.item) {
return;
}
this.ctx.save();
const rect = this.getBoundingBox();
const w = rect.width;
const h = rect.height;
const x = rect.x //+ w / 2;
const y = rect.y //+ h / 2;
this.ctx.setLineDash([4, 4]);
this.ctx.lineWidth = 1;
this.ctx.strokeStyle = '#ffa568';
this.ctx.beginPath();
this.ctx.moveTo( x + w / 2 , y + h / 2 );
this.ctx.lineTo(this.item.x, this.item.y);
// this.ctx.fill();
this.ctx.stroke();
this.ctx.restore();
}
drawFrame() {
this.ctx.save();
const rect = this.getBoundingBox();
const w = rect.width;
const h = rect.height;
const x = rect.x //+ w / 2;
const y = rect.y //+ h / 2;
this.ctx.setLineDash([4, 4]);
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = '#ffa568';
// this.ctx.fillStyle = '#ffffff';
this.ctx.beginPath();
this.ctx.moveTo( x - w / 2, y - h / 2);
this.ctx.lineTo(x + w / 2, y - h / 2);
this.ctx.lineTo(x + w / 2, y + h / 2);
this.ctx.lineTo(x - w / 2, y + h / 2);
this.ctx.lineTo(x - w / 2, y - h / 2);
// this.ctx.fill();
this.ctx.stroke();
this.ctx.restore();
}
draw() {
super.draw();
if (this.lineDashFlag) {
this.drawLine();
// this.drawFrame();
// this.drawArrow();
}
}
}
export class EditorItem extends MySprite {
......@@ -2208,6 +2364,8 @@ export class EditorItem extends MySprite {
arrow: MySprite;
label: Label;
text;
arrowTop;
arrowRight;
showLabel(text = null) {
......@@ -2246,6 +2404,13 @@ export class EditorItem extends MySprite {
this.arrow.load('assets/common/arrow.png', 1, 0);
this.arrow.setScaleXY(0.06);
// this.arrowTop = new MySprite(this.ctx);
// this.arrowTop.load('assets/common/arrow_top.png', 0.5, 0);
// this.arrowTop.setScaleXY(0.06);
//
// this.arrowRight = new MySprite(this.ctx);
// this.arrowRight.load('assets/common/arrow_right.png', 1, 0.5);
// this.arrowRight.setScaleXY(0.06);
}
this.showLabel();
......@@ -2262,16 +2427,25 @@ export class EditorItem extends MySprite {
this.hideLabel();
}
refreshLabelScale() {}
drawArrow() {
if (!this.arrow) { return; }
const rect = this.getBoundingBox();
this.arrow.x = rect.x + rect.width;
this.arrow.y = rect.y;
this.arrow.update();
// this.arrowTop.x = rect.x + rect.width / 2;
// this.arrowTop.y = rect.y;
// this.arrowTop.update();
//
// this.arrowRight.x = rect.x + rect.width;
// this.arrowRight.y = rect.y + rect.height / 2;
// this.arrowRight.update();
}
drawFrame() {
......@@ -2325,784 +2499,3 @@ export class EditorItem extends MySprite {
}
//
//
// import TWEEN from '@tweenjs/tween.js';
//
//
// class Sprite {
// x = 0;
// y = 0;
// color = '';
// radius = 0;
// alive = false;
// margin = 0;
// angle = 0;
// ctx;
//
// constructor(ctx) {
// this.ctx = ctx;
// }
// update($event) {
// this.draw();
// }
// draw() {
//
// }
//
// }
//
//
//
//
//
// export class MySprite extends Sprite {
//
// width = 0;
// height = 0;
// _anchorX = 0;
// _anchorY = 0;
// _offX = 0;
// _offY = 0;
// scaleX = 1;
// scaleY = 1;
// alpha = 1;
// rotation = 0;
// visible = true;
//
// children = [this];
//
// img;
// _z = 0;
//
//
// init(imgObj = null, anchorX:number = 0.5, anchorY:number = 0.5) {
//
// if (imgObj) {
//
// this.img = imgObj;
//
// this.width = this.img.width;
// this.height = this.img.height;
// }
//
// this.anchorX = anchorX;
// this.anchorY = anchorY;
// }
//
//
//
// update($event = null) {
// if (this.visible) {
// this.draw();
// }
// }
// draw() {
//
// this.ctx.save();
//
// this.drawInit();
//
// this.updateChildren();
//
// this.ctx.restore();
// }
//
// drawInit() {
//
// this.ctx.translate(this.x, this.y);
//
// this.ctx.rotate(this.rotation * Math.PI / 180);
//
// this.ctx.scale(this.scaleX, this.scaleY);
//
// this.ctx.globalAlpha = this.alpha;
//
// }
//
// drawSelf() {
// if (this.img) {
// this.ctx.drawImage(this.img, this._offX, this._offY);
// }
// }
//
// updateChildren() {
//
// if (this.children.length <= 0) { return; }
//
// for (let i = 0; i < this.children.length; i++) {
//
// if (this.children[i] === this) {
//
// this.drawSelf();
// } else {
//
// this.children[i].update();
// }
// }
// }
//
//
// load(url, anchorX = 0.5, anchorY = 0.5) {
//
// return new Promise((resolve, reject) => {
// const img = new Image();
// img.onload = () => resolve(img);
// img.onerror = reject;
// img.src = url;
// }).then(img => {
//
// this.init(img, anchorX, anchorY);
// return img;
// });
// }
//
// addChild(child, z = 1) {
// if (this.children.indexOf(child) === -1) {
// this.children.push(child);
// child._z = z;
// child.parent = this;
// }
//
// this.children.sort((a, b) => {
// return a._z - b._z;
// });
//
// }
// removeChild(child) {
// const index = this.children.indexOf(child);
// if (index !== -1) {
// this.children.splice(index, 1);
// }
// }
//
// set anchorX(value) {
// this._anchorX = value;
// this.refreshAnchorOff();
// }
// get anchorX() {
// return this._anchorX;
// }
// set anchorY(value) {
// this._anchorY = value;
// this.refreshAnchorOff();
// }
// get anchorY() {
// return this._anchorY;
// }
// refreshAnchorOff() {
// this._offX = -this.width * this.anchorX;
// this._offY = -this.height * this.anchorY;
// }
//
// setScaleXY(value) {
// this.scaleX = this.scaleY = value;
// }
//
// getBoundingBox() {
//
// const x = this.x + this._offX * this.scaleX;
// const y = this.y + this._offY * this.scaleY;
// const width = this.width * this.scaleX;
// const height = this.height * this.scaleY;
//
// return {x, y, width, height};
// }
//
// }
//
//
//
//
//
// export class Item extends MySprite {
//
// baseX;
//
// move(targetY, callBack) {
//
// const self = this;
//
// const tween = new TWEEN.Tween(this)
// .to({ y: targetY }, 2500)
// .easing(TWEEN.Easing.Quintic.Out)
// .onComplete(function() {
//
// self.hide(callBack);
// // if (callBack) {
// // callBack();
// // }
// })
// .start();
//
// }
//
// show(callBack = null) {
//
// const tween = new TWEEN.Tween(this)
// .to({ alpha: 1 }, 800)
// // .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
// .onComplete(function() {
// if (callBack) {
// callBack();
// }
// })
// .start(); // Start the tween immediately.
//
// }
//
// hide(callBack = null) {
//
// const tween = new TWEEN.Tween(this)
// .to({ alpha: 0 }, 800)
// // .easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
// .onComplete(function() {
// if (callBack) {
// callBack();
// }
// })
// .start(); // Start the tween immediately.
// }
//
//
// shake(id) {
//
//
// if (!this.baseX) {
// this.baseX = this.x;
// }
//
// const baseX = this.baseX;
// const baseTime = 50;
// const sequence = [
// {target: {x: baseX + 40 * id}, time: baseTime - 25},
// {target: {x: baseX - 20 * id}, time: baseTime},
// {target: {x: baseX + 10 * id}, time: baseTime},
// {target: {x: baseX - 5 * id}, time: baseTime},
// {target: {x: baseX + 2 * id}, time: baseTime},
// {target: {x: baseX - 1 * id}, time: baseTime},
// {target: {x: baseX}, time: baseTime},
//
// ];
//
//
// const self = this;
//
// function runSequence() {
//
// if (self['shakeTween']) {
// self['shakeTween'].stop();
// }
//
// const tween = new TWEEN.Tween(self);
//
// if (sequence.length > 0) {
// // console.log('sequence.length: ', sequence.length);
// const action = sequence.shift();
// tween.to(action['target'], action['time']);
// tween.onComplete( () => {
// runSequence();
// });
// tween.start();
//
// self['shakeTween'] = tween;
// }
// }
//
// runSequence();
//
// }
//
//
//
// drop(targetY, callBack = null) {
//
// const self = this;
//
// const time = Math.abs(targetY - this.y) * 2.4;
//
// this.alpha = 1;
//
// const tween = new TWEEN.Tween(this)
// .to({ y: targetY }, time)
// .easing(TWEEN.Easing.Cubic.In)
// .onComplete(function() {
//
// // self.hideItem(callBack);
// if (callBack) {
// callBack();
// }
// })
// .start();
//
//
// }
//
//
// }
//
//
// export class EndSpr extends MySprite {
//
// show(s) {
//
// this.scaleX = this.scaleY = 0;
// this.alpha = 0;
//
// const tween = new TWEEN.Tween(this)
// .to({ alpha: 1, scaleX: s, scaleY: s }, 800)
// .easing(TWEEN.Easing.Elastic.Out) // Use an easing function to make the animation smooth.
// .onComplete(function() {
//
// })
// .start(); // Start the tween immediately.
//
// }
// }
//
//
//
// export class ShapeRect extends MySprite {
//
// fillColor = '#FF0000';
//
// setSize(w, h) {
// this.width = w;
// this.height = h;
//
// console.log('w:', w);
// console.log('h:', h);
// }
//
// drawShape() {
//
// this.ctx.fillStyle = this.fillColor;
// this.ctx.fillRect(this._offX, this._offY, this.width, this.height);
//
// }
//
//
// drawSelf() {
// super.drawSelf();
// this.drawShape();
// }
// }
//
//
// export class HotZoneItem extends MySprite {
//
//
// lineDashFlag = false;
// arrow: MySprite;
// label: Label;
// title;
//
// arrowTop;
// arrowRight;
//
// audio_url;
// pic_url;
// text;
// private _itemType;
// private shapeRect: ShapeRect;
//
// get itemType() {
// return this._itemType;
// }
// set itemType(value) {
// this._itemType = value;
// }
//
// setSize(w, h) {
// this.width = w;
// this.height = h;
//
//
// const rect = new ShapeRect(this.ctx);
// rect.x = -w / 2;
// rect.y = -h / 2;
// rect.setSize(w, h);
// rect.fillColor = '#ffffff';
// rect.alpha = 0.2;
// this.addChild(rect);
// }
//
// showLabel(text = null) {
//
//
// if (!this.label) {
// this.label = new Label(this.ctx);
// this.label.anchorY = 0;
// this.label.fontSize = '40px';
// this.label.textAlign = 'center';
// this.addChild(this.label);
// // this.label.scaleX = 1 / this.scaleX;
// // this.label.scaleY = 1 / this.scaleY;
//
// this.refreshLabelScale();
//
// }
//
// if (text) {
// this.label.text = text;
// } else if (this.title) {
// this.label.text = this.title;
// }
// this.label.visible = true;
//
// }
//
// hideLabel() {
// if (!this.label) { return; }
//
// this.label.visible = false;
// }
//
// refreshLabelScale() {
// if (this.scaleX == this.scaleY) {
// this.label.setScaleXY(1);
// }
//
// if (this.scaleX > this.scaleY) {
// this.label.scaleX = this.scaleY / this.scaleX;
// } else {
// this.label.scaleY = this.scaleX / this.scaleY;
// }
// }
//
// showLineDash() {
// this.lineDashFlag = true;
//
// if (this.arrow) {
// this.arrow.visible = true;
// } else {
// this.arrow = new MySprite(this.ctx);
// this.arrow.load('assets/common/arrow.png', 1, 0);
// this.arrow.setScaleXY(0.06);
//
// this.arrowTop = new MySprite(this.ctx);
// this.arrowTop.load('assets/common/arrow_top.png', 0.5, 0);
// this.arrowTop.setScaleXY(0.06);
//
// this.arrowRight = new MySprite(this.ctx);
// this.arrowRight.load('assets/common/arrow_right.png', 1, 0.5);
// this.arrowRight.setScaleXY(0.06);
// }
//
// this.showLabel();
// }
//
// hideLineDash() {
//
// this.lineDashFlag = false;
//
// if (this.arrow) {
// this.arrow.visible = false;
// }
//
// this.hideLabel();
// }
//
//
//
// drawArrow() {
// if (!this.arrow) { return; }
//
// const rect = this.getBoundingBox();
// this.arrow.x = rect.x + rect.width;
// this.arrow.y = rect.y;
//
// this.arrow.update();
//
//
// this.arrowTop.x = rect.x + rect.width / 2;
// this.arrowTop.y = rect.y;
// this.arrowTop.update();
//
// this.arrowRight.x = rect.x + rect.width;
// this.arrowRight.y = rect.y + rect.height / 2;
// this.arrowRight.update();
// }
//
// drawFrame() {
//
//
// this.ctx.save();
//
//
// const rect = this.getBoundingBox();
//
// const w = rect.width;
// const h = rect.height;
// const x = rect.x + w / 2;
// const y = rect.y + h / 2;
//
// this.ctx.setLineDash([5, 5]);
// this.ctx.lineWidth = 2;
// this.ctx.strokeStyle = '#1bfff7';
// // this.ctx.fillStyle = '#ffffff';
//
// this.ctx.beginPath();
//
// this.ctx.moveTo( x - w / 2, y - h / 2);
//
// this.ctx.lineTo(x + w / 2, y - h / 2);
//
// this.ctx.lineTo(x + w / 2, y + h / 2);
//
// this.ctx.lineTo(x - w / 2, y + h / 2);
//
// this.ctx.lineTo(x - w / 2, y - h / 2);
//
// // this.ctx.fill();
// this.ctx.stroke();
//
//
//
//
// this.ctx.restore();
//
// }
//
// draw() {
// super.draw();
//
// if (this.lineDashFlag) {
// this.drawFrame();
// this.drawArrow();
// }
// }
// }
//
//
// export class EditorItem extends MySprite {
//
// lineDashFlag = false;
// arrow: MySprite;
// label:Label;
// text;
//
// showLabel(text = null) {
//
//
// if (!this.label) {
// this.label = new Label(this.ctx);
// this.label.anchorY = 0;
// this.label.fontSize = '50px';
// this.label.textAlign = 'center';
// this.addChild(this.label);
// this.label.setScaleXY(1 / this.scaleX);
// }
//
// if (text) {
// this.label.text = text;
// } else if (this.text) {
// this.label.text = this.text;
// }
// this.label.visible = true;
//
// }
//
// hideLabel() {
// if (!this.label) { return; }
//
// this.label.visible = false;
// }
//
// showLineDash() {
// this.lineDashFlag = true;
//
// if (this.arrow) {
// this.arrow.visible = true;
// } else {
// this.arrow = new MySprite(this.ctx);
// this.arrow.load('assets/common/arrow.png', 1, 0);
// this.arrow.setScaleXY(0.06);
//
// }
//
// this.showLabel();
// }
//
// hideLineDash() {
//
// this.lineDashFlag = false;
//
// if (this.arrow) {
// this.arrow.visible = false;
// }
//
// this.hideLabel();
// }
//
//
//
// drawArrow() {
// if (!this.arrow) { return; }
//
// const rect = this.getBoundingBox();
// this.arrow.x = rect.x + rect.width;
// this.arrow.y = rect.y;
//
// this.arrow.update();
// }
//
// drawFrame() {
//
//
// this.ctx.save();
//
//
// const rect = this.getBoundingBox();
//
// const w = rect.width;
// const h = rect.height;
// const x = rect.x + w / 2;
// const y = rect.y + h / 2;
//
// this.ctx.setLineDash([5, 5]);
// this.ctx.lineWidth = 2;
// this.ctx.strokeStyle = '#1bfff7';
// // this.ctx.fillStyle = '#ffffff';
//
// this.ctx.beginPath();
//
// this.ctx.moveTo( x - w / 2, y - h / 2);
//
// this.ctx.lineTo(x + w / 2, y - h / 2);
//
// this.ctx.lineTo(x + w / 2, y + h / 2);
//
// this.ctx.lineTo(x - w / 2, y + h / 2);
//
// this.ctx.lineTo(x - w / 2, y - h / 2);
//
// // this.ctx.fill();
// this.ctx.stroke();
//
//
//
//
// this.ctx.restore();
//
// }
//
// draw() {
// super.draw();
//
// if (this.lineDashFlag) {
// this.drawFrame();
// this.drawArrow();
// }
// }
// }
//
//
//
// export class Label extends MySprite {
//
// text:String;
// fontSize:String = '40px';
// fontName:String = 'Verdana';
// textAlign:String = 'left';
//
//
// constructor(ctx) {
// super(ctx);
// this.init();
// }
//
// drawText() {
//
// // console.log('in drawText', this.text);
//
// if (!this.text) { return; }
//
// this.ctx.font = `${this.fontSize} ${this.fontName}`;
// this.ctx.textAlign = this.textAlign;
// this.ctx.textBaseline = 'middle';
// this.ctx.fontWeight = 900;
//
// this.ctx.lineWidth = 5;
// this.ctx.strokeStyle = '#ffffff';
// this.ctx.strokeText(this.text, 0, 0);
//
// this.ctx.fillStyle = '#000000';
// this.ctx.fillText(this.text, 0, 0);
//
//
// }
//
//
// drawSelf() {
// super.drawSelf();
// this.drawText();
// }
//
// }
//
//
//
// export function getPosByAngle(angle, len) {
//
// const radian = angle * Math.PI / 180;
// const x = Math.sin(radian) * len;
// const y = Math.cos(radian) * len;
//
// return {x, y};
//
// }
//
// export function getAngleByPos(px, py, mx, my) {
//
// // const _x = p2x - p1x;
// // const _y = p2y - p1y;
// // const tan = _y / _x;
// //
// // const radina = Math.atan(tan); // 用反三角函数求弧度
// // const angle = Math.floor(180 / (Math.PI / radina)); //
// //
// // console.log('r: ' , angle);
// // return angle;
// //
//
//
//
// const x = Math.abs(px - mx);
// const y = Math.abs(py - my);
// // const x = Math.abs(mx - px);
// // const y = Math.abs(my - py);
// const z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
// const cos = y / z;
// const radina = Math.acos(cos); // 用反三角函数求弧度
// let angle = Math.floor(180 / (Math.PI / radina) * 100) / 100; // 将弧度转换成角度
//
// if(mx > px && my > py) {// 鼠标在第四象限
// angle = 180 - angle;
// }
//
// if(mx === px && my > py) {// 鼠标在y轴负方向上
// angle = 180;
// }
//
// if(mx > px && my === py) {// 鼠标在x轴正方向上
// angle = 90;
// }
//
// if(mx < px && my > py) {// 鼠标在第三象限
// angle = 180 + angle;
// }
//
// if(mx < px && my === py) {// 鼠标在x轴负方向
// angle = 270;
// }
//
// if(mx < px && my < py) {// 鼠标在第二象限
// angle = 360 - angle;
// }
//
// // console.log('angle: ', angle);
// return angle;
//
// }
......@@ -32,33 +32,143 @@
<nz-divider style="margin-top: 10px;"></nz-divider>
<div style="margin-top: -20px; margin-bottom: 5px; width: 100%;">
<div style="margin-top: -20px; margin-bottom: 5px">
<nz-radio-group [ngModel]="it.itemType" (ngModelChange)="radioChange($event, it)">
<label *ngIf="isHasRect" nz-radio nzValue="rect">矩形</label>
<label *ngIf="isHasPic" nz-radio nzValue="pic">图片</label>
<label *ngIf="isHasText" nz-radio nzValue="text">文本</label>
</nz-radio-group>
</div>
<div *ngIf="customTypeGroupArr">
<nz-radio-group [ngModel]="it.gIdx" (ngModelChange)="customRadioChange($event, it)" style="display: flex; align-items: center; justify-content: center; flex-wrap: wrap;">
<div *ngFor="let group of customTypeGroupArr; let gIdx = index" style="display: flex; ">
<label nz-radio nzValue="{{gIdx}}">{{group.name}}</label>
</div>
</nz-radio-group>
<div *ngIf="it.itemType == 'pic'">
<app-upload-image-with-preview
[picUrl]="it?.pic_url"
(imageUploaded)="onItemImgUploadSuccess($event, it)">
</app-upload-image-with-preview>
</div>
</div>
<!-- <div *ngIf="!customTypeGroupArr">
<nz-radio-group [ngModel]="it.itemType" (ngModelChange)="radioChange($event, it)" style="display: flex; align-items: center; justify-content: center">
<label *ngIf="isHasRect" nz-radio nzValue="rect">矩形</label>
<label *ngIf="isHasPic" nz-radio nzValue="pic">图片</label>
<label *ngIf="isHasText" nz-radio nzValue="text">文本</label>
</nz-radio-group>
</div> -->
<div *ngIf="it.itemType == 'text'">
<input type="text" nz-input [(ngModel)]="it.text" (blur)="saveText(it)">
</div>
<div style="width: 100%; margin-top: 5px;">
<app-audio-recorder
[audioUrl]="it.audio_url"
(audioUploaded)="onItemAudioUploadSuccess($event, it)"
></app-audio-recorder>
<div *ngIf="customTypeGroupArr && customTypeGroupArr[it.gIdx]">
<div *ngIf="customTypeGroupArr[it.gIdx].pic">
<app-upload-image-with-preview
[picUrl]="it?.pic_url"
(imageUploaded)="onItemImgUploadSuccess($event, it)">
</app-upload-image-with-preview>
</div>
<div *ngIf="customTypeGroupArr[it.gIdx].text" style="margin-top: 5px">
<input type="text" nz-input [(ngModel)]="it.text" (blur)="saveText(it)">
</div>
<div *ngIf="customTypeGroupArr[it.gIdx].anima" align="center" style="margin-top: 5px">
<button nz-button (click)="setAnimaBtnClick(i)" >
<i nz-icon nzType="tool" nzTheme="outline"></i>
配置龙骨动画
</button>
</div>
<div *ngIf="customTypeGroupArr[it.gIdx].animaSmall" align="center" style="margin-top: 5px">
<button nz-button (click)="setAnimaSmallBtnClick(i)" >
<i nz-icon nzType="tool" nzTheme="outline"></i>
配置龙骨动画(小)
</button>
</div>
<div *ngIf="customTypeGroupArr[it.gIdx].audio" style="display: flex;align-items: center; margin-top: 5px">
<app-audio-recorder
style="margin: auto"
[audioUrl]="it.audio_url"
(audioUploaded)="onItemAudioUploadSuccess($event, it)"
></app-audio-recorder>
</div>
<!-- <div *ngIf="customTypeGroupArr[it.gIdx]?.action" style="display: flex;align-items: center; margin-top: 5px">-->
<!-- <app-custom-action-->
<!-- style="margin: auto"-->
<!-- [item]="it ? it['actionData_' + it.gIdx] : {}"-->
<!-- [type]="customTypeGroupArr[it.gIdx].action.type"-->
<!-- [option]="customTypeGroupArr[it.gIdx].action.option"-->
<!-- (save)="onSaveCustomAction($event, it)">-->
<!-- ></app-custom-action>-->
<!-- </div>-->
<div *ngIf="customTypeGroupArr[it.gIdx]?.isShowPos" style="display: flex; align-items: center; justify-content: center; margin-top: 5px;">
x: <input type="text" nz-input [(ngModel)]="it.posX" style="width: 50px; margin-right: 15px;" (blur)="saveItemPos(it)">
y: <input type="text" nz-input [(ngModel)]="it.posY" style="width: 50px" (blur)="saveItemPos(it)">
</div>
<div *ngIf="customTypeGroupArr[it.gIdx]?.select" align="center" >
<nz-select [(ngModel)]="it.selectType" nzAllowClear nzPlaceHolder="Choose" style="width: 70%; margin-top: 5px;">
<nz-option *ngFor="let s of customTypeGroupArr[it.gIdx]?.select" [nzValue]="s.value" [nzLabel]="s.label">
</nz-option>
</nz-select>
</div>
<div *ngIf="customTypeGroupArr[it.gIdx]?.label" align="center" style="margin-top: 5px; display: flex; align-items: center; justify-content: center;">
<span style="width: 30%;">{{customTypeGroupArr[it.gIdx].label + ':'}}</span>
<input type="text" nz-input [(ngModel)]="it.labelText" (blur)="saveText(it)">
</div>
<!-- <div *ngIf="customTypeGroupArr[it.gIdx]?.mathLabel" align="center" style="margin-top: 5px; display: flex; align-items: center; justify-content: center;">-->
<!-- <span style="width: 30%;">{{customTypeGroupArr[it.gIdx].mathLabel + ':'}}</span>-->
<!-- <app-formula-input [(ngfModel)]="it.mathLabel" ></app-formula-input>-->
<!-- </div>-->
<div *ngIf="customTypeGroupArr[it.gIdx]?.isCopy" align="center" style="margin-top: 5px; display: flex; align-items: center; justify-content: center;">
<button nz-button (click)="copyItem(it)" >
<i nz-icon nzType="copy" nzTheme="outline"></i>
复制粘贴
</button>
</div>
</div>
<!-- <div *ngIf="!customTypeGroupArr">
<div *ngIf="it.itemType == 'pic'">
<app-upload-image-with-preview
[picUrl]="it?.pic_url"
(imageUploaded)="onItemImgUploadSuccess($event, it)">
</app-upload-image-with-preview>
</div>
<div *ngIf="it.itemType == 'text'">
<input type="text" nz-input [(ngModel)]="it.text" (blur)="saveText(it)">
</div>
<div *ngIf="isHasAudio"
style="width: 100%; margin-top: 5px; display: flex; align-items: center; justify-items: center;">
<app-audio-recorder
style="margin: auto"
[audioUrl]="it.audio_url"
(audioUploaded)="onItemAudioUploadSuccess($event, it)"
></app-audio-recorder>
</div>
<div *ngIf="it.itemType == 'rect' && isHasAnima" align="center" style="margin-bottom: 5px">
<button nz-button (click)="setAnimaBtnClick(i)" >
<i nz-icon nzType="tool" nzTheme="outline"></i>
配置龙骨动画
</button>
</div>
</div> -->
</div>
</div>
......@@ -83,12 +193,29 @@
<div class="save-box">
<button class="save-btn" nz-button nzType="primary" [nzSize]="'large'" nzShape="round"
<button style="margin-left: 200px" class="save-btn" nz-button nzType="primary" [nzSize]="'large'" nzShape="round"
(click)="saveClick()" >
<i nz-icon nzType="save"></i>
Save
</button>
<div *ngIf="isCopyData" style="height: 40px; display: flex; justify-items: center;" >
<label style="margin-left: 40px" nz-checkbox [(ngModel)]="bgItem.isShowDebugLine">显示辅助框</label>
<button style="margin-left: 20px; margin-top: -5px" nz-button (click)="copyHotZoneData()"> 复制基础数据 </button>
<div style="margin-left: 10px; margin-top: -5px" >
<span>粘贴数据: </span>
<input style="width: 100px;" type="text" nz-input [(ngModel)]="pasteData" >
<button style="margin-left: 5px;" nz-button [disabled]="pasteData==''" nzType="primary" (click)="importData()">导入</button>
</div>
</div>
</div>
......@@ -98,3 +225,52 @@
<label style="opacity: 0; position: absolute; top: 0px; font-family: 'BRLNSR_1'">1</label>
<!--龙骨面板-->
<nz-modal [(nzVisible)]="animaPanelVisible" nzTitle="配置资源文件" (nzAfterClose)="closeAfterPanel()" (nzOnCancel)="animaPanelCancel()" (nzOnOk)="animaPanelOk()" nzOkText="保存">
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 ske_json 文件: </span>
<nz-upload [nzShowUploadList]="false"
nzAccept="application/json"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="skeJsonHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isSkeJsonLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="skeJsonData['name']" style="margin-left: 10px"><u> {{skeJsonData['name']}} </u></span>
</div>
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 tex_json 文件: </span>
<nz-upload [nzShowUploadList]="false"
nzAccept="application/json"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="texJsonHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isTexJsonLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="texJsonData['name']" style="margin-left: 10px"><u> {{texJsonData['name']}} </u></span>
</div>
<div class="anima-upload-btn">
<span style="margin-right: 10px">上传 tex_png 文件: </span>
<nz-upload [nzShowUploadList]="false"
nzAccept = "image/*"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="texPngHandleChange($event)">
<button nz-button><i nz-icon nzType="upload"></i><span>Upload</span></button>
</nz-upload>
<i *ngIf="isTexPngLoading" style="margin-left: 10px;" nz-icon [nzType]="'loading'"></i>
<span *ngIf="texPngData['name']" style="margin-left: 10px"><u> {{texPngData['name']}} </u></span>
</div>
<div class="anima-upload-btn" *ngIf="customTypeGroupArr && customTypeGroupArr[curDragonBoneGIdx] && customTypeGroupArr[curDragonBoneGIdx].animaNames">
提示:需包含以下动画: {{customTypeGroupArr[curDragonBoneGIdx].animaNames.toString()}}
</div>
</nz-modal>
......@@ -81,6 +81,10 @@
}
}
.anima-upload-btn {
padding: 10px;
}
h5 {
margin-top: 1rem;
}
......@@ -89,8 +93,8 @@ h5 {
@font-face
{
font-family: 'BRLNSR_1';
src: url("/assets/font/BRLNSR_1.TTF") ;
font-family: 'ahronbd-1';
src: url("/assets/font/ahronbd-1.ttf") ;
}
......@@ -105,106 +109,3 @@ h5 {
//@import '../../../style/common_mixin';
//
//.p-image-uploader {
// position: relative;
// display: block;
// width: 100%;
// height: 0;
// padding-bottom: 56.25%;
// .p-box {
// position: absolute;
// left: 0;
// top: 0;
// right: 0;
// bottom: 0;
// border: 2px dashed #ddd;
// border-radius: 0.5rem;
// background-color: #fafafa;
// text-align: center;
// color: #aaa;
// .p-upload-icon {
// text-align: center;
// margin: auto;
// .anticon-upload {
// color: #888;
// font-size: 5rem;
// }
// .p-progress-bar {
// position: relative;
// width: 20rem;
// height: 1.5rem;
// border: 1px solid #ccc;
// border-radius: 1rem;
// .p-progress-bg {
// background-color: #1890ff;
// border-radius: 1rem;
// height: 100%;
// }
// .p-progress-value {
// position: absolute;
// top: 0;
// left: 0;
// width: 100%;
// height: 100%;
// text-shadow: 0 0 4px #000;
// color: white;
// text-align: center;
// font-size: 0.9rem;
// line-height: 1.5rem;
// }
// }
// }
// .p-preview {
// width: 100%;
// height: 100%;
// //background-image: url("https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png");
// @include k-img-bg();
// }
// }
//}
//
//.p-btn-delete {
// position: absolute;
// right: -0.5rem;
// top: -0.5rem;
// width: 2rem;
// height: 2rem;
// border: 0.2rem solid white;
// border-radius: 50%;
// font-size: 1.2rem;
// background-color: #fb781a;
// color: white;
// text-align: center;
//}
//
//.p-upload-progress-bg {
// position: absolute;
// width: 100%;
// height: 100%;
// display: flex;
// align-items: center;
// justify-content: center;
// & .i-text {
// position: absolute;
// text-align: center;
// color: white;
// text-shadow: 0 0 2px rgba(0, 0, 0, .85);
// }
// & .i-bg {
// position: absolute;
// left: 0;
// top: 0;
// height: 100%;
// background-color: #27b43f;
// border-radius: 0.5rem;
// }
//}
//
//
//:host ::ng-deep .ant-upload {
// display: block;
//}
import {
ApplicationRef,
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
......@@ -12,10 +14,11 @@ import {
} from '@angular/core';
import {Subject} from 'rxjs';
import {debounceTime} from 'rxjs/operators';
import {EditorItem, HotZoneImg, HotZoneItem, HotZoneLabel, Label, MySprite, removeItemFromArr} from './Unit';
import {DragItem, EditorItem, HotZoneImg, HotZoneItem, HotZoneLabel, Label, MySprite, removeItemFromArr, ShapeRect, ShapeRectNew} from './Unit';
import TWEEN from '@tweenjs/tween.js';
import {getMinScale} from "../../play/Unit";
import {tar} from "compressing";
import {getMinScale} from '../../play/Unit';
import {tar} from 'compressing';
import {NzMessageService} from 'ng-zorro-antd';
@Component({
......@@ -25,18 +28,14 @@ import {tar} from "compressing";
})
export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
@ViewChild('canvas', {static: true}) canvas: ElementRef;
@ViewChild('wrap', {static: true}) wrap: ElementRef;
@Input()
imgItemArr = null;
@Input()
hotZoneItemArr = null;
@Input()
hotZoneArr = null;
@Output()
save = new EventEmitter();
@ViewChild('canvas', {static: true}) canvas: ElementRef;
@ViewChild('wrap', {static: true}) wrap: ElementRef;
@Input()
isHasRect = true;
@Input()
......@@ -44,16 +43,31 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
@Input()
isHasText = true;
@Input()
hotZoneFontObj = {
size: 50,
name: 'BRLNSR_1',
color: '#8f3758'
}
isHasAudio = true;
@Input()
isHasAnima = false;
@Input()
customTypeGroupArr; // [{name:string, rect:boolean, pic:boolean, text:boolean, audio:boolean, anima:boolean, animaNames:['name1', ..]}, ...]
@Input()
// hotZoneFontObj;
@Input()
isCopyData = false;
hotZoneFontObj;
// hotZoneFontObj = {
// size: 50,
// name: 'ahronbd-1',
// color: '#8f3758'
// }
@Input()
defaultItemType = 'text';
@Input()
hotZoneImgSize = 190;
hotZoneImgSize = 0;
@Output()
save = new EventEmitter();
saveDisabled = true;
......@@ -86,8 +100,43 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
changeSizeFlag = false;
changeTopSizeFlag = false;
changeRightSizeFlag = false;
constructor() {
animaPanelVisible = false;
uploadUrl;
uploadData;
skeJsonData = {};
texJsonData = {};
texPngData = {};
animaName = '';
curDragonBoneIndex;
curDragonBoneGIdx;
pasteData = '';
isSkeJsonLoading = false;
isTexJsonLoading = false;
isTexPngLoading = false;
isAnimaSmall = false;
savePropertyArr = [
'id',
'gIdx',
'selectType',
'labelText',
'posX',
'posY',
'mathLabel',
]
constructor(private nzMessageService: NzMessageService, private appRef: ApplicationRef, private changeDetectorRef: ChangeDetectorRef) {
this.uploadUrl = (<any> window).courseware.uploadUrl();
this.uploadData = (<any> window).courseware.uploadData();
window['air'].getUploadCallback = (url, data) => {
this.uploadUrl = url;
this.uploadData = data;
};
}
_bgItem = null;
......@@ -110,11 +159,14 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
ngOnInit() {
this.initListener();
// this.init();
this.update();
this.refresh();
}
ngOnDestroy() {
......@@ -136,10 +188,12 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
onItemImgUploadSuccess(e, item) {
item.pic_url = e.url;
this.loadHotZonePic(item.pic, e.url);
this.refresh();
}
onItemAudioUploadSuccess(e, item) {
item.audio_url = e.url;
this.refresh();
}
......@@ -150,37 +204,61 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.renderArr.push(this.bg);
}
if (!this.bgItem.url) {
this.bgItem.url = 'http://teach.cdn.ireadabc.com/8ebb1858564340ea0936b83e3280ad7d.jpg';
}
const bg = this.bg;
if (this.bgItem.url) {
// if (this.bgItem.url) {
bg.load(this.bgItem.url).then(() => {
const rate1 = this.canvasWidth / bg.width;
const rate2 = this.canvasHeight / bg.height;
bg.load(this.bgItem.url).then(() => {
const rate1 = this.canvasWidth / bg.width;
const rate2 = this.canvasHeight / bg.height;
const rate = Math.min(rate1, rate2);
bg.setScaleXY(rate);
const rate = Math.min(rate1, rate2);
bg.setScaleXY(rate);
bg.x = this.canvasWidth / 2;
bg.y = this.canvasHeight / 2;
bg.removeChildren();
bg.x = this.canvasWidth / 2;
bg.y = this.canvasHeight / 2;
const bgBorder = new ShapeRectNew(this.ctx);
bgBorder.setSize(bg.width, bg.height, 0);
bgBorder.fillColor = '#ff0000';
bgBorder.fill = false;
bgBorder.stroke = true;
bgBorder.x = -bg.width / 2;
bgBorder.y = -bg.height / 2;
bgBorder.lineWidth = 0.5;
bg.addChild(bgBorder);
if (callBack) {
callBack();
}
});
}
if (callBack) {
callBack();
}
this.refresh();
});
// }
}
addBtnClick() {
addBtnClick(data=null) {
// this.imgArr.push({});
// this.hotZoneArr.push({});
const item = this.getHotZoneItem();
const item = this.getHotZoneItem(data);
this.hotZoneArr.push(item);
this.refreshItem(item);
if (this.customTypeGroupArr) {
this.refreshCustomItem(item);
} else {
this.refreshItem(item);
}
this.refreshHotZoneId();
......@@ -191,6 +269,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
const item = this.hotZoneArr.splice(index, 1)[0];
removeItemFromArr(this.renderArr, item.pic);
removeItemFromArr(this.renderArr, item.textLabel);
removeItemFromArr(this.renderArr, item.drag);
this.refreshHotZoneId();
......@@ -199,6 +278,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
onImgUploadSuccessByImg(e, img) {
img.pic_url = e.url;
this.refreshImage(img);
this.refresh();
}
refreshImage(img) {
......@@ -221,6 +301,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
}
}
this.refresh();
}
......@@ -245,10 +326,18 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
item.anchorX = 0.5;
item.anchorY = 0.5;
item.x = this.canvasWidth / 2;
item.y = this.canvasHeight / 2;
item.itemType = this.defaultItemType;
item.itemType = this.getDefaultItemType();
item.gIdx = '0';
item['id'] = this.createItemId() // new Date().getTime().toString();
item['data'] = saveData;
console.log('item.x: ', item.x);
if (saveData) {
......@@ -257,41 +346,203 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
item.scaleY = saveRect.height / item.height;
item.x = saveRect.x + saveRect.width / 2;
item.y = saveRect.y + saveRect.height / 2;
item.gIdx = saveData.gIdx;
item['id'] = saveData.id;
item['skeJsonData'] = saveData.skeJsonData;
item['texJsonData'] = saveData.texJsonData;
item['texPngData'] = saveData.texPngData;
item['actionData_' + item.gIdx] = saveData['actionData_' + item.gIdx];
this.savePropertyArr.forEach((key) => {
if (saveData[key]) {
item[key] = saveData[key];
}
})
}
console.log('item.x:~~ ', item.x);
item.showLineDash();
const pic = new HotZoneImg(this.ctx);
// const pic = new HotZoneImg(this.ctx);
this.setItemPic(item, saveData);
this.setItemLabel(item, saveData);
this.setItemAnima(item, saveData);
this.setItemDrag(item, saveData);
return item;
}
setItemPic(item, saveData) {
console.log('in setItemPic ', saveData);
const pic = new EditorItem(this.ctx);
pic.visible = false;
item['pic'] = pic;
if (saveData && saveData.pic_url) {
this.loadHotZonePic(pic, saveData.pic_url);
if (saveData) {
let picUrl = saveData.pic_url;
const actionData = saveData['actionData_' + item.gIdx];
if (actionData && actionData.type == 'pic') {
picUrl = actionData.pic_url;
}
console.log('saveData: ', saveData);
console.log('picUrl: ', picUrl);
if (picUrl) {
this.loadHotZonePic(pic, picUrl, saveData.imgScale);
}
}
pic.x = item.x;
pic.y = item.y;
this.renderArr.push(pic);
}
setItemDrag(item, saveData) {
console.log('in setItemDrag ', saveData);
const dragItem = new DragItem(this.ctx);
dragItem.init();
dragItem.item = item;
item['drag'] = dragItem;
dragItem.visible = false;
dragItem.x = item.x;
dragItem.y = item.y;
this.renderArr.push(dragItem);
if (saveData) {
if (saveData.dragDot) {
dragItem.x = saveData.dragDot.x / saveData.mapScale * this.mapScale;
dragItem.y = saveData.dragDot.y / saveData.mapScale * this.mapScale;
}
}
// console.log('item.itemType: ', item.itemType);
// let w = item.width;
// let h = item.height;
// if (saveData) {
// switch (saveData.itemType) {
// case 'rect':
// w = saveData.rect.width;
// h = saveData.rect.height;
// break;
// case 'pic':
// w = saveData.imgSizeW * saveData.imgScale;
// h = saveData.imgSizeH * saveData.imgScale;;
// break;
// case 'text':
// w = saveData.rect.width;
// h = saveData.rect.height;
// break;
// }
// }
// dragItem.setSize(w, h);
}
setItemAnima(item, saveData) {
console.log('in setItemAnima ', saveData);
// const pic = new EditorItem(this.ctx);
// pic.visible = false;
// item['pic'] = pic;
// if (saveData) {
// let picUrl = saveData.pic_url;
// const actionData = saveData['actionData_' + item.gIdx];
// if (actionData && actionData.type == 'pic') {
// picUrl = actionData.pic_url;
// }
// console.log('saveData: ', saveData);
// console.log('picUrl: ', picUrl);
// if (picUrl) {
// this.loadHotZonePic(pic, picUrl, saveData.imgScale);
// }
// }
// pic.x = item.x;
// pic.y = item.y;
// this.renderArr.push(pic);
}
setItemLabel(item, saveData) {
const textLabel = new HotZoneLabel(this.ctx);
textLabel.fontSize = this.hotZoneFontObj.size;
textLabel.fontName = this.hotZoneFontObj.name;
textLabel.fontColor = this.hotZoneFontObj.color;
if (this.hotZoneFontObj) {
textLabel.fontSize = this.hotZoneFontObj.size;
textLabel.fontName = this.hotZoneFontObj.name;
textLabel.fontColor = this.hotZoneFontObj.color;
}
textLabel.textAlign = 'center';
// textLabel.setOutline();
// console.log('saveData:', saveData);
item['textLabel'] = textLabel;
textLabel.setScaleXY(this.mapScale);
if (saveData && saveData.text) {
textLabel.text = saveData.text;
if (saveData) {
if (saveData.text && this.hotZoneFontObj) {
textLabel.text = saveData.text
}
this.setActionFont(textLabel, saveData['actionData_' + item.gIdx]);
textLabel.refreshSize();
}
textLabel.x = item.x;
textLabel.y = item.y;
this.renderArr.push(textLabel);
}
return item;
setActionFont(textLabel, actionData) {
if (actionData && actionData.type == 'text') {
textLabel.text = actionData.text;
for (let i=0; i<actionData.changeOption.length; i++) {
const op = actionData.changeOption[i];
textLabel[op[0]] = op[1];
}
}
}
getDefaultItemType() {
if (this.customTypeGroupArr) {
const group = this.customTypeGroupArr[0];
if (group.rect) {
return 'rect';
}
if (group.pic) {
return 'pic';
}
if (group.text) {
return 'text';
}
} else {
return this.defaultItemType;
}
}
getPicItem(img, saveData = null) {
......@@ -327,9 +578,11 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
item.y = saveRect.y + saveRect.height / 2;
} else {
item.showLineDash();
// item.showLineDash();
}
item.showLineDash();
console.log('aaa');
});
return item;
}
......@@ -337,6 +590,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
onAudioUploadSuccessByImg(e, img) {
img.audio_url = e.url;
this.refresh();
}
deleteItem(e, i) {
......@@ -345,15 +599,111 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.hotZoneArr.splice(i, 1);
this.refreshHotZoneId();
this.refresh();
}
// radioChange(e, item) {
// item.itemType = e;
radioChange(e, item) {
item.itemType = e;
// this.refreshItem(item);
// this.refresh();
// // console.log(' in radioChange e: ', e);
// }
this.refreshItem(item);
customRadioChange(e, item) {
console.log('in customRadioChange', e);
item.gIdx = -1;
setTimeout(() => {
item.gIdx = e;
this.refreshCustomItem(item);
this.refresh();
}, 1);
// const curGroup = this.customTypeGroupArr[e];
// console.log(' in radioChange e: ', e);
}
refreshCustomItem(item) {
this.hideHotZoneItem(item);
const group = this.customTypeGroupArr[item.gIdx];
if (!group) {
return;
}
if (group.text) {
this.showItemLabel(item);
}
if (group.rect) {
this.showItemRect(item, !group.isFixed);
}
if (group.pic && !group.anima) {
this.showItemPic(item);
}
if (group.action) {
if (group.action.type == 'pic') {
this.showItemPic(item);
}
if (group.action.type == 'text') {
this.showItemLabel(item);
}
if (group.action.type == 'anima') {
this.showItemRect(item);
}
}
item.drag.visible = group.drag;
item.setAnimaStyle(group.animaSmall)
}
showItemDrag(item) {
item.drag.visible = true;
// item.dragBody.visible = true;
// item.itemType = 'pic';
// this.showArrowTop(item)
}
showItemPic(item) {
item.pic.visible = true;
item.itemType = 'pic';
this.showArrowTop(item, true)
}
showItemLabel(item) {
item.textLabel.visible = true;
item.itemType = 'text';
this.showArrowTop(item)
}
showItemRect(item, isShowArrowTop = true) {
item.visible = true;
item.itemType = 'rect';
this.showArrowTop(item, isShowArrowTop)
}
showArrowTop(item, isShowArrowTop = false) {
if (isShowArrowTop) {
item.arrowTop.visible = true;
item.arrowRight.visible = true;
} else {
item.arrowTop.visible = false;
item.arrowRight.visible = false;
}
}
hideHotZoneItem(item) {
item.visible = false;
item.pic.visible = false;
item.textLabel.visible = false;
}
refreshItem(item) {
......@@ -368,33 +718,30 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.setTextState(item);
break;
default:
this.setNoneState(item);
}
}
init() {
console.log('init');
this.initData();
this.initCtx();
this.initItem();
}
initItem() {
this.changeDetectorRef.markForCheck();
this.changeDetectorRef.detectChanges();
if (!this.bgItem) {
this.bgItem = {};
} else {
this.refreshBackground(() => {
// if (!this.imgItemArr) {
// this.imgItemArr = [];
// } else {
// this.initImgArr();
// }
// console.log('aaaaa');
if (!this.hotZoneItemArr) {
this.hotZoneItemArr = [];
} else {
......@@ -404,6 +751,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
});
}
this.refresh();
}
initHotZoneArr() {
......@@ -427,6 +775,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.hotZoneArr = [];
const arr = this.hotZoneItemArr.concat();
console.log('this.hotZoneItemArr: ', this.hotZoneItemArr);
for (let i = 0; i < arr.length; i++) {
const data = JSON.parse(JSON.stringify(arr[i]));
......@@ -449,9 +798,15 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
item.pic_url = data.pic_url;
item.text = data.text;
item.itemType = data.itemType;
this.refreshItem(item);
console.log('item: ', item);
if (this.customTypeGroupArr) {
this.refreshCustomItem(item);
} else {
this.refreshItem(item);
}
console.log('1 item: ', item);
this.hotZoneArr.push(item);
}
......@@ -463,48 +818,6 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
}
initImgArr() {
console.log('this.imgItemArr: ', this.imgItemArr);
let curBgRect;
if (this.bg) {
curBgRect = this.bg.getBoundingBox();
} else {
curBgRect = {x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight};
}
let oldBgRect = this.bgItem.rect;
if (!oldBgRect) {
oldBgRect = curBgRect;
}
const rate = curBgRect.width / oldBgRect.width;
console.log('rate: ', rate);
this.imgArr = [];
const arr = this.imgItemArr.concat();
for (let i = 0; i < arr.length; i++) {
const data = JSON.parse(JSON.stringify(arr[i]));
const img = {pic_url: data.pic_url};
data.rect.x *= rate;
data.rect.y *= rate;
data.rect.width *= rate;
data.rect.height *= rate;
data.rect.x += curBgRect.x;
data.rect.y += curBgRect.y;
img['picItem'] = this.getPicItem(img, data);
img['audio_url'] = arr[i].audio_url;
this.imgArr.push(img);
}
this.refreshImageId();
}
initData() {
this.canvasWidth = this.wrap.nativeElement.clientWidth;
......@@ -528,9 +841,28 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
this.oldPos = {x: this.mx, y: this.my};
for (let i = 0; i < this.hotZoneArr.length; i++) {
// 先检测拖拽点
for (let i = this.hotZoneArr.length - 1; i >= 0; i--) {
const item = this.hotZoneArr[i];
if (item && item.drag && item.drag.visible) {
if (this.checkClickTarget(item.drag)) {
this.clickedDragPoint(item.drag);
return;
}
}
}
for (let i = this.hotZoneArr.length - 1; i >= 0; i--) {
const item = this.hotZoneArr[i];
console.log('mapDown item: ', item);
let callback;
let target;
switch (item.itemType) {
......@@ -548,7 +880,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
break;
}
if (this.checkClickTarget(target)) {
if (target && this.checkClickTarget(target)) {
callback(target);
return;
}
......@@ -578,15 +910,18 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
const addY = this.my - this.oldPos.y;
this.curItem.x += addX;
this.curItem.y += addY;
this.curItem.posX = this.curItem.x;
this.curItem.posY = this.curItem.y;
}
this.oldPos = {x: this.mx, y: this.my};
this.saveDisabled = true;
// this.saveDisabled = false;
}
mapUp(event) {
mapUp(event=null) {
this.curItem = null;
this.changeSizeFlag = false;
this.changeTopSizeFlag = false;
......@@ -685,10 +1020,13 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
changeCurItem(item) {
console.log(' in changeCurItem', item)
this.hideAllLineDash();
this.curItem = item;
this.curItem.showLineDash();
}
hideAllLineDash() {
......@@ -711,9 +1049,7 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
// 清除画布内容
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
for (let i = 0; i < this.renderArr.length; i++) {
this.renderArr[i].update(this);
}
// for (let i = 0; i < this.imgArr.length; i++) {
// const picItem = this.imgArr[i].picItem;
......@@ -722,8 +1058,16 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
// }
// }
for (let i = 0; i < this.renderArr.length; i++) {
this.renderArr[i].update(this);
}
this.updateArr(this.hotZoneArr);
this.updatePos()
this.updatePos();
TWEEN.update();
......@@ -833,7 +1177,9 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
checkClickTarget(target) {
if (!target || !target.visible) {
return;
}
const rect = target.getBoundingBox();
if (this.checkPointInRect(this.mx, this.my, rect)) {
return true;
......@@ -852,9 +1198,21 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
saveClick() {
const sendData = this.getSendData();
this.save.emit(sendData);
}
getSendData() {
const bgItem = this.bgItem;
if (this.bg) {
bgItem['rect'] = this.bg.getBoundingBox();
const rect = this.bg.getBoundingBox();
bgItem['rect'] = rect;
rect.x = Math.round(rect.x * 100) / 100;
rect.y = Math.round(rect.y * 100) / 100;
rect.width = Math.round(rect.width * 100) / 100;
rect.height = Math.round(rect.height * 100) / 100;
} else {
bgItem['rect'] = {
x: 0,
......@@ -870,19 +1228,52 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
for (let i = 0; i < hotZoneArr.length; i++) {
const hotZoneItem = {
id: hotZoneArr[i].id,
index: hotZoneArr[i].index,
pic_url: hotZoneArr[i].pic_url,
text: hotZoneArr[i].text,
audio_url: hotZoneArr[i].audio_url,
itemType: hotZoneArr[i].itemType,
fontSize: this.hotZoneFontObj.size,
fontName: this.hotZoneFontObj.name,
fontColor: this.hotZoneFontObj.color,
fontScale: hotZoneArr[i].textLabel ? hotZoneArr[i].textLabel.scaleX : 1,
imgScale: hotZoneArr[i].pic ? hotZoneArr[i].pic.scaleX : 1,
mapScale: this.mapScale
imgSizeW: hotZoneArr[i].pic ? hotZoneArr[i].pic.width : 0,
imgSizeH: hotZoneArr[i].pic ? hotZoneArr[i].pic.height : 0,
mapScale: this.mapScale,
skeJsonData: hotZoneArr[i].skeJsonData,
texJsonData: hotZoneArr[i].texJsonData,
texPngData: hotZoneArr[i].texPngData,
dragDot: hotZoneArr[i].drag.getPosition(),
gIdx: hotZoneArr[i].gIdx,
};
hotZoneItem['rect'] = hotZoneArr[i].getBoundingBox();
this.savePropertyArr.forEach((key) => {
if (hotZoneArr[i][key]) {
hotZoneItem[key] = hotZoneArr[i][key];
}
})
hotZoneItem['actionData_' + hotZoneItem.gIdx] = hotZoneArr[i]['actionData_' + hotZoneArr[i].gIdx]
if (this.hotZoneFontObj) {
hotZoneItem['fontSize'] = this.hotZoneFontObj.size;
hotZoneItem['fontName'] = this.hotZoneFontObj.name;
hotZoneItem['ontColor'] = this.hotZoneFontObj.color;
}
if (hotZoneArr[i].itemType == 'pic') {
hotZoneItem['rect'] = hotZoneArr[i].pic.getBoundingBox();
} else if (hotZoneArr[i].itemType == 'text') {
hotZoneArr[i].textLabel.refreshSize();
hotZoneItem['rect'] = hotZoneArr[i].textLabel.getLabelRect();
// hotZoneItem['rect'].width = hotZoneItem['rect'].width / hotZoneArr[i].textLabel.scaleX;
// hotZoneItem['rect'].height = hotZoneArr[i].textLabel.height * hotZoneArr[i].textLabel.scaleY;
} else {
hotZoneItem['rect'] = hotZoneArr[i].getBoundingBox();
}
// hotZoneItem['rect'] = hotZoneArr[i].getBoundingBox();
hotZoneItem['rect'].x = Math.round((hotZoneItem['rect'].x - bgItem['rect'].x) * 100) / 100;
hotZoneItem['rect'].y = Math.round((hotZoneItem['rect'].y - bgItem['rect'].y) * 100) / 100;
hotZoneItem['rect'].width = Math.round((hotZoneItem['rect'].width) * 100) / 100;
......@@ -894,7 +1285,360 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
console.log('hotZoneItemArr: ', hotZoneItemArr);
this.save.emit({bgItem, hotZoneItemArr});
return {bgItem, hotZoneItemArr};
}
saveText(item) {
if (item.itemType == 'text') {
item.textLabel.text = item.text;
}
}
saveItemPos(item) {
console.log('item.posX: ', item.posX)
console.log('item.posY: ', item.posY)
item.x = Number(item.posX || 0)
item.y = Number(item.posY || 0)
// this.changeCurItem(item);
// this.curItem.x = item.posX || 0;
// this.curItem.y = item.posY || 0;
// this.mapUp();
}
onSaveCustomAction(e, item) {
const data = e;
item['actionData_' + item.gIdx] = data;
if (data.type == 'pic') {
let picUrl = data.pic_url;
if (picUrl) {
this.loadHotZonePic(item.pic, picUrl);
}
}
if (data.type == 'text') {
this.setActionFont(item.textLabel, data);
item.textLabel.refreshSize();
}
// if (data.type == 'anima') {
// this.setActionAnima(item.anima, data);
// }
// this.loadHotZonePic(item.pic, e.url);
this.refresh()
}
setActionAnima() {
}
setAnimaBtnClick(index) {
console.log('aaaa')
this.isAnimaSmall = false;
this.setCurDragonBone(index);
// this.curDragonBoneIndex = index;
// this.curDragonBoneGIdx = Number(this.hotZoneArr[index].gIdx);
// const {skeJsonData, texJsonData, texPngData} = this.hotZoneArr[index];
// this.skeJsonData = skeJsonData || {};
// this.texJsonData = texJsonData || {};
// this.texPngData = texPngData || {};
// this.animaPanelVisible = true;
// this.refresh();
}
setAnimaSmallBtnClick(index) {
console.log('bbb')
this.isAnimaSmall = true;
this.setCurDragonBone(index);
}
setCurDragonBone(index) {
this.curDragonBoneIndex = index;
this.curDragonBoneGIdx = Number(this.hotZoneArr[index].gIdx);
const {skeJsonData, texJsonData, texPngData} = this.hotZoneArr[index];
this.skeJsonData = skeJsonData || {};
this.texJsonData = texJsonData || {};
this.texPngData = texPngData || {};
this.animaPanelVisible = true;
this.refresh();
}
setItemSizeByAnima(jsonData, item) {
console.log('json: ', jsonData);
const request = new XMLHttpRequest();
//通过url获取文件,第二个选项是文件所在的具体地址
request.open('GET', jsonData.url, true);
request.send(null);
request.onreadystatechange = ()=> {
if (request.readyState === 4 && request.status === 200) {
var type = request.getResponseHeader('Content-Type');
if (type.indexOf("text") !== 1) {
//返回一个文件内容的对象
const data = JSON.parse(request.responseText);
console.log('request.responseText;', data)
const animaSize = data.armature[0].canvas;
item.width = animaSize.width;
item.height = animaSize.height;
// return request.responseText;
}
}
}
}
animaPanelCancel() {
this.animaPanelVisible = false;
this.refresh();
}
animaPanelOk() {
this.setItemDragonBoneData(this.hotZoneArr[this.curDragonBoneIndex]);
console.log('this.hotZoneArr: ', this.hotZoneArr);
this.animaPanelVisible = false;
if (this.isAnimaSmall) {
this.setItemSizeByAnima(this.skeJsonData, this.hotZoneArr[this.curDragonBoneIndex]);
}
this.refresh();
}
setItemDragonBoneData(item) {
item['skeJsonData'] = this.skeJsonData;
item['texJsonData'] = this.texJsonData;
item['texPngData'] = this.texPngData;
}
skeJsonHandleChange(e) {
console.log('e: ', e);
switch (e.type) {
case 'start':
this.isSkeJsonLoading = true;
break;
case 'success':
this.skeJsonData['url'] = e.file.response.url;
this.skeJsonData['name'] = e.file.name;
this.nzMessageService.success('上传成功');
this.isSkeJsonLoading = false;
break;
case 'progress':
break;
}
}
texJsonHandleChange(e) {
console.log('e: ', e);
switch (e.type) {
case 'start':
this.isTexJsonLoading = true;
break;
case 'success':
this.texJsonData['url'] = e.file.response.url;
this.texJsonData['name'] = e.file.name;
this.nzMessageService.success('上传成功');
this.isTexJsonLoading = false;
break;
case 'progress':
break;
}
}
texPngHandleChange(e) {
console.log('e: ', e);
switch (e.type) {
case 'start':
this.isTexPngLoading = true;
break;
case 'success':
this.texPngData['url'] = e.file.response.url;
this.texPngData['name'] = e.file.name;
this.nzMessageService.success('上传成功');
this.isTexPngLoading = false;
break;
case 'progress':
break;
}
}
copyItem(it) {
const {hotZoneItemArr} = this.getSendData();
let itemData;
hotZoneItemArr.forEach((data) => {
if (data.id == it.id) {
itemData = data;
}
})
let curBgRect;
if (this.bg) {
curBgRect = this.bg.getBoundingBox();
} else {
curBgRect = {x: 0, y: 0, width: this.canvasWidth, height: this.canvasHeight};
}
let oldBgRect = this.bgItem.rect;
if (!oldBgRect) {
oldBgRect = curBgRect;
}
const rate = curBgRect.width / oldBgRect.width;
console.log('rate: ', rate);
const data = itemData
data.rect.x *= rate;
data.rect.y *= rate;
data.rect.width *= rate;
data.rect.height *= rate;
data.rect.x += curBgRect.x;
data.rect.y += curBgRect.y;
const item = this.getHotZoneItem(data);
item.audio_url = data.audio_url;
item.pic_url = data.pic_url;
item.text = data.text;
item.itemType = data.itemType;
this.hotZoneArr.push(item);
if (this.customTypeGroupArr) {
this.refreshCustomItem(item);
} else {
this.refreshItem(item);
}
this.refreshHotZoneId();
item['id'] = this.createItemId();
}
createItemId() {
return new Date().getTime().toString();
}
copyHotZoneData() {
const {bgItem, hotZoneItemArr} = this.getSendData();
// const hotZoneItemArrNew = [];
// const tmpArr = JSON.parse(JSON.stringify(hotZoneItemArr));
// tmpArr.forEach((item) => {
// if (item.gIdx === '0') {
// hotZoneItemArr.push(item);
// }
// })
const jsonData = {
bgItem,
hotZoneItemArr,
isHasRect: this.isHasRect,
isHasPic: this.isHasPic,
isHasText: this.isHasText,
isHasAudio: this.isHasAudio,
isHasAnima: this.isHasAnima,
hotZoneFontObj: this.hotZoneFontObj,
defaultItemType: this.defaultItemType,
hotZoneImgSize: this.hotZoneImgSize,
};
const oInput = document.createElement('input');
oInput.value = JSON.stringify(jsonData);
document.body.appendChild(oInput);
oInput.select(); // 选择对象
document.execCommand('Copy'); // 执行浏览器复制命令
document.body.removeChild(oInput);
this.nzMessageService.success('复制成功');
// alert('复制成功');
}
importData() {
if (!this.pasteData) {
return;
}
try {
const data = JSON.parse(this.pasteData);
console.log('data:', data);
const {
bgItem,
hotZoneItemArr,
isHasRect,
isHasPic,
isHasText,
isHasAudio,
isHasAnima,
hotZoneFontObj,
defaultItemType,
hotZoneImgSize,
} = data;
this.hotZoneItemArr = hotZoneItemArr;
this.isHasRect = isHasRect;
this.isHasPic = isHasPic;
this.isHasText = isHasText;
this.isHasAudio = isHasAudio;
this.isHasAnima = isHasAnima;
this.hotZoneFontObj = hotZoneFontObj;
this.defaultItemType = defaultItemType;
this.hotZoneImgSize = hotZoneImgSize;
this.bgItem = bgItem;
this.pasteData = '';
} catch (e) {
console.log('err: ', e);
this.nzMessageService.error('导入失败');
}
}
private updatePos() {
......@@ -917,12 +1661,15 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
break;
}
item.x = x;
item.y = y;
item.pic.x = x;
item.pic.y = y;
item.textLabel.x = x;
item.textLabel.y = y;
if (x != undefined && y != undefined) {
item.x = x;
item.y = y;
item.pic.x = x;
item.pic.y = y;
item.textLabel.x = x;
item.textLabel.y = y;
}
});
}
......@@ -944,6 +1691,12 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
item.textLabel.visible = true;
}
private setNoneState(item: any) {
item.visible = false;
item.pic.visible = false;
item.textLabel.visible = false;
}
private clickedHotZoneRect(item: any) {
if (this.checkClickTarget(item)) {
......@@ -962,6 +1715,17 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
private clickedHotZonePic(item: any) {
if (this.checkClickTarget(item)) {
if (item.lineDashFlag && this.checkClickTarget(item.arrow)) {
this.changeItemSize(item);
} else if (item.lineDashFlag && this.checkClickTarget(item.arrowTop)) {
this.changeItemTopSize(item);
} else if (item.lineDashFlag && this.checkClickTarget(item.arrowRight)) {
this.changeItemRightSize(item);
} else {
this.changeCurItem(item);
}
this.curItem = item;
}
}
......@@ -972,15 +1736,42 @@ export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges {
}
}
saveText(item) {
item.textLabel.text = item.text;
clickedDragPoint(item) {
this.curItem = item;
}
private loadHotZonePic(pic: HotZoneImg, url) {
const baseLen = this.hotZoneImgSize * this.mapScale;
private loadHotZonePic(pic: HotZoneImg, url, scale = null) {
let baseLen;
if (this.hotZoneImgSize) {
baseLen = this.hotZoneImgSize * this.mapScale;
}
pic.load(url).then(() => {
const s = getMinScale(pic, baseLen);
pic.setScaleXY(s);
if (!scale) {
if (baseLen) {
scale = getMinScale(pic, baseLen);
} else {
scale = this.bg.scaleX;
}
}
pic.setScaleXY(scale);
});
}
closeAfterPanel() {
this.refresh();
}
/**
* 刷新 渲染页面
*/
refresh() {
setTimeout(() => {
this.appRef.tick();
}, 1);
}
}
<div class="position-relative">
<div class="position-relative" (drop)="handle_drop($event)" (dragover)="handle_dragover($event)">
<button nz-button (click)="setAnimaBtnClick()" style=" border-radius: 0.5rem; border: 1px solid #ddd;">
<button nz-button (click)="setAnimaBtnClick()" style=" border-radius: 0.5rem; border: 1px solid #ddd;" (dragover)="handle_dragover($event)">
<i nz-icon nzType="tool" nzTheme="outline"></i>
{{btnName}}
</button>
......
......@@ -178,4 +178,43 @@ export class UploadDragonBoneComponent implements OnDestroy, OnChanges {
ngOnDestroy() {
}
linkInputed (ske, tex, png) {
this.skeJsonData["url"] = ske.url;
this.skeJsonData["name"] = ske.name;
this.texJsonData["url"] = tex.url;
this.texJsonData["name"] = tex.name;
this.texPngData["url"] = png.url;
this.texPngData["name"] = png.name;
this.animaPanelOk();
}
handle_dragover(e) {
e.preventDefault();
}
handle_drop(e) {
e.preventDefault();
const dt = e.dataTransfer.getData("text/plain");
console.log("handle_drop===", dt);
if (!dt) {
return;
}
try {
const {ske, tex, png} = JSON.parse(dt);
if (!ske || !tex || !png ||
ske.url.indexOf("teach")<0 || ske.url.indexOf("cdn")<0 || ske.url.indexOf(".json")<0 ||
tex.url.indexOf("teach")<0 || tex.url.indexOf("cdn")<0 || tex.url.indexOf(".json")<0 ||
png.url.indexOf("teach")<0 || png.url.indexOf("cdn")<0 || png.url.indexOf(".png")<0 ||
!ske.name || !tex.name || !png.name
) {
console.warn("handle_drop拖拽在线骨骼动画传递参数不合法,应该是{ske:{url:'', name:''},tex:{url:'', name:''},png:{url:'', name:''}}");
return;
}
this.linkInputed(ske, tex, png);
} catch (error) {
console.warn("handle_drop拖拽在线骨骼动画传递参数不合法,应该是{ske:{url:'', name:''},tex:{url:'', name:''},png:{url:'', name:''}}");
}
}
}
<div class="position-relative">
<div class="position-relative" (drop)="handle_drop($event)" (dragover)="handle_dragover($event)">
<nz-upload class="p-image-uploader" [nzDisabled]="disableUpload"
[nzShowUploadList]="false"
nzAccept = "image/*"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="handleChange($event)">
(nzChange)="handleChange($event)"
>
<!--[nzBeforeUpload]="customUpload">-->
<div class="p-box d-flex align-items-center">
<div class="p-upload-icon" *ngIf="!picUrl && !uploading">
......
......@@ -155,4 +155,39 @@ export class UploadImageWithPreviewComponent implements OnDestroy, OnChanges {
ngOnDestroy() {
}
linkInputed (url) {
const file = {
response: {url}
};
const img = new Image();
img.addEventListener('load', () => {
const height = img.naturalHeight;
const width = img.naturalWidth;
file['height'] = height;
file['width'] = width;
img.remove();
this.imageUploaded.emit(file.response);
});
img.src = url;
this.picUrl = url;
}
handle_dragover(e) {
e.preventDefault();
}
handle_drop(e) {
const dt = e.dataTransfer.getData("text/plain");
console.log("handle_drop===", dt);
if (!dt || dt.indexOf("teach")<0 || dt.indexOf("cdn")<0) {
return;
}
const white = [".jpg", ".jpeg", ".png", ".bmp", ".JPG", ".JPEG", ".PNG", ".BMP"];
if (!white.includes(dt.substr(dt.lastIndexOf(".")))) {
return;
}
this.linkInputed(dt);
}
}
<div class="p-video-box">
<div class="up-video" style="display: flex;">
<!--<nz-upload class="" [nzDisabled]="!showUploadBtn"-->
<!--[nzShowUploadList]="false"-->
<!--[nzBeforeUpload]="beforeUpload"-->
<!--nzAccept = ".mp4"-->
<!--style="margin-right: 1rem">-->
<div class="p-video-box" (drop)="handle_drop($event)" (dragover)="handle_dragover($event)">
<div class="up-video" style="display: flex;">
<!--<nz-upload class="" [nzDisabled]="!showUploadBtn"-->
<!--[nzShowUploadList]="false"-->
<!--[nzBeforeUpload]="beforeUpload"-->
<!--nzAccept = ".mp4"-->
<!--style="margin-right: 1rem">-->
<nz-upload class="p-image-uploader" [nzDisabled]="uploading"
[nzShowUploadList]="false"
nzAccept = ".mp4"
[nzAction]="uploadUrl"
[nzData]="uploadData"
(nzChange)="handleChange($event)"
style="margin-right: 1rem">
<nz-upload class="p-image-uploader" [nzDisabled]="uploading" [nzShowUploadList]="false" nzAccept=".mp4"
[nzAction]="uploadUrl" [nzData]="uploadData" (nzChange)="handleChange($event)" style="margin-right: 1rem">
<button type="button" nz-button nzType="default" *ngIf="showUploadBtn" [disabled]="uploading"
[nzLoading]="uploading" >
[nzLoading]="uploading">
<i nz-icon nzType="plus" nzTheme="outline"></i>
<span>{{ uploading ? 'Uploading' : 'Select Video' }}</span>
<!--<span>Select Video</span>-->
......@@ -25,14 +20,14 @@
</nz-upload>
<!--<button nz-button nzType="primary" *ngIf="showUploadBtn"-->
<!--style="margin-right: 1rem"-->
<!--type="button"-->
<!--[nzLoading]="uploading"-->
<!--(click)="handleUpload()"-->
<!--[disabled]="!videoFile || uploading">-->
<!--<i nz-icon type="upload" theme="outline"></i>-->
<!--<span>{{ uploading ? 'Uploading' : 'Start Upload' }}</span>-->
<!--<button nz-button nzType="primary" *ngIf="showUploadBtn"-->
<!--style="margin-right: 1rem"-->
<!--type="button"-->
<!--[nzLoading]="uploading"-->
<!--(click)="handleUpload()"-->
<!--[disabled]="!videoFile || uploading">-->
<!--<i nz-icon type="upload" theme="outline"></i>-->
<!--<span>{{ uploading ? 'Uploading' : 'Start Upload' }}</span>-->
<!--</button>-->
<!--
......@@ -54,41 +49,37 @@
-->
</div>
<div class="p-box d-flex align-items-center p-video-uploader">
<div class="p-upload-icon" *ngIf="!showUploadBtn && !videoUrl && !uploading">
<i nz-icon nzType="upload" nzTheme="outline"></i>
<div class="m-3"></div>
<span>Click here to upload video</span>
<div class="mt-5 p-progress-bar" *ngIf="uploading">
<div class="p-progress-bg" [style.width]="progress*0.2+'rem'"></div>
<div class="p-progress-value">{{progress}}%</div>
</div>
</div>
<div class="p-upload-progress-bg dddd " *ngIf="uploading"
[ngClass]="{'smart-bar': showUploadBtn}" >
<div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text">
<fa-icon icon="cloud-upload-alt"></fa-icon>
Uploading...
<div class="p-box d-flex align-items-center p-video-uploader">
<div class="p-upload-icon" *ngIf="!showUploadBtn && !videoUrl && !uploading">
<i nz-icon nzType="upload" nzTheme="outline"></i>
<div class="m-3"></div>
<span>Click here to upload video</span>
<div class="mt-5 p-progress-bar" *ngIf="uploading">
<div class="p-progress-bg" [style.width]="progress*0.2+'rem'"></div>
<div class="p-progress-value">{{progress}}%</div>
</div>
</div>
</div>
<div class="p-upload-check-bg" *ngIf="checking">
<div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text">
<fa-icon icon="cloud-upload-alt"></fa-icon>
<i nz-icon nzType="loading" nzTheme="outline"></i>Checking...
<div class="p-upload-progress-bg dddd " *ngIf="uploading" [ngClass]="{'smart-bar': showUploadBtn}">
<div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text">
<fa-icon icon="cloud-upload-alt"></fa-icon>
Uploading...
</div>
</div>
<div class="p-upload-check-bg" *ngIf="checking">
<div class="i-bg" [style.width]="progress+'%'"></div>
<div class="i-text">
<fa-icon icon="cloud-upload-alt"></fa-icon>
<i nz-icon nzType="loading" nzTheme="outline"></i>Checking...
</div>
</div>
<div class="p-preview" *ngIf="!uploading && videoUrl ">
<!--<video crossorigin="anonymous" [src]="videoUrl" controls #videoNode></video>-->
<video [src]="safeVideoUrl(videoUrl)" controls #videoNode></video>
</div>
</div>
<div class="p-preview" *ngIf="!uploading && videoUrl " >
<!--<video crossorigin="anonymous" [src]="videoUrl" controls #videoNode></video>-->
<video [src]="safeVideoUrl(videoUrl)" controls #videoNode></video>
<div [style.display]="!checkVideoExists?'none':''">
<span><i nz-icon nzType="loading" nzTheme="outline"></i> checking file to upload</span>
</div>
</div>
<div [style.display]="!checkVideoExists?'none':''">
<span><i nz-icon nzType="loading" nzTheme="outline"></i> checking file to upload</span>
</div>
</div>
</div>
\ No newline at end of file
......@@ -225,5 +225,55 @@ export class UploadVideoComponent implements OnChanges, OnDestroy {
// console.log(Math.floor(p * 100));
this.progress = Math.floor(p * 100);
}
linkInputed (url, name) {
const file = {
response: {url}
};
const vid = document.createElement('video');
vid.addEventListener('loadedmetadata', () => {
const height = vid.videoHeight;
const width = vid.videoWidth;
let duration = vid.duration;
if (duration) {
duration = duration * 1000;
}
file["height"] = height;
file["width"] = width;
file["duration"] = duration;
vid.preload = 'none';
vid.src = '';
vid.remove();
this.videoUploaded.emit(file.response);
});
vid.src = file.response.url;
this.videoUrl = url;
}
handle_dragover(e) {
e.preventDefault();
}
handle_drop(e) {
const dt = e.dataTransfer.getData("text/plain");
console.log("handle_drop===", dt);
if (!dt) {
return;
}
try {
const {url, name} = JSON.parse(dt);
if (url.indexOf("teach")<0 || url.indexOf("cdn")<0) {
return;
}
const white = [".mp4"];
if (!white.includes(url.substr(url.lastIndexOf(".")))) {
return;
}
this.linkInputed(url, name);
} catch (error) {
console.warn("handle_drop拖拽在线视频传递参数不合法,应该是{url:'', name:''}");
}
}
}
<div class="model-content">
<div style="padding: 10px;">
<div class="border" style="width: 1000px;">
<textarea style="width: 955px; height: 300px;" (blur)="load()" #itemTextarea>{{itemStr}}</textarea>
<button (click)="copyData();">Copy</button>
</div>
<div class="border" style="width: 1000px;">
<span style="font-size: 20px;">标题: </span>
......@@ -19,6 +15,8 @@
></app-audio-recorder>
</div>
<div class="border" style="width: 1000px;">
<div *ngFor="let question of item.questions; let i = index">
<div class="border" style="width: 950px;">
......
......@@ -40,4 +40,19 @@ export class FormComponent extends ComponentBase implements OnInit, OnChanges, O
this.item.audioFileName=name;
this.save();
}
handle_dragover(e) {
e.preventDefault();
}
handle_drop(e) {
e.preventDefault();
const dt = e.dataTransfer.getData("text/plain");
console.log("handle_drop===", dt);
// 网络文件 dt 的数据遵循如下格式
// 图片 "http://staging-teach.cdn.ireadabc.com/f38f9928-c3bd-47f8-9ed1-43c0e03d2f30.png";
// 音频(JSON字符串) {url: "http://staging-teach.cdn.ireadabc.com/1c8694612563f4e2da707f1f6a37d066_l.mp3", name: "test.mp3"};
// 视频(JSON字符串) {url: "http://staging-teach.cdn.ireadabc.com/c37a3945121274a1f7d95717327539ec_l.mp4", name: "视频.mp4"};
// 骨骼动画(JSON字符串) {"ske":{"url":"http://staging-teach.cdn.ireadabc.com/3d4a36b83aada60709771fbe15e2b6db.json","name":"飞鸟_ske.json"},"tex":{"url":"http://staging-teach.cdn.ireadabc.com/08a676a5f456634f9c6c90e9efd3c2ea.json","name":"飞鸟_tex.json"},"png":{"url":"http://staging-teach.cdn.ireadabc.com/874393ecf5e0cd42a09f5b34d48854d2.png","name":"飞鸟_tex.png"}};
}
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<img id="drag" style="width: 100px; height: 100px; background-color: gold;" draggable="true" ele-data="http://staging-teach.cdn.ireadabc.com/c37a3945121274a1f7d95717327539ec_l.mp4" src="http://staging-teach.cdn.ireadabc.com/f38f9928-c3bd-47f8-9ed1-43c0e03d2f30.png"></img>
<div id="target" ondrop="handle_drop(event)" ondragover="handle_dragover(event)" style="position: absolute; top: 10px; right: 10px; width: 80px; height: 80px; background: #00ffff;">
</div>
<script>
var dragEl = document.getElementById("drag");
dragEl.ondragstart = function(e) {
// 图片
// const dt = "http://staging-teach.cdn.ireadabc.com/f38f9928-c3bd-47f8-9ed1-43c0e03d2f30.png";
// e.dataTransfer.setData("text/plain", dt);
// 音频
const dt = {url: "http://staging-teach.cdn.ireadabc.com/1c8694612563f4e2da707f1f6a37d066_l.mp3", name: "test.mp3"};
e.dataTransfer.setData("text/plain", JSON.stringify(dt));
// 视频
// const dt = {url: "http://staging-teach.cdn.ireadabc.com/c37a3945121274a1f7d95717327539ec_l.mp4", name: "视频.mp4"};
// e.dataTransfer.setData("text/plain", JSON.stringify(dt));
// 骨骼动画
// const dt = {"ske":{"url":"http://staging-teach.cdn.ireadabc.com/3d4a36b83aada60709771fbe15e2b6db.json","name":"飞鸟_ske.json"},"tex":{"url":"http://staging-teach.cdn.ireadabc.com/08a676a5f456634f9c6c90e9efd3c2ea.json","name":"飞鸟_tex.json"},"png":{"url":"http://staging-teach.cdn.ireadabc.com/874393ecf5e0cd42a09f5b34d48854d2.png","name":"飞鸟_tex.png"}};
// e.dataTransfer.setData("text/plain", JSON.stringify(dt))
}
dragEl.drop = function(e) {
e.dataTransfer.getData("text/plain");
}
var target = document.getElementById('target')
// target.ondragover = handle_dragover
function handle_dragover(e) {
e.preventDefault()
}
function handle_drop(e) {
}
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment