Commit ca9d44f4 authored by limingzhe's avatar limingzhe

feat: 滚动条

parent def3657a
......@@ -33,7 +33,7 @@
</div>
<div *ngIf="item.sentenceArr && item.sentenceArr.length < 4">
<div>
<button nz-button nzType="dashed" (click)="addBtnClick()" style="width: 200px; height: 50px;">
<i nz-icon nzType="plus-circle" nzTheme="outline"></i>
......
......@@ -310,6 +310,8 @@ export class MySprite extends Sprite {
child.alpha = this.alpha;
}
child.ctx = this.ctx;
}
removeChild(child) {
const index = this.children.indexOf(child);
......@@ -2002,6 +2004,281 @@ export class MyVideo extends MySprite {
export class ScrollView extends MySprite {
static ScrollSideType = {
VERTICAL : 'VERTICAL',
HORIZONTAL : 'HORIZONTAL',
}
_offCtx;
_offCanvas;
_scrollBar;
content;
bgColor;
barColor = '#fbe9b7'
scrollSide = ScrollView.ScrollSideType.VERTICAL;
scorllBarWidth;
scrollBarHeight;
constructor(ctx = null) {
super(ctx);
this._createOffCtx();
this._createScrollBar();
}
_createOffCtx() {
if (!this._offCtx) {
this._offCanvas = document.createElement('canvas'); // 创建一个新的canvas
this._offCanvas.width = this.width; // 创建一个正好包裹住一个粒子canvas
this._offCanvas.height = this.height;
this._offCtx = this._offCanvas.getContext('2d');
this.content = new MySprite(this._offCtx);
}
}
_createScrollBar() {
this._scrollBar = new ShapeRectNew();
this._scrollBar.anchorY = 0;
this._scrollBar.anchorX = 1;
this._scrollBar.setSize(10, 100, 5);
this._scrollBar.fillColor = this.barColor;
this.addChild(this._scrollBar);
}
setBgColor(color) {
this.bgColor = color;
}
setShowSize(w, h) {
this.width = w;
this.height = h;
if (this.content.width < this.width) {
this.content.width = this._offCanvas.width = this.width;
}
if (this.content.height < this.height) {
this.content.height = this._offCanvas.height = this.height;
}
this.refreshScrollBar();
}
setContentSize(w, h) {
this.content.width = w;
this.content.height = h;
this._offCanvas.width = w;
this._offCanvas.height = h;
}
addItem(sprite) {
this.content.addChild(sprite);
sprite.ctx = this._offCtx;
this.refreshContentSize();
}
refreshContentSize() {
const children = this.content.children;
console.log('children: ', children);
let maxW = 0;
let maxH = 0;
for (let i=0; i<children.length; i++) {
if (children[i] == this.content) {
continue;
}
const box = children[i].getBoundingBox();
console.log('box: ', box);
const boxEdgeX = box.x + box.width;
const boxEdgeY = box.y + box.height;
console.log('boxEdgeY: ', boxEdgeY);
if (boxEdgeX > maxW) {
maxW = boxEdgeX;
}
if (boxEdgeY > maxH) {
maxH = boxEdgeY;
}
}
console.log('maxW: ', maxW);
console.log('maxH: ', maxH);
this.content.width = maxW;
this.content.height = maxH ;
this.refreshScrollBar();
}
setScrollBarSize(w, h) {
this.scorllBarWidth = w;
this.scrollBarHeight = h;
}
setContentScale(s) {
this.content.setScaleXY( 1 / s);
}
refreshScrollBar() {
let w = this.scorllBarWidth;
if (!w) {
w = this.width / 50;
}
let rate = this.height * this.scaleY / this.content.height / this.content.scaleY;
if (rate >= 1) {
this._scrollBar.visible = false;
rate = 1;
} else {
this._scrollBar.visible = true;
}
const h = rate * this.height
const r = w / 2;
this._scrollBar.setSize(w, h, r);
this._scrollBar.x = this.width;
}
refreshScrollBarPos() {
this._scrollBar.y = -this.content.y * ( this.height / this.content.height );
}
drawSelf() {
super.drawSelf();
this._offScreenRender();
}
touchStartPos;
touchStartContentPos;
onTouchStart(x, y) {
if (!this._scrollBar.visible) {
return;
}
this.touchStartPos = { x, y };
this.touchStartContentPos = { x: this.content.x, y: this.content.y };
}
onTouchMove(x, y) {
if (!this.touchStartPos) {
return;
}
if (!this.touchStartContentPos) {
return;
}
const offsetX = x - this.touchStartPos.x;
const offsetY = y - this.touchStartPos.y;
if (this.scrollSide == ScrollView.ScrollSideType.VERTICAL) {
this.content.y = between(this.touchStartContentPos.y + offsetY, 0, this.getBoundingBox().height - this.content.height);
} else {
this.content.x = between(this.touchStartContentPos.x + offsetX, 0, this.getBoundingBox().width - this.content.width);
}
this.refreshScrollBarPos();
}
onTouchEnd(x, y) {
this.touchStartPos = null;
this.touchStartContentPos = null;
}
onWheelUp(offsetY) {
if (!this._scrollBar.visible) {
return;
}
if (this.scrollSide == ScrollView.ScrollSideType.VERTICAL) {
this.content.y = between(this.content.y + 40, 0, this.getBoundingBox().height - this.content.height);
} else {
this.content.x = between(this.content.x + 40, 0, this.getBoundingBox().width - this.content.width);
}
this.refreshScrollBarPos();
}
onWheelDown(offsetY) {
if (!this._scrollBar.visible) {
return;
}
if (this.scrollSide == ScrollView.ScrollSideType.VERTICAL) {
this.content.y = between(this.content.y - 40, 0, this.getBoundingBox().height - this.content.height);
} else {
this.content.x = between(this.content.x - 40, 0, this.getBoundingBox().width - this.content.width);
}
this.refreshScrollBarPos();
}
setContentSpr() {
}
_offScreenRender() {
this._offCtx.save();
this._offCtx.clearRect(0, 0, this._offCanvas.width, this._offCanvas.height);
if (this.bgColor) {
this._offCtx.fillStyle = this.bgColor;
this._offCtx.fillRect(this._offX, this._offY, this.width, this.height);
this._offCtx.globalCompositeOperation = "source-atop";
} else {
this._offCtx.fillStyle = '#ffffff'
this._offCtx.fillRect(this._offX, this._offY, this.width, this.height);
this._offCtx.globalCompositeOperation = "xor";
}
this.content.update();
this.ctx.drawImage(this._offCanvas, this._offX, this._offY);
// this.ctx.drawImage(this._offCanvas, this._offX, this._offY);
// this.ctx.drawImage(this._offCanvas, this._offX, this._offY, this.content.width, this.content.height, this._offX + this.content.x, this._offY + this.content.y, this.width, this.height);
this._offCtx.restore();
}
}
export function between(a, b, c) {
return [a, b, c].sort((x, y) => x - y)[1];
}
// --------------- custom class --------------------
......@@ -6,7 +6,7 @@ import {
moveItem,
rotateItem,
removeItemFromArr,
ShapeRect, scaleItem, tweenChange, showPopParticle, hideItem, showItem, LineRect, shake, RichText, ShapeRectNew, showShapeParticle, delayCall, randomSortByArr,
ShapeRect, scaleItem, tweenChange, showPopParticle, hideItem, showItem, LineRect, shake, RichText, ShapeRectNew, showShapeParticle, delayCall, randomSortByArr, ScrollView,
} from './Unit';
import { res, resAudio } from './resources';
......@@ -177,6 +177,7 @@ export class PlayComponent implements OnInit, OnDestroy {
this.initImg();
this.initListener();
}, this.KEY);
......@@ -245,6 +246,10 @@ export class PlayComponent implements OnInit, OnDestroy {
submitCount = 0;
safeDefaultUrl;
resultAnswerArr;
scrollView;
resultSv;
initData() {
......@@ -284,7 +289,7 @@ export class PlayComponent implements OnInit, OnDestroy {
this.resultAnswerArr = [];
this.resultSv = null;
}
......@@ -550,16 +555,43 @@ export class PlayComponent implements OnInit, OnDestroy {
}
_initView() {
// const spr = new MySprite()
// spr.init(this.images.get("result_panel_item"));
// this.renderArr.push(spr);
this.renderArr = [];
const scrollView = new ScrollView();
// scrollView.setContentSize(300, 300);
scrollView.setShowSize(200, 200);
scrollView.x = this.canvasWidth / 2;
scrollView.y = this.canvasHeight / 2;
this.scrollView = scrollView;
this.renderArr.push(scrollView);
for (let i=0; i<10; i++) {
const spr = new MySprite()
spr.init(this.images.get("info_icon"));
spr.anchorX = 0;
spr.y = i * 100;
scrollView.addItem(spr)
}
}
initView() {
this.initBg();
this.initBtn();
this.initSentence();
this.initBtn();
this.changeBtnOff();
......@@ -571,9 +603,9 @@ export class PlayComponent implements OnInit, OnDestroy {
this.relink();
// this.gameStart();
// this.initResultView();
}
relink() {
......@@ -756,22 +788,37 @@ export class PlayComponent implements OnInit, OnDestroy {
}
initResultSentence() {
let baseY = -500;
const resultSv = new ScrollView();
resultSv.setShowSize(this.resultPanel.width, this.resultPanel.height * 0.85);
resultSv.setBgColor("#3e9e33");
resultSv.x = -this.resultPanel.width / 2;
resultSv.y = -this.resultPanel.height / 2 + 120;
resultSv.setScrollBarSize(20 * this.mapScale, 5);
resultSv.setContentScale(this.mapScale);
this.resultPanel.addChild(resultSv);
this.resultSv = resultSv;
let baseY = 0 //-500;
for (let i=0; i<this.sentenceArr.length; i++) {
const richText = new RichText();
richText.disH = 5;
richText.x = -this.panel.width / 2 * 0.9
// richText.x = -this.panel.width / 2 * 0.9
richText.x = 0.05 * this.panel.width;
richText.y = baseY + 80;
richText.fontSize = 48;
richText.width = this.panel.width * 0.9;
richText.fontColor = '#ffffff'
richText.fontName = 'DroidSansFallback';
richText.text = this.sentenceArr[i].text ;
richText.text = this.sentenceArr[i].text;
// this.resultPanel.addChild(richText, 1)
resultSv.addItem(richText);
this.resultPanel.addChild(richText, 1)
const rect = richText.getSubTextRect('____________________');
rect.width += 8;
......@@ -794,7 +841,9 @@ export class PlayComponent implements OnInit, OnDestroy {
const infoBg = new MySprite();
infoBg.init(this.images.get("info_bg"));
infoBg.y = baseY + 50;
this.resultPanel.addChild(infoBg);
infoBg.x = this.resultPanel.width / 2 * this.mapScale;
resultSv.addItem(infoBg);
// this.resultPanel.addChild(infoBg);
baseY += 130;
const infoIcon = new MySprite();
......@@ -832,9 +881,11 @@ export class PlayComponent implements OnInit, OnDestroy {
if (i != this.sentenceArr.length - 1) {
const line = new MySprite();
line.init(this.images.get("line"));
line.x = 0;
line.x = this.resultPanel.width / 2;
line.y = baseY + 30;
this.resultPanel.addChild(line);
resultSv.addItem(line);
// this.resultPanel.addChild(line);
baseY = line.y
}
......@@ -853,28 +904,33 @@ export class PlayComponent implements OnInit, OnDestroy {
const btnArr = [];
let arr = JSON.parse(JSON.stringify(this.sentenceArr)) ;
// arr = arr.concat(arr[0]);
arr = randomSortByArr(arr);
if (!arr) {
return;
}
const disW = 500 * this.mapScale;
const baseX = this.canvasWidth / 2 - (arr.length - 1) * disW / 2
const baseY = this.canvasHeight / 2 - 380 * this.mapScale;
const disW = 400 * this.mapScale;
const disH = 120 * this.mapScale;
const tmpLen = arr.length > 5 ? 5 : arr.length;
let baseX = this.canvasWidth / 2 - (tmpLen - 1) * disW / 2
let baseY = this.canvasHeight / 2 - 380 * this.mapScale;
let col = 0;
for (let i=0; i<arr.length; i++) {
const btn = new MySprite();
btn.init(this.images.get("btn"))
btn.x = baseX + disW * i;
btn.x = baseX + disW * col;
btn.y = baseY;
btn['baseX'] = btn.x;
btn['baseY'] = btn.y;
btn.setScaleXY(this.mapScale);
btn.setScaleXY(this.mapScale * 0.8);
const btnBg = new MySprite();
btnBg.init(this.images.get("btn_bg"))
btnBg.x = btn.x;
btnBg.y = btn.y;
btnBg.setScaleXY(this.mapScale);
btnBg.setScaleXY(this.mapScale * 0.8);
this.renderArr.push(btnBg);
this.topArr.push(btn);
......@@ -882,6 +938,12 @@ export class PlayComponent implements OnInit, OnDestroy {
this.addBtnLabel(btn, arr[i].answer);
btnArr.push(btn);
col ++ ;
if (col % 5 == 0) {
col = 0;
baseY += disH;
}
}
this.btnArr = btnArr;
......@@ -1004,15 +1066,37 @@ export class PlayComponent implements OnInit, OnDestroy {
sentenceEmptyArr;
initSentence() {
const tmpY = this.btnArr[this.btnArr.length - 1].y;
const sv = new ScrollView();
sv.setShowSize(this.panel.width, 1250 - tmpY);
sv.x = -this.panel.width / 2;
sv.y = tmpY - 720;
sv.setBgColor('#faf7ee')
// sv.setMapScale(this.mapScale);
// sv.content.setScaleXY(1/this.mapScale);
sv.setScrollBarSize(20 * this.mapScale, 5)
// this.renderArr.push(sv);
// sv.setScaleXY(this.mapScale);
// sv.x = 0;
// sv.y = 200;
sv.setContentScale(this.mapScale);
this.panel.addChild(sv);
this.scrollView = sv;
this.sentenceEmptyArr = [];
const arr = this.sentenceArr;
// const arr = this.sentenceArr.concat(this.sentenceArr);
if (!arr) {
return;
}
const baseX = this.canvasWidth / 2 -990 * this.mapScale;
let curY = this.canvasHeight / 2 - 110 * this.mapScale;
const baseX = this.panel.width / 2 - 1000;
let curY = 70 // this.canvasHeight / 2 - 110 * this.mapScale;
const disH = 70 * this.mapScale;
for (let i=0; i<arr.length; i++) {
const richText = this.getSentenceLabel();
......@@ -1040,7 +1124,13 @@ export class PlayComponent implements OnInit, OnDestroy {
curY += richText.getAreaHeight() * this.mapScale + disH;
richText['data'] = arr[i];
this.renderArr.push(richText);
sv.addItem(richText);
// this.renderArr.push(richText);
colorRect.ctx = colorRect.parent.ctx;
}
......@@ -1281,11 +1371,12 @@ export class PlayComponent implements OnInit, OnDestroy {
this.renderArr.push(panel);
const panelItem = new MySprite();
panelItem.init(this.images.get("panel_item"));
// panelItem.x = this.canvasWidth / 2;
panelItem.y = 150;
panel.addChild(panelItem);
// const panelItem = new MySprite();
// panelItem.init(this.images.get("panel_item"));
// panelItem.anchorY = 1;
// // panelItem.x = this.canvasWidth / 2;
// panelItem.y = 550;
// panel.addChild(panelItem);
const title = new Label();
......@@ -1316,6 +1407,9 @@ export class PlayComponent implements OnInit, OnDestroy {
mapDown(event) {
console.log('aaaa 1')
if (!this.canTouch) {
return;
}
......@@ -1325,6 +1419,7 @@ export class PlayComponent implements OnInit, OnDestroy {
}
this.downFlag = true;
console.log('aaaa 2')
......@@ -1340,6 +1435,7 @@ export class PlayComponent implements OnInit, OnDestroy {
return;
}
console.log('aaaa 3')
if (this.moreBtn) {
if (this.checkClickTarget(this.moreBtn)) {
......@@ -1350,6 +1446,7 @@ export class PlayComponent implements OnInit, OnDestroy {
}
}
console.log('aaaa 4')
for (let i = 0; i < this.btnArr.length; i++) {
......@@ -1361,9 +1458,11 @@ export class PlayComponent implements OnInit, OnDestroy {
return;
}
}
console.log('aaaa 5')
for (let i = 0; i < this.sentenceEmptyArr.length; i++) {
if (this.checkClickTarget(this.sentenceEmptyArr[i])) {
if (this.checkClickTargetSv(this.sentenceEmptyArr[i])) {
if (!this.sentenceEmptyArr[i].isRight) {
this.emptyRectDown(this.sentenceEmptyArr[i]);
......@@ -1373,6 +1472,9 @@ export class PlayComponent implements OnInit, OnDestroy {
}
}
console.log('aaaa 6')
if (this.checkClickTarget(this.submitBtn)) {
if (this.submitBtn.visible) {
this.submitBtnClick();
......@@ -1382,6 +1484,17 @@ export class PlayComponent implements OnInit, OnDestroy {
return;
}
if (this.resultSv && this.checkClickTarget(this.resultSv)) {
this.resultSv.onTouchStart(this.mx, this.my);
return;
}
if (this.checkClickTarget(this.scrollView)) {
this.scrollView.onTouchStart(this.mx, this.my);
return;
}
this.downFlag = false;
}
......@@ -1391,8 +1504,16 @@ export class PlayComponent implements OnInit, OnDestroy {
mapMove(event) {
event.preventDefault()
if (event) {
event.preventDefault()
}
if (this.resultSv) {
this.resultSv.onTouchMove(this.mx, this.my);
} else {
this.scrollView.onTouchMove(this.mx, this.my);
}
if (!this.curMoveItem) {
return;
......@@ -1409,6 +1530,7 @@ export class PlayComponent implements OnInit, OnDestroy {
this.curMoveItem.x += this.curMoveItem.moveOffX;
this.curMoveItem.y += this.curMoveItem.moveOffY;
}
// this.curMoveItem.ctx = this.ctx;
}
......@@ -1416,6 +1538,8 @@ export class PlayComponent implements OnInit, OnDestroy {
mapUp(event) {
this.downFlag = false;
if (this.curMoveItem) {
......@@ -1423,6 +1547,13 @@ export class PlayComponent implements OnInit, OnDestroy {
}
this.curMoveItem = null;
if (this.resultSv) {
this.resultSv.onTouchEnd(this.mx, this.my);
} else {
this.scrollView.onTouchEnd(this.mx, this.my);
}
}
......@@ -1496,7 +1627,19 @@ export class PlayComponent implements OnInit, OnDestroy {
emptyRectDown(emptyRect) {
if (emptyRect.label) {
this.curMoveItem = emptyRect.label;
emptyRect.label.visible = false;
console.log('emptyRect.label: ', emptyRect.label);
const label = this.getFillLabel();
label.textAlign = 'center';
label.text = emptyRect.label.text;
this.renderArr.push(label);
label['targetLabel'] = emptyRect.label;
label['fillRect'] = emptyRect.label.fillRect;
this.curMoveItem = label;
this.mapMove(null)
return;
}
}
......@@ -1614,7 +1757,8 @@ export class PlayComponent implements OnInit, OnDestroy {
this.showBtnByText(emptyRect.label.text);
removeItemFromArr(this.renderArr, emptyRect.label);
emptyRect.removeChild(emptyRect.label);
// removeItemFromArr(this.renderArr, emptyRect.label);
emptyRect.label = null;
}
......@@ -1649,7 +1793,7 @@ export class PlayComponent implements OnInit, OnDestroy {
for (let i = 0; i < this.sentenceEmptyArr.length; i++) {
if (this.checkClickTarget(this.sentenceEmptyArr[i])) {
if (this.checkClickTargetSv(this.sentenceEmptyArr[i])) {
this.playAudio('click', true);
......@@ -1672,6 +1816,7 @@ export class PlayComponent implements OnInit, OnDestroy {
this.fillText(this.sentenceEmptyArr[i], this.curMoveItem.text);
if (this.curMoveItem.fillRect) {
this.fillText(this.curMoveItem.fillRect, tmpText);
this.curMoveItem.text = tmpText;
this.moveItemBack();
}
......@@ -1686,6 +1831,7 @@ export class PlayComponent implements OnInit, OnDestroy {
}
this.moveItemBack();
}
removeBtn(btn) {
......@@ -1702,7 +1848,11 @@ export class PlayComponent implements OnInit, OnDestroy {
if (!emptyRect.label) {
emptyRect.label = this.getFillLabel();
this.renderArr.push(emptyRect.label);
emptyRect.label.setScaleXY(1);
emptyRect.label.textAlign = 'center';
emptyRect.addChild(emptyRect.label);
// this.renderArr.push(emptyRect.label);
}
const label = emptyRect.label
label.text = text;
......@@ -1711,8 +1861,12 @@ export class PlayComponent implements OnInit, OnDestroy {
label.refreshSize();
label.anchorY = 0.5;
label.y = emptyRect.parent.y //- label.height * label.scaleY ;
label.x = emptyRect.parent.x + ( emptyRect.x + emptyRect.width / 2 - label.width / 2 ) * this.mapScale
// label.y = emptyRect.parent.y //- label.height * label.scaleY ;
// label.x = emptyRect.parent.x + ( emptyRect.x + emptyRect.width / 2 - label.width / 2 ) * this.mapScale
label.y = emptyRect.height / 2;
label.x = ( emptyRect.width / 2 )
// const w1 = emptyRect.width / this.mapScale;
// const w2 = label.width;
......@@ -1745,6 +1899,12 @@ export class PlayComponent implements OnInit, OnDestroy {
moveItemBack() {
if (this.curMoveItem.targetLabel) {
this.curMoveItem.targetLabel.visible = true;
removeItemFromArr(this.renderArr, this.curMoveItem);
return;
}
this.curMoveItem.x = this.curMoveItem['baseX'];
this.curMoveItem.y = this.curMoveItem['baseY'];
}
......@@ -1759,6 +1919,9 @@ export class PlayComponent implements OnInit, OnDestroy {
this.templateArr = this.data.contentObj.templateArr;
if (this.templateArr.length <= 0) {
return;
}
console.log('arr: ', this.templateArr);
const c = window['courseware'];
......@@ -2337,9 +2500,46 @@ export class PlayComponent implements OnInit, OnDestroy {
addMouseListener();
addTouchListener();
element.addEventListener('mousewheel', (event) => {
setMxMyByMouse(event);
if (event.deltaY > 0) {
this.wheelDown(event);
} else {
this.wheelUp(event);
}
});
}
wheelUp(event: any) {
if (this.resultSv) {
if (this.checkClickTarget(this.resultSv)) {
this.resultSv.onWheelUp(event.deltaY);
}
} else {
if (this.checkClickTarget(this.scrollView)) {
this.scrollView.onWheelUp(event.deltaY);
}
}
}
wheelDown(event: any) {
if (this.resultSv) {
if (this.checkClickTarget(this.resultSv)) {
this.resultSv.onWheelDown(event.deltaY);
}
} else {
if (this.checkClickTarget(this.scrollView)) {
this.scrollView.onWheelDown(event.deltaY);
}
}
}
playAudio(key, now = false, callback = null) {
const audio = this.audioObj[key];
......@@ -2461,7 +2661,48 @@ export class PlayComponent implements OnInit, OnDestroy {
this.init();
}
checkClickTargetSv(target) {
let tmpRect = target.getBoundingBox();
// rect.x /= 2;
// rect.y /= 2;
// rect.width /= 2;
// rect.height /= 2;
const svBox = this.scrollView.getBoundingBox();
const x = svBox.x + tmpRect.x * this.mapScale;
const y = svBox.y + tmpRect.y * this.mapScale;
const width = tmpRect.width * this.mapScale;
const height = tmpRect.height * this.mapScale;
const rect = {x, y, width, height};
// const contentBox = this.scrollView.content.getBoundingBox();
// rect.x += contentBox.x + svBox.x;
// rect.y += contentBox.y + svBox.y;
// console.log('rect: ', rect);
// console.log('this.mx: ', this.mx);
// console.log('this.my: ', this.my);
// const shape = new ShapeRectNew();
// shape.x = rect.x;
// shape.y = rect.y;
// shape.fillColor = '#0000ff'
// shape.alpha = 0.5;
// shape.setSize(rect.width, rect.height, 1);
// this.renderArr.push(shape);
if (this.checkPointInRect(this.mx, this.my, rect)) {
return true;
}
return false;
}
checkClickTarget(target) {
......@@ -2472,6 +2713,9 @@ export class PlayComponent implements OnInit, OnDestroy {
// rect.width /= 2;
// rect.height /= 2;
// console.log('rect: ', rect);
if (this.checkPointInRect(this.mx, this.my, rect)) {
return true;
}
......
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