Commit e5f1c4f8 authored by limingzhe's avatar limingzhe

feat: 增加语法评测

parent 404a936f
...@@ -841,48 +841,67 @@ export class RichTextOld extends Label { ...@@ -841,48 +841,67 @@ export class RichTextOld extends Label {
export class RichText extends Label { export class RichText extends Label {
topH = 8; topH = 0;
disH = 10; disH = 10;
offW = 10; offW = 10;
private rowCount = 1; row = 1;
textBaseline = "middle"; textBaseline = "middle";
isShowWordBg = false;
wordBgData;
constructor(ctx?: any) { constructor(ctx?: any) {
super(ctx); super(ctx);
// this.dataArr = dataArr;
} }
getLineNum() { getLineNum() {
this.drawSelf(); this.drawSelf();
return this.rowCount; return this.row;
} }
getAreaHeight() { getAreaHeight() {
this.drawSelf(); this.drawSelf();
const tmpTextH = this.rowCount * this.fontSize; const tmpTextH = this.row * this.fontSize;
const tmpDisH = (this.rowCount - 1) * this.disH const tmpDisH = (this.row - 1) * this.disH
return tmpTextH + tmpDisH; return tmpTextH + tmpDisH;
} }
// addLabelMask(mask) { getSubTextRectGroup(text, targetIndex = 0) {
// this._labelMaskArr.push(mask); const rectGroup = [];
// this._createLabelOffCtx(); const subTextArr = text.split(' ');
// } let baseIndex = targetIndex;
console.log('subTextArr: ', subTextArr);
for (let i=0; i<subTextArr.length; i++) {
const subtText = subTextArr[i];
const subData = this.getSubTextRect(subtText, baseIndex)
if (subData) {
rectGroup.push(subData);
baseIndex = Number( subData.index );
}
}
// _createLabelOffCtx() { return rectGroup;
// if (!this._labelOffCtx) { }
// this._labelOffCanvas = document.createElement('canvas'); // 创建一个新的canvas
// this._labelOffCanvas.width = this.width; // 创建一个正好包裹住一个粒子canvas getSubTextRect(subText, targetIndex=0) {
// this._labelOffCanvas.height = this.height;
// this._labelOffCtx = this._labelOffCanvas.getContext('2d');
// }
// } subText = subText.trim();
if (!subText) {
return;
}
this.isShowWordBg = true;
this.update();
getSubTextRect(subText) {
const tmpLabel = new RichText(); const tmpLabel = new RichText();
tmpLabel.fontSize = this.fontSize; tmpLabel.fontSize = this.fontSize;
...@@ -892,22 +911,31 @@ export class RichText extends Label { ...@@ -892,22 +911,31 @@ export class RichText extends Label {
tmpLabel.fontWeight = this.fontWeight; tmpLabel.fontWeight = this.fontWeight;
tmpLabel.width = this.width; tmpLabel.width = this.width;
tmpLabel.height = this.height; tmpLabel.height = this.height;
console.log('subText: ', subText);
console.log('this.text: ', this.text);
// const indexArr = searchSubStr(this.text, subText);
// console.log('indexArr: ', indexArr);
// const index = indexArr[targetIndex];
const index = this.text.indexOf(subText); const index = this.text.indexOf(subText, targetIndex);
tmpLabel.text = this.text.substring(0, index);
tmpLabel.refreshSize();
const x = tmpLabel.width; console.log('index: ', index);
if (index == -1) {
return;
}
tmpLabel.text = subText; // console.log('this.wordBgData: ', this.wordBgData);
tmpLabel.refreshSize(); // const index = this.text.indexOf(subText);
// console.log('!!!index: ', index);
const width = tmpLabel.width; const data = this.wordBgData[index.toString()];
// console.log('!!!wordBgData: ', this.wordBgData);
// console.log('!!!data: ', data);
return data;
const y = this.fontSize / 2;
const height = this.fontSize;
return {x, y, width, height}
} }
...@@ -930,7 +958,6 @@ export class RichText extends Label { ...@@ -930,7 +958,6 @@ export class RichText extends Label {
curCtx = this._offCtx; curCtx = this._offCtx;
} }
curCtx.font = `${this.fontSize}px ${this.fontName}`; curCtx.font = `${this.fontSize}px ${this.fontName}`;
curCtx.textAlign = this.textAlign; curCtx.textAlign = this.textAlign;
curCtx.textBaseline = this.textBaseline; curCtx.textBaseline = this.textBaseline;
...@@ -943,40 +970,68 @@ export class RichText extends Label { ...@@ -943,40 +970,68 @@ export class RichText extends Label {
const chr = this.text.split(' '); const chr = this.text.split(' ');
let temp = ''; let temp = '';
const rows = []; const row = [];
const w = selfW - this.offW * 2; const w = selfW - this.offW * 2;
const disH = (this.fontSize + this.disH) * this.scaleY; const disH = (this.fontSize + this.disH) * this.scaleY;
let isPushWordData = false;
if (this.isShowWordBg && !this.wordBgData) {
this.wordBgData = {};
isPushWordData = true;
}
let wordIndex = -1;
for (const c of chr) {
if (isPushWordData) {
}
for (const c of chr) {
if (curCtx.measureText(temp).width < w && curCtx.measureText(temp + (c)).width <= w) { if (c == '\n') {
row.push(temp);
temp = '';
} else if (curCtx.measureText(temp).width < w && curCtx.measureText(temp + (c)).width <= w) {
temp += ' ' + c; temp += ' ' + c;
} else { } else {
rows.push(temp); row.push(temp);
temp = ' ' + c; temp = ' ' + c;
} }
if (isPushWordData) {
wordIndex = this.text.indexOf(c, wordIndex+1);
const key = wordIndex.toString();
const rectX = curCtx.measureText(temp).width
const rectY = ( row.length ) * disH / this.scaleY
const rectW = curCtx.measureText(c).width;
const rectH = this.fontSize;
this.wordBgData[key] = {rect: {x: rectX, y: rectY, width: rectW, height: rectH}, text: c, index: wordIndex}
}
} }
rows.push(temp); row.push(temp);
this.rowCount = rows.length; this.row = row.length;
const x = 0; const x = 0;
const y = this.topH; const y = this.topH//-row.length * disH / 2;
// for (let b = 0 ; b < row.length; b++) {
// curCtx.strokeText(row[b], x, y + ( b + 1 ) * disH ); // 每行字体y坐标间隔20
// }
if (this._outlineFlag) { if (this._outlineFlag) {
curCtx.lineWidth = this._outLineWidth; curCtx.lineWidth = this._outLineWidth;
curCtx.strokeStyle = this._outLineColor; curCtx.strokeStyle = this._outLineColor;
for (let b = 0 ; b < rows.length; b++) { for (let b = 0 ; b < row.length; b++) {
curCtx.strokeText(rows[b], x, y + ( b + 0 ) * disH / this.scaleY ); // 每行字体y坐标间隔20 curCtx.strokeText(row[b], x, y + ( b + 0 ) * disH / this.scaleY ); // 每行字体y坐标间隔20
} }
// curCtx.strokeText(this.text, 0, 0);
} }
for (let b = 0 ; b < rows.length; b++) { // curCtx.fillStyle = '#ff7600';
curCtx.fillText(rows[b], x, y + ( b + 0 ) * disH / this.scaleY ); // 每行字体y坐标间隔20 for (let b = 0 ; b < row.length; b++) {
curCtx.fillText(row[b], x, y + ( b + 0 ) * disH / this.scaleY ); // 每行字体y坐标间隔20
} }
...@@ -991,7 +1046,6 @@ export class RichText extends Label { ...@@ -991,7 +1046,6 @@ export class RichText extends Label {
this._maskSprArr[i].ctx = this._offCtx; this._maskSprArr[i].ctx = this._offCtx;
this._maskSprArr[i].update(); this._maskSprArr[i].update();
} }
// console.log('aaaaa1'); // console.log('aaaaa1');
} }
...@@ -1001,11 +1055,10 @@ export class RichText extends Label { ...@@ -1001,11 +1055,10 @@ export class RichText extends Label {
} }
drawSelf() { drawSelf() {
super.drawSelf(); super.drawSelf();
this.drawText();
} }
} }
......
...@@ -874,9 +874,9 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -874,9 +874,9 @@ export class PlayComponent implements OnInit, OnDestroy {
moreBtn; moreBtn;
initResultView(data = null) { initResultView(data = null) {
this.setAnswerData();
if (data) { if (data) {
console.log('initResultView data : ', data)
this.setRectRight(data); this.setRectRight(data);
} else { } else {
const resultData = this.getResultData(); const resultData = this.getResultData();
...@@ -1004,6 +1004,9 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -1004,6 +1004,9 @@ export class PlayComponent implements OnInit, OnDestroy {
let baseY = 0 //-500; let baseY = 0 //-500;
for (let i=0; i<this.hotZoneArr.length; i++) { for (let i=0; i<this.hotZoneArr.length; i++) {
const result = this.hotZoneArr[i].result;
const richText = new RichText(); const richText = new RichText();
richText.disH = 5; richText.disH = 5;
// richText.x = -this.panel.width / 2 * 0.9 // richText.x = -this.panel.width / 2 * 0.9
...@@ -1014,7 +1017,7 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -1014,7 +1017,7 @@ export class PlayComponent implements OnInit, OnDestroy {
richText.width = this.resultPanel.width * 0.9; richText.width = this.resultPanel.width * 0.9;
richText.fontColor = '#ffffff' richText.fontColor = '#ffffff'
richText.fontName = 'DroidSansFallback'; richText.fontName = 'DroidSansFallback';
richText.text = this.hotZoneArr[i].result.userAnswer; richText.text = result.userAnswer;
// this.resultPanel.addChild(richText, 1) // this.resultPanel.addChild(richText, 1)
...@@ -1048,7 +1051,36 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -1048,7 +1051,36 @@ export class PlayComponent implements OnInit, OnDestroy {
baseY = richText.y + richText.getAreaHeight(); baseY = richText.y + richText.getAreaHeight();
if (!this.hotZoneArr[i].isRight) { if (result.isAi) {
colorRect.alpha = 0;
const infoBg = new ShapeRectNew();
// infoBg.init(this.images.get("info_bg"));
infoBg.setSize(1838, 120, 60);
infoBg.fillColor = '#3b962e';
infoBg.y = baseY //+ 50;
infoBg.x = (this.resultPanel.width - infoBg.width) / 2//* this.mapScale;
// infoBg.x = this.resultPanel.width / 2 //* this.mapScale;
resultSv.addItem(infoBg);
// this.resultPanel.addChild(infoBg);
// baseY += 130;
const infoIcon = new MySprite();
infoIcon.init(this.images.get("ai_icon"));
infoIcon.x = 100;
infoIcon.y = 60;
infoBg.addChild(infoIcon);
this.addResultLabelCircle(richText, result);
const tmpH = this.getInfoLabelLayer(infoBg, result);
baseY += tmpH;
infoBg.height = tmpH;
resultSv.refreshContentSize();
} else if (!this.hotZoneArr[i].isRight) {
colorRect.fillColor = '#d71818' colorRect.fillColor = '#d71818'
const infoBg = new MySprite(); const infoBg = new MySprite();
...@@ -1111,6 +1143,171 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -1111,6 +1143,171 @@ export class PlayComponent implements OnInit, OnDestroy {
} }
getInfoLabelLayer(infoBg, result) {
const {resultTextArr, iconData} = result;
const arr = [];
for (let k in iconData) {
iconData[k].index = k ;
arr.push(iconData[k])
}
const layer = new MySprite();
let baseIndex = 0;
let tmpH = 40;
for (let i=0; i<arr.length; i++) {
const circle = new ShapeCircle();
circle.setRadius(30);
circle.x = 200;
circle.y = tmpH + 20;
circle.fillColor = '#dcc077'
infoBg.addChild(circle);
const label = new Label();
label.text = (i+1).toString();
label.fontColor = '#ffffff';
label.textAlign = 'center';
label.fontName = 'Aileron-Bold';
label.y = 3;
circle.addChild(label);
const infoLabel = new RichText();
infoLabel.topH = 0;
infoBg.addChild(infoLabel);
infoLabel.x = 230;
infoLabel.fontSize = 48;
infoLabel.y = tmpH + 20;
infoLabel.width = infoBg.width * 0.8;
infoLabel.fontColor = '#ffe9b1'
infoLabel.fontName = 'Aileron-Black';
infoLabel.text = arr[i].dataArr[0].reason;
tmpH = infoLabel.y + infoLabel.getAreaHeight();
// const rect = lastRect.rect;
// rect.x -= rect.width;
// rect.y -= rect.height / 2;
// const colorRect = this.getColorRect(rect);
// colorRect.alpha = 0.5;
// // colorRect.y -= rect.height;
// // infoLabel.addChild(colorRect);
// const circle = new ShapeCircle();
// circle.setRadius(20);
// circle.fillColor = '#dcc077';
// circle.x = rect.x + rect.width;
// circle.y = rect.y;
// infoLabel.addChild(circle);
// const label = new Label();
// label.textAlign = 'center';
// label.fontColor = '#ffffff';
// label.fontSize = 30;
// label.text = (i + 1).toString()
// circle.addChild(label);
}
return tmpH
// const infoLabel = new RichText();
// infoBg.addChild(infoLabel);
// infoLabel.x = infoIcon.x + 50;
// infoLabel.fontSize = 48;
// infoLabel.y = 5;
// infoLabel.width = infoBg.width;
// infoLabel.fontColor = '#ffe9b1'
// infoLabel.fontName = 'Aileron-Black';
// infoLabel.text = this.getOneAiResultText(result);// this.hotZoneArr[i].result?.info || '';
// this.addResultLabelCircle(infoLabel, result);
}
getOneAiResultText(result) {
const {resultTextArr} = result;
let curText = '';
for (let i=0; i<resultTextArr.length; i++) {
curText += resultTextArr[i].text + '';
}
console.log(' in getOneAiResultText ', resultTextArr);
return curText;
}
addResultLabelCircle(infoLabel, result) {
const {resultTextArr, iconData} = result;
let baseIndex = 0;
for (let i=0; i<resultTextArr.length; i++) {
const curText = resultTextArr[i].text;
// const rect = infoLabel.getSubTextRect(curText)?.rect;
const rectGroup = infoLabel.getSubTextRectGroup(curText, baseIndex);
if (!rectGroup) {
continue;
}
console.log('~rectGroup: ', rectGroup);
// const rectFirst = rectGroup[0];
const lastRect = rectGroup[rectGroup.length - 1];
const key = lastRect.index + lastRect.text.length;
console.log('~key: ', key);
console.log('~rect: ', lastRect);
console.log('iconData: ', iconData);
if (!iconData[key]) {
continue;
}
const rect = lastRect.rect;
rect.x -= rect.width;
rect.y -= rect.height / 2;
const colorRect = this.getColorRect(rect);
colorRect.alpha = 0.5;
// colorRect.y -= rect.height;
// infoLabel.addChild(colorRect);
const circle = new ShapeCircle();
circle.setRadius(20);
circle.fillColor = '#dcc077';
circle.x = rect.x + rect.width;
circle.y = rect.y;
infoLabel.addChild(circle);
const label = new Label();
label.fontName = 'Aileron-Bold';
label.textAlign = 'center';
label.fontColor = '#ffffff';
label.fontSize = 30;
label.text = (i + 1).toString()
label.y = 3;
circle.addChild(label);
// colorRect.addChild(circle);
}
}
getColorRect(rect) {
const colorRect = new ShapeRectNew();
colorRect.setSize(rect.width, rect.height, 1);
colorRect.fillColor = Math.random() < 0.5 ? '#ff0000' : '#00ff00'
// const offX = 13;
colorRect.x = rect.x // + offX;
colorRect.y = rect.y // -rect.height / 2;
// console.log('rect.height: ', rect.height);
// colorRect.alpha = 0;
return colorRect;
}
submitBtn; submitBtn;
...@@ -1653,8 +1850,12 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -1653,8 +1850,12 @@ export class PlayComponent implements OnInit, OnDestroy {
this.convertCanvasToImage(); this.convertCanvasToImage();
// this.hideSubmit(); // this.hideSubmit();
setTimeout(() => { setTimeout(() => {
this.initResultView(); this.setAnswerData(() => {
this.canTouch = true; this.initResultView();
this.canTouch = true;
});
}, 500); }, 500);
}, 500); }, 500);
...@@ -2166,7 +2367,7 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -2166,7 +2367,7 @@ export class PlayComponent implements OnInit, OnDestroy {
setAnswerData() { async setAnswerData(cb) {
let isAllRight = true; let isAllRight = true;
for (let i=0; i<this.hotZoneArr.length; i++) { for (let i=0; i<this.hotZoneArr.length; i++) {
...@@ -2176,23 +2377,26 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -2176,23 +2377,26 @@ export class PlayComponent implements OnInit, OnDestroy {
let answer = this.hotZoneArr[i].label?.text || ''; let answer = this.hotZoneArr[i].label?.text || '';
console.log('data.selectType: ', data.selectType);
console.log('answer: ', answer); console.log('answer: ', answer);
console.log('i: ', i);
// answer = answer.replace(/\n/g," "); // answer = answer.replace(/\n/g," ");
let result; let result;
// if (data.selectType == 'ai') { if (data.selectType == 'ai') {
// this.serverTest(answer); result = await this.serverTest(answer);
result.isAi = true;
// } else { } else {
result = checkAnswer(data.selectType, answer, this.hotZoneArr[i].labelText || null); result = checkAnswer(data.selectType, answer, this.hotZoneArr[i].labelText || null);
// } }
console.log('result: ', JSON.parse(JSON.stringify(result)) );
this.hotZoneArr[i].result = result; this.hotZoneArr[i].result = result;
if (!result.right) { if (!result.right) {
// this.removeRectText( this.hotZoneArr[i] ); // this.removeRectText( this.hotZoneArr[i] );
isAllRight = false; isAllRight = false;
...@@ -2203,48 +2407,61 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -2203,48 +2407,61 @@ export class PlayComponent implements OnInit, OnDestroy {
} }
return isAllRight; cb();
// return isAllRight;
} }
serverTest(text) { async serverTest(text) {
const c = window['courseware'];
if (!c) {
console.error('not found window.courseware')
return;
}
return new Promise((resolve, reject) => {
if (text) { const c = window['courseware'];
if (!c) {
c.greadPapersForText(text, (res) => { console.error('not found window.courseware')
const resData = JSON.parse(res); reject();
const sentsFeedback = resData.detail?.essayFeedback?.sentsFeedback return;
if (sentsFeedback) { }
for (let i=0; i<sentsFeedback.length; i++) {
const {errorPosInfos, rawSent} = sentsFeedback[i];
if (!errorPosInfos || !rawSent) { if (text) {
continue;
} this.iconData = {};
const baseIndex = text.indexOf(rawSent); c.greadPapersForText(text, (res) => {
const resData = JSON.parse(res);
console.log('text: ', text); const sentsFeedback = resData.detail?.essayFeedback?.sentsFeedback
console.log('rawSent: ', rawSent); let startIndex = 0;
console.log('baseIndex: ', baseIndex); if (sentsFeedback) {
for (let j=0; j<errorPosInfos.length; j++) { for (let i=0; i<sentsFeedback.length; i++) {
const {reason, endPos} = errorPosInfos[j]; const {errorPosInfos, rawSent} = sentsFeedback[i];
this.addIconData(baseIndex + endPos, {reason}); if (!errorPosInfos || !rawSent) {
continue;
}
const baseIndex = text.indexOf(rawSent, startIndex);
console.log('text: ', text);
console.log('rawSent: ', rawSent);
console.log('baseIndex: ', baseIndex);
for (let j=0; j<errorPosInfos.length; j++) {
const {reason, endPos} = errorPosInfos[j];
this.addIconData(baseIndex + endPos, {reason});
}
startIndex = baseIndex;
} }
} }
} console.log('res : ', res);
console.log('res : ', res); console.log('iconData : ', this.iconData);
console.log('iconData : ', this.iconData);
this.createResultTextArr(text);
resolve({resultTextArr:this.resultTextArr, iconData: this.iconData});
// this.setComment(resData);
})
}
this.createResultTextArr(text); });
// this.setComment(resData);
})
}
} }
...@@ -2429,12 +2646,11 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -2429,12 +2646,11 @@ export class PlayComponent implements OnInit, OnDestroy {
const arr = this.hotZoneArr; const arr = this.hotZoneArr;
console.log('arr: ', arr);
for (let i=0; i<arr.length; i++) { for (let i=0; i<arr.length; i++) {
console.log('i: ', i);
console.log('arr[i]: ', arr[i]);
if (arr[i].data.gIdx == '0') { if (arr[i].data.gIdx == '0') {
if (!arr[i].label || !arr[i].label.text || arr[i].label.isDefault) { if (!arr[i].label || !arr[i].label.text || arr[i].label.isDefault) {
this.hideSubmit(); this.hideSubmit();
...@@ -2955,6 +3171,7 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -2955,6 +3171,7 @@ export class PlayComponent implements OnInit, OnDestroy {
const rectLabel = this.getFillLabel(); const rectLabel = this.getFillLabel();
rectLabel.topH = 8;
rectLabel.fontSize = this.inputFontSize; rectLabel.fontSize = this.inputFontSize;
rectLabel.disH = 0; rectLabel.disH = 0;
rectLabel.offW = 0; rectLabel.offW = 0;
......
...@@ -32,6 +32,8 @@ const res = [ ...@@ -32,6 +32,8 @@ const res = [
['info_icon', "assets/play/info_icon.png"], ['info_icon', "assets/play/info_icon.png"],
['info_bg', "assets/play/info_bg.png"], ['info_bg', "assets/play/info_bg.png"],
['ai_icon', "assets/play/ai_icon.png"],
]; ];
...@@ -42,6 +44,8 @@ const resAudio = [ ...@@ -42,6 +44,8 @@ const resAudio = [
['submit', "assets/play/music/submit.mp3"], ['submit', "assets/play/music/submit.mp3"],
['more', "assets/play/music/more.mp3"], ['more', "assets/play/music/more.mp3"],
]; ];
export {res, resAudio}; export {res, resAudio};
......
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