import { ApplicationRef, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, OnChanges, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'; import {Subject} from 'rxjs'; import {debounceTime} from 'rxjs/operators'; 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 {NzMessageService} from 'ng-zorro-antd'; @Component({ selector: 'app-custom-hot-zone', templateUrl: './custom-hot-zone.component.html', styleUrls: ['./custom-hot-zone.component.scss'] }) export class CustomHotZoneComponent implements OnInit, OnDestroy, OnChanges { @ViewChild('canvas', {static: true}) canvas: ElementRef; @ViewChild('wrap', {static: true}) wrap: ElementRef; @Input() hotZoneItemArr = null; @Input() hotZoneArr = null; @Input() isHasRect = true; @Input() isHasPic = true; @Input() isHasText = true; @Input() 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 = 0; @Output() save = new EventEmitter(); saveDisabled = true; canvasWidth = 1280; canvasHeight = 720; canvasBaseW = 1280; // @HostListener('window:resize', ['$event']) canvasBaseH = 720; mapScale = 1; ctx; mx; my; // 点击坐标 // 声音 bgAudio = new Audio(); images = new Map(); animationId: any; // 资源 // rawImages = new Map(res); winResizeEventStream = new Subject(); canvasLeft; canvasTop; renderArr; imgArr = []; oldPos; radioValue; curItem; bg: MySprite; changeSizeFlag = false; changeTopSizeFlag = false; changeRightSizeFlag = false; 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; get bgItem() { return this._bgItem; } @Input() set bgItem(v) { this._bgItem = v; this.init(); } onResize(event) { this.winResizeEventStream.next(); } ngOnInit() { this.initListener(); // this.init(); this.update(); this.refresh(); } ngOnDestroy() { window.cancelAnimationFrame(this.animationId); } ngOnChanges() { } onBackgroundUploadSuccess(e) { console.log('e: ', e); this.bgItem.url = e.url; this.refreshBackground(); } 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(); } refreshBackground(callBack = null) { if (!this.bg) { this.bg = new MySprite(this.ctx); 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) { 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); bg.x = this.canvasWidth / 2; bg.y = this.canvasHeight / 2; bg.removeChildren(); 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(); } this.refresh(); }); // } } addBtnClick(data=null) { // this.imgArr.push({}); // this.hotZoneArr.push({}); const item = this.getHotZoneItem(data); this.hotZoneArr.push(item); if (this.customTypeGroupArr) { this.refreshCustomItem(item); } else { this.refreshItem(item); } this.refreshHotZoneId(); } deleteBtnClick(index) { 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(); } onImgUploadSuccessByImg(e, img) { img.pic_url = e.url; this.refreshImage(img); this.refresh(); } refreshImage(img) { this.hideAllLineDash(); img.picItem = this.getPicItem(img); this.refreshImageId(); } refreshHotZoneId() { for (let i = 0; i < this.hotZoneArr.length; i++) { this.hotZoneArr[i].index = i; if (this.hotZoneArr[i]) { this.hotZoneArr[i].title = 'item-' + (i + 1); } } this.refresh(); } refreshImageId() { for (let i = 0; i < this.imgArr.length; i++) { this.imgArr[i].id = i; if (this.imgArr[i].picItem) { this.imgArr[i].picItem.text = 'Image-' + (i + 1); } } } getHotZoneItem(saveData = null) { const itemW = 200; const itemH = 200; const item = new HotZoneItem(this.ctx); item.setSize(itemW, itemH); item.anchorX = 0.5; item.anchorY = 0.5; item.x = this.canvasWidth / 2; item.y = this.canvasHeight / 2; 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) { const saveRect = saveData.rect; item.scaleX = saveRect.width / item.width; 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); 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) { 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); if (this.hotZoneFontObj) { textLabel.fontSize = this.hotZoneFontObj.size; textLabel.fontName = this.hotZoneFontObj.name; textLabel.fontColor = this.hotZoneFontObj.color; } textLabel.textAlign = 'center'; // textLabel.setOutline(); item['textLabel'] = textLabel; textLabel.setScaleXY(this.mapScale); 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); } 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) { const item = new EditorItem(this.ctx); item.load(img.pic_url).then(img => { let maxW, maxH; if (this.bg) { maxW = this.bg.width * this.bg.scaleX; maxH = this.bg.height * this.bg.scaleY; } else { maxW = this.canvasWidth; maxH = this.canvasHeight; } let scaleX = maxW / 3 / item.width; let scaleY = maxH / 3 / item.height; if (item.height * scaleX < this.canvasHeight) { item.setScaleXY(scaleX); } else { item.setScaleXY(scaleY); } item.x = this.canvasWidth / 2; item.y = this.canvasHeight / 2; if (saveData) { const saveRect = saveData.rect; item.setScaleXY(saveRect.width / item.width); item.x = saveRect.x + saveRect.width / 2; item.y = saveRect.y + saveRect.height / 2; } else { // item.showLineDash(); } item.showLineDash(); console.log('aaa'); }); return item; } onAudioUploadSuccessByImg(e, img) { img.audio_url = e.url; this.refresh(); } deleteItem(e, i) { // this.imgArr.splice(i , 1); // this.refreshImageId(); this.hotZoneArr.splice(i, 1); this.refreshHotZoneId(); this.refresh(); } // radioChange(e, item) { // item.itemType = e; // this.refreshItem(item); // this.refresh(); // // console.log(' in radioChange e: ', e); // } 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]; } 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) { switch (item.itemType) { case 'rect': this.setRectState(item); break; case 'pic': this.setPicState(item); break; case 'text': 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.hotZoneItemArr) { this.hotZoneItemArr = []; } else { this.initHotZoneArr(); } }); } this.refresh(); } initHotZoneArr() { // console.log('this.hotZoneArr: ', this.hotZoneArr); 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.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])); // 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); 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; if (this.customTypeGroupArr) { this.refreshCustomItem(item); } else { this.refreshItem(item); } console.log('1 item: ', item); this.hotZoneArr.push(item); } this.refreshHotZoneId(); // this.refreshImageId(); } initData() { this.canvasWidth = this.wrap.nativeElement.clientWidth; this.canvasHeight = this.wrap.nativeElement.clientHeight; this.mapScale = this.canvasWidth / this.canvasBaseW; this.renderArr = []; this.bg = null; this.imgArr = []; this.hotZoneArr = []; } initCtx() { this.ctx = this.canvas.nativeElement.getContext('2d'); this.canvas.nativeElement.width = this.canvasWidth; this.canvas.nativeElement.height = this.canvasHeight; } mapDown(event) { this.oldPos = {x: this.mx, y: this.my}; // 先检测拖拽点 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) { case 'rect': target = item; callback = this.clickedHotZoneRect.bind(this); break; case 'pic': target = item.pic; callback = this.clickedHotZonePic.bind(this); break; case 'text': target = item.textLabel; callback = this.clickedHotZoneText.bind(this); break; } if (target && this.checkClickTarget(target)) { callback(target); return; } } } mapMove(event) { if (!this.curItem) { return; } if (this.changeSizeFlag) { this.changeSize(); } else if (this.changeTopSizeFlag) { this.changeTopSize(); } else if (this.changeRightSizeFlag) { this.changeRightSize(); } else { const addX = this.mx - this.oldPos.x; 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 = false; } mapUp(event=null) { this.curItem = null; this.changeSizeFlag = false; this.changeTopSizeFlag = false; this.changeRightSizeFlag = false; } changeSize() { const rect = this.curItem.getBoundingBox(); let lenW = (this.mx - (rect.x + rect.width / 2)) * 2; let lenH = ((rect.y + rect.height / 2) - this.my) * 2; let minLen = 20; let s; if (lenW < lenH) { if (lenW < minLen) { lenW = minLen; } s = lenW / this.curItem.width; } else { if (lenH < minLen) { lenH = minLen; } s = lenH / this.curItem.height; } // console.log('s: ', s); this.curItem.setScaleXY(s); this.curItem.refreshLabelScale(); } changeTopSize() { const rect = this.curItem.getBoundingBox(); // let lenW = ( this.mx - (rect.x + rect.width / 2) ) * 2; let lenH = ((rect.y + rect.height / 2) - this.my) * 2; let minLen = 20; let s; // if (lenW < lenH) { // if (lenW < minLen) { // lenW = minLen; // } // s = lenW / this.curItem.width; // // } else { if (lenH < minLen) { lenH = minLen; } s = lenH / this.curItem.height; // } // console.log('s: ', s); this.curItem.scaleY = s; this.curItem.refreshLabelScale(); } changeRightSize() { const rect = this.curItem.getBoundingBox(); let lenW = (this.mx - (rect.x + rect.width / 2)) * 2; // let lenH = ( (rect.y + rect.height / 2) - this.my ) * 2; let minLen = 20; let s; if (lenW < minLen) { lenW = minLen; } s = lenW / this.curItem.width; this.curItem.scaleX = s; this.curItem.refreshLabelScale(); } changeItemSize(item) { this.curItem = item; this.changeSizeFlag = true; } changeItemTopSize(item) { this.curItem = item; this.changeTopSizeFlag = true; } changeItemRightSize(item) { this.curItem = item; this.changeRightSizeFlag = true; } changeCurItem(item) { console.log(' in changeCurItem', item) this.hideAllLineDash(); this.curItem = item; this.curItem.showLineDash(); } hideAllLineDash() { for (let i = 0; i < this.imgArr.length; i++) { if (this.imgArr[i].picItem) { this.imgArr[i].picItem.hideLineDash(); } } } update() { if (!this.ctx) { return; } this.animationId = window.requestAnimationFrame(this.update.bind(this)); // 清除画布内容 this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight); // for (let i = 0; i < this.imgArr.length; i++) { // const picItem = this.imgArr[i].picItem; // if (picItem) { // picItem.update(this); // } // } for (let i = 0; i < this.renderArr.length; i++) { this.renderArr[i].update(this); } this.updateArr(this.hotZoneArr); this.updatePos(); TWEEN.update(); } updateArr(arr) { if (arr) { for (let i = 0; i < arr.length; i++) { arr[i].update(); } } } renderAfterResize() { this.canvasWidth = this.wrap.nativeElement.clientWidth; this.canvasHeight = this.wrap.nativeElement.clientHeight; this.init(); } initListener() { this.winResizeEventStream .pipe(debounceTime(500)) .subscribe(data => { this.renderAfterResize(); }); if (this.IsPC()) { this.canvas.nativeElement.addEventListener('mousedown', (event) => { setMxMyByMouse(event); this.mapDown(event); }); this.canvas.nativeElement.addEventListener('mousemove', (event) => { setMxMyByMouse(event); this.mapMove(event); }); this.canvas.nativeElement.addEventListener('mouseup', (event) => { setMxMyByMouse(event); this.mapUp(event); }); const setMxMyByMouse = (event) => { this.mx = event.offsetX; this.my = event.offsetY; }; } else { this.canvas.nativeElement.addEventListener('touchstart', (event) => { setMxMyByTouch(event); this.mapDown(event); }); this.canvas.nativeElement.addEventListener('touchmove', (event) => { setMxMyByTouch(event); this.mapMove(event); }); this.canvas.nativeElement.addEventListener('touchend', (event) => { setMxMyByTouch(event); this.mapUp(event); }); this.canvas.nativeElement.addEventListener('touchcancel', (event) => { setMxMyByTouch(event); this.mapUp(event); }); const setMxMyByTouch = (event) => { if (event.touches.length <= 0) { return; } if (this.canvasLeft == null) { setParentOffset(); } this.mx = event.touches[0].pageX - this.canvasLeft; this.my = event.touches[0].pageY - this.canvasTop; }; const setParentOffset = () => { const rect = this.canvas.nativeElement.getBoundingClientRect(); this.canvasLeft = rect.left; this.canvasTop = rect.top; }; } } IsPC() { if (window['ELECTRON']) { return false; // 封装客户端标记 } if (document.body.ontouchstart !== undefined) { return false; } else { return true; } } checkClickTarget(target) { if (!target || !target.visible) { return; } const rect = target.getBoundingBox(); if (this.checkPointInRect(this.mx, this.my, rect)) { return true; } return false; } checkPointInRect(x, y, rect) { if (x >= rect.x && x <= rect.x + rect.width) { if (y >= rect.y && y <= rect.y + rect.height) { return true; } } return false; } saveClick() { const sendData = this.getSendData(); this.save.emit(sendData); } getSendData() { const bgItem = this.bgItem; if (this.bg) { 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, y: 0, width: Math.round(this.canvasWidth * 100) / 100, height: Math.round(this.canvasHeight * 100) / 100 }; } const hotZoneItemArr = []; const hotZoneArr = this.hotZoneArr; 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, fontScale: hotZoneArr[i].textLabel ? hotZoneArr[i].textLabel.scaleX : 1, imgScale: hotZoneArr[i].pic ? hotZoneArr[i].pic.scaleX : 1, 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, }; 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; hotZoneItem['rect'].height = Math.round((hotZoneItem['rect'].height) * 100) / 100; hotZoneItemArr.push(hotZoneItem); } console.log('hotZoneItemArr: ', 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() { this.hotZoneArr.forEach((item) => { let x, y; switch (item.itemType) { case 'rect': x = item.x; y = item.y; break; case 'pic': x = item.pic.x; y = item.pic.y; break; case 'text': x = item.textLabel.x; y = item.textLabel.y; break; } 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; } }); } private setPicState(item: any) { item.visible = false; item.textLabel.visible = false; item.pic.visible = true; } private setRectState(item: any) { item.visible = true; item.textLabel.visible = false; item.pic.visible = false; } private setTextState(item: any) { item.visible = false; item.pic.visible = false; 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)) { 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); } return; } } 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; } } private clickedHotZoneText(item: any) { if (this.checkClickTarget(item)) { this.curItem = item; } } clickedDragPoint(item) { this.curItem = item; } private loadHotZonePic(pic: HotZoneImg, url, scale = null) { let baseLen; if (this.hotZoneImgSize) { baseLen = this.hotZoneImgSize * this.mapScale; } pic.load(url).then(() => { 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); } }