Copy link to clipboard
Copied
hi,
in flash cs using as3 to find the position of a character we used getCharBoundaries(index).x is it possible to find a character of a label.innerHTML using adobe animate html5 canvas?? thanks.
create a movieclip that contains a textfield. right align the text if you're going to use right-to-left language like arabic, left align the text for left-to-right languages. assign the textfield an instance name, eg tf. assign the movieclip a linkage id, eg tf_mc.
your can then use:
// [word or phrase to be display, character index where bin should be placed for a correct answer]var wordA = [["first word",2],["second word",5]];
var index,i,mc;
// add your drag and drop listeners. bind(
...Copy link to clipboard
Copied
you can use textmetrics, https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics
eg,
this.tf.text = "ab cd ef gh ij kl mn"; // tf is on stage textfield;
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
var tm = ctx.measureText("a");
console.log(tm.width,tm.actualBoundingBoxLeft,tm.actualBoundingBoxRight);
tm = ctx.measureText("mn");
console.log(tm.width,tm.actualBoundingBoxLeft,tm.actualBoundingBoxRight);
Copy link to clipboard
Copied
there's no way to finding Bounds() for letter in the text without split it ??
Copy link to clipboard
Copied
there might be but it would take significantly more time, for me, to develop.
can you answer : if letters are connected, how do arabic typewriters work? eg, if you type (in arabic ) a letter you would see one kind of glyph and then if you type another, the first glyph has to change, doesn't it?
Copy link to clipboard
Copied
yes, when we type ع and then ن the first letter change to عن then عنك and then عنكب then عنكبو and so on
Copy link to clipboard
Copied
Not by any reasonable means, no. If you want the position of an individual character, you have to make the character an individual object.
Copy link to clipboard
Copied
unfortunately,it's an impractical solution because there is alot of words inside the website also it's an arabic words the width changed when the letter inside the word or it inside an individual object
Copy link to clipboard
Copied
Hi.
This is just a suggestion that I hope will help you to get started.
It doesn't work perfectly with arabic texts unfortunately. This is because in arabic texts two (or more?) letters are usually combined together and this makes the calculations very hard.
Special characters may overflow as well.
It's not the most efficient way of doing this and also the bounding boxes will need some workaround to remain invisible.
Again, I just want to provide a sample of what it is possible by only using the CreateJS API. Maybe it's possible to do more using the canvas API.
Try it:
https://bit.ly/3WEJHtm
Javascript:
[Global script]:
(function()
{
window.ui = {};
// text boxes
ui.TextBoxes = function(target)
{
this.target = target;
this.setBoundingBoxes();
}
ui.TextBoxes.prototype.setBoundingBoxes = function()
{
var originalText = this.target.text;
var originalMetrics = this.target.getMetrics();
var currentWidth = originalMetrics.width;
var lines = originalMetrics.lines;
var totalLines = lines.length;
var lettersWidthSum = 0;
var totalLinesLetters, letterMetrics, i, j;
var boundingBox = {};
var alignOffset = this.getAlignmentOffset(this.target);
this.target.text = "";
this.target.boundingBoxes = [];
for (i = 0; i < totalLines; i++)
{
totalLinesLetters = lines[i].length;
lettersWidthSum = 0;
this.target.text = lines[i];
currentWidth = this.target.getMetrics().width;
for (j = 0; j < totalLinesLetters; j++)
{
this.target.text = lines[i][j];
letterMetrics = this.target.getMetrics();
boundingBox = this.drawBoundingBox(letterMetrics.width, letterMetrics.height);
boundingBox.x = this.target.x + lettersWidthSum - currentWidth * alignOffset;
boundingBox.y = this.target.y + letterMetrics.lineHeight * i;
boundingBox.setBounds(boundingBox.x, boundingBox.y, letterMetrics.width, letterMetrics.height);
boundingBox.alpha = 0.2;
boundingBox.tf = this.target;
this.target.parent.addChild(boundingBox);
lettersWidthSum += letterMetrics.width;
this.target.boundingBoxes.push(boundingBox);
}
}
this.target.text = originalText;
};
ui.TextBoxes.prototype.drawBoundingBox = function(width, height)
{
var shape = new createjs.Shape();
shape.graphics.beginFill("rgba(255,255,255,0.1)");
shape.graphics.beginStroke("rgba(255,255,255,1)");
shape.graphics.setStrokeStyle(1);
shape.graphics.drawRect(0, 0, width, height);
shape.graphics.endFill();
shape.graphics.endStroke();
return shape;
}
ui.TextBoxes.prototype.getAlignmentOffset = function()
{
if (this.target.textAlign === "left")
return 0;
if (this.target.textAlign === "center")
return 0.5;
if (this.target.textAlign === "right")
return 1;
};
ui.TextBoxes.prototype.destroy = function()
{
if (!this.target.boundingBoxes)
return;
this.target.boundingBoxes.forEach(function(boundingBox)
{
boundingBox.parent.removeChild(boundingBox);
boundingBox._off = true;
});
delete this.target.boundingBoxes;
};
// drag and drop
ui.DragAndDrop = function(target, callbacks)
{
this.target = target;
this.callbacks = callbacks || {};
this.mouseDownListener = this.target.on("mousedown", this.onMouseDown, this);
this.pressMoveListener = this.target.on("pressmove", this.onPressMove, this);
this.pressUpListener = this.target.on("pressup", this.onPressUp, this);
};
ui.DragAndDrop.prototype.onMouseDown = function(e)
{
var pointer = this.getPointer(this.target);
this.target.offset = { x: pointer.x - this.target.x, y: pointer.y - this.target.y };
this.target.parent.addChild(this.target);
if (this.callbacks.onMouseDown)
this.callbacks.onMouseDown.call(this);
};
ui.DragAndDrop.prototype.onPressMove = function(e)
{
var pointer = this.getPointer(this.target);
this.target.x = pointer.x - this.target.offset.x;
this.target.y = pointer.y - this.target.offset.y;
if (this.callbacks.onPressMove)
this.callbacks.onPressMove.call(this);
};
ui.DragAndDrop.prototype.onPressUp = function(e)
{
if (this.callbacks.onPressUp)
this.callbacks.onPressUp.call(this);
};
ui.DragAndDrop.prototype.getPointer = function(target)
{
return target.parent.globalToLocal(target.stage.mouseX, target.stage.mouseY);
};
ui.DragAndDrop.prototype.destroy = function()
{
this.target.off("mousedown", this.mouseDownListener);
this.target.off("pressmove", this.pressMoveListener);
this.target.off("pressup", this.pressUpListener);
delete this.target;
delete this.callbacks;
};
})();
[Frame 0 of main timeline]:
// the TextBoxes and DragAndDrop classes are located in the globa script section (left sections)
var callbacks =
{
onMouseDown: function()
{
this.target.mouseEnabled = false;
},
onPressUp: function()
{
var box = this.currentBoundingBox;
this.target.mouseEnabled = true;
if (box && box.correct !== undefined)
{
drawBoundingBox(box);
this.target.x = box.x + box.getBounds().width * 0.5;
this.target.y = box.y - this.target.nominalBounds.height * 0.5;
box.tf.dragAndDrop.destroy();
box.tf.textBoxes.destroy();
box = null;
}
else
{
this.target.x = this.target.initialX;
this.target.y = this.target.initialY;
}
}
};
function main()
{
var resetTarget0 = { tf: root.tf0, bin: root.bin0, correct: 1, slot: root.slot0 };
var resetTarget1 = { tf: root.tf1, bin: root.bin1, correct: 0, slot: root.slot1 };
var resetTarget2 = { tf: root.tf2, bin: root.bin2, correct: 2, slot: root.slot2 };
setup();
setGame(root.tf0, root.bin0, 1, root.slot0);
setGame(root.tf1, root.bin1, 0, root.slot1);
setGame(root.tf2, root.bin2, 2, root.slot2);
root.resetButton0.on("click", onReset, null, false, resetTarget0);
root.resetButton1.on("click", onReset, null, false, resetTarget1);
root.resetButton2.on("click", onReset, null, false, resetTarget2);
root.resetAllButton.on("click", onResetAll, null, false, { targets: [ resetTarget0, resetTarget1, resetTarget2 ] });
}
function setup()
{
document.body.style.backgroundColor = lib.properties.color;
createjs.Touch.enable(stage);
stage.enableMouseOver(50);
stage.mouseMoveOutside = true;
root.stop();
}
function setGame(tf, bin, correct, slot)
{
tf.textBoxes = new ui.TextBoxes(tf);
tf.boundingBoxes[correct].correct = true;
tf.boundingBoxes.forEach(function(boundingBox)
{
boundingBox.mouseOverListener = boundingBox.on("mouseover", onMouseOver);
boundingBox.mouseOutListener = boundingBox.on("mouseout", onMouseOut);
});
tf.dragAndDrop = new ui.DragAndDrop(bin, callbacks);
bin.initialX = slot.x;
bin.initialY = slot.y;
}
function onMouseOver(e)
{
e.currentTarget.alpha = 1;
e.currentTarget.tf.dragAndDrop.currentBoundingBox = e.currentTarget;
}
function onMouseOut(e)
{
e.currentTarget.alpha = 0.2;
e.currentTarget.tf.dragAndDrop.currentBoundingBox = null;
}
function drawBoundingBox(box)
{
box.tf.winBox = new createjs.Shape();
box.tf.winBox.graphics.beginFill("rgba(255,255,255,0.5)");
box.tf.winBox.graphics.beginStroke("white");
box.tf.winBox.graphics.setStrokeStyle(2);
box.tf.winBox.graphics.drawRect(0, 0, box.getBounds().width, box.getBounds().height);
box.tf.winBox.graphics.endFill();
box.tf.winBox.graphics.endStroke();
box.tf.winBox.x = box.x;
box.tf.winBox.y = box.y;
box.tf.parent.addChild(box.tf.winBox);
}
function onReset(e, data)
{
if (data.tf.dragAndDrop.target)
data.tf.dragAndDrop.destroy();
if (data.tf.textBoxes.target)
data.tf.textBoxes.destroy();
root.addChild(data.bin);
data.bin.x = data.slot.x;
data.bin.y = data.slot.y;
if (data.tf.winBox && data.tf.winBox.parent)
{
data.tf.winBox.parent.removeChild(data.tf.winBox);
data.tf.winBox._off = true;
}
setGame(data.tf, data.bin, data.correct, data.slot);
}
function onResetAll(e, data)
{
data.targets.forEach(function(target){ onReset(null, target); });
}
if (!this.frame0started)
{
window.root = this;
main();
this.frame0started = true;
}
Code / FLA / files / source:
https://bit.ly/3BWEx3S
I hope it helps.
Regards,
JC
Copy link to clipboard
Copied
thank's alot 🙂