How to find start and end points of filltext in canvas - javascript

Hey there how am i going to find the start and end point of a canvas
i have created a letter like this on a canvas
var centerx = (c.width - cx.measureText(letter).width) / 2;
var centery = c.height / 2;
console.log("Bilawal");
console.log(cx.measureText(letter));
var lines = letter.split('\n');
var lineheight = 20;
//for (var i = 0; i<lines.length; i++)
//cx.fillText(lines[i], centerx, centery + (i*lineheight) );
console.log("X "+centerx+" Y "+centery);
cx.fillText(letter, centerx, centery);
now i dont know how to find the start X,Y and end X,Y

You asked for a code sample. Below I have included the same math. Hope this helps.
var centerx = (c.width - cx.measureText(letter).width) / 2;
var centery = c.height / 2;
console.log("Bilawal");
console.log(cx.measureText(letter));
var lines = letter.split('\n');
var lineheight = 20;
//for (var i = 0; i<lines.length; i++)
//cx.fillText(lines[i], centerx, centery + (i*lineheight) );
console.log("X "+centerx+" Y "+centery);
cx.fillText(letter, centerx, centery);
startx = centerx;
starty = centery - 10;
endx = (c.width / 2) + (cx.measureText(letter).width / 2);
endy = centery + 10;
Start and end for each letter as you asked. Once it runs you can access the array of COORDS "startsEnds". If the space between the letters is to large drop the spacer value.
function COORD(sx,sy,ex,ey) {
this.startX = sx;
this.startY = sy;
this.endX = ex;
this.endY = ey;
}
var startsEnds = [];
var spacer = 1;
var centerx = (c.width - cx.measureText(letter).width) / 2;
var centery = c.height / 2;
console.log("Bilawal");
console.log(cx.measureText(letter));
console.log("X "+centerx+" Y "+centery);
var lines = letter.split('\n');
var lineheight = 20;
//for (var i = 0; i<lines.length; i++)
//cx.fillText(lines[i], centerx, centery + (i*lineheight) );
var lett = letter.split("");
var newCenterX = centerx;
var newCenterY = centery;
for (var i = 0; i < lett.length; i++){
console.log("X "+newCenterX+" Y "+newCenterY );
var startEnd = new COORD(newCenterX,newCenterY - 10,(c.width / 2) + (cx.measureText(lett[i]).width / 2), newCenterY + 10);
startsEnds.push(startEnd);
newCenterX = newCenterX + cx.measureText(lett[i]) + spacer;
}
cx.fillText(letter, centerx, centery);

Related

Is this possible to draw a full circle involing cot or tan?

I have a code like this to draw multiple points into a circle
var cxt=c.getContext("2d");
var centerX = 500;
var centerY = 500;
cxt.moveTo(centerX, centerY);
var increment = 1/100;
var distance = 100;
for( theta=0;theta <100; theta++) {
var newX = centerX +distance *Math.cos(theta*2*Math.PI*increment);
var newY = centerY +distance *Math.sin(theta*2*Math.PI*increment);
cxt.fillText("0",newX, newY);
}
cxt.stroke();
Outcome:
enter image description here
I try to rewote the code with tan & cot (1/tan)but what i get usually an eclipse or oval. Can we use these function to make a perfect circle out of given points?
Yes, this is possible - the tan is enough (formulas here)
var cxt = c.getContext("2d");
var centerX = 100;
var centerY = 100;
cxt.moveTo(centerX, centerY);
var increment = 1 / 50;
var distance = 90;
for (let theta = 0; theta < 100; theta++) {
var t = Math.tan(theta * Math.PI * increment);
var newX = centerX + distance * (1 - t*t)/(1 + t*t);
var newY = centerY + distance * 2 * t/(1 + t*t);
cxt.fillText("0", newX, newY);
}
cxt.stroke();
<canvas id=c width=200 height=200></canvas>

Project an image onto an elliptic cylinder

I have a flat image that I want to transform so it looks like a projection on an elliptic cylinder.
I've found the great script from Blindman67 for a regular cylinder at https://stackoverflow.com/a/40999097/4273683
However I don't understand, how to change the script to get an elliptic result. Any idea?
Thanks a lot for help.
var createImage=function(w,h){var i=document.createElement("canvas");i.width=w;i.height=h;i.ctx=i.getContext("2d");return i;}
var canvas = createImage(400,400);
var ctx = canvas.ctx;
document.body.appendChild(canvas)
ctx.clearRect(0,0,500,500)
var image = createImage(400,200);
image.ctx.font = "60px arial";
image.ctx.textAlign = "center";
image.ctx.fillStyle = "#7F5";
image.ctx.fillRect(0,0,image.width,image.height)
image.ctx.fillStyle = "white";
image.ctx.fillText("Wrap around",200,60)
image.ctx.fillText("Some images",200,140)
function draw(ang,tilt, perspective){
var step = 1/(Math.max(image.width,400));
for(var i = 0; i < 1; i += step){
var a = i * Math.PI;
var a1 = (i+ step*2) * Math.PI ;
var ix = i * image.width*1.2;
var iw = step * image.width*1.2;
a += ang * Math.PI * 2;
a1 += ang * Math.PI * 2;
a = Math.PI -a;
a1 = Math.PI -a1;
var x = canvas.width * 0.5;
var y = canvas.height * 0.1;
var x1 = x + Math.cos(a1) * 110;
var y1 = y + Math.sin(a) * tilt;
x += Math.cos(a) * 110;
y += Math.sin(a) * tilt;
var s = Math.sin(a);
var s1 = Math.sin(a1);
if(s > 0 || s1 > 0){
ctx.drawImage(image,ix,0,iw,image.height,x1,y- s * perspective*0.5,x-x1,200 + s * perspective)
}
}
}
var w = canvas.width;
var h = canvas.height;
// main update function
function update(timer){
ctx.setTransform(1,0,0,1,0,0); // reset transform
ctx.globalAlpha = 1; // reset alpha
ctx.fillStyle = "black"
ctx.fillRect(0,0,w,h);
draw(timer / 2000, 40,30)
requestAnimationFrame(update);
}
requestAnimationFrame(update);

Why isn't my program drawing anything?

I made this program that will hopefully draw a cool shape based on the sliders. The problem is, nothing is showing up other than the sliders! Why is this?
var aslider, lslider, sslider, newx, newy;
function setup() {
createCanvas(300,300);
aslider = createSlider(1,359,17);
lslider = createSlider(1,50,10);
sslider = createSlider(1,50,20);
}
function draw() {
var angle = aslider.value();
var length = lslider.value();
var size = sslider.value();
var startx = width / 2;
var starty = height / 2;
var radians = angle * (Math.PI/180);
for (var i = 0; i++; i < size) {
newx = startx * Math.sin(radians) + starty * Math.cos(radians);
newy = startx * Math.sin(radians) + starty * -Math.cos(radians);
line(startx, starty, newx, newy);
startx = newx;
starty = newy;
}
}
Your for loop is wrong. It should be
for (var i = 0; i < size; i++)
I tested it here: http://codepen.io/eerk/pen/wgOZVW?editors=1010

How not to make the canvas flash when i call clearRect [duplicate]

I've a screen being redraw every 25ms, and images are flickering, here is my code
var FRAME_RATE = 40;
var intervalTime = 1000/FRAME_RATE;
gameLoop();
function gameLoop(){
context.clearRect(0, 0, 640, 640);
renderMap();
window.setTimeout(gameLoop, intervalTime);
}
and here is renderMap() function
function renderMap(){
var startX = playerX - (screenW / 2);
var startY = playerY - (screenH / 2);
maxX = playerX + (screenW / 2);
maxY = playerY + (screenH / 2);
$.getJSON('mapa3.json', function(json){
for (x = startX; x < maxX; x=x+32){
for (y = startY; y < maxY; y=y+32){
intTile = json.layers[0].data[((y/32)* 100) + (x/32)];
context.putImageData(getTile(intTile - 1), x - startX, y - startY);
}
}
});
var imgCharacter = new Image();
imgCharacter.src = 'char.png';
var posX = (screenW - imgCharacter.width) / 2;
var posY = (screenH - imgCharacter.height) / 2;
imgCharacter.onload = function(){context.drawImage(imgCharacter, posX, posY)}
}
What changes do I need to make to the code to stop flickering?
I believe it is because you are loading the image each iteration. Try putting the var imgCharacter..., the following line, and the image's onload function outside of renderMap so it is only ran once
var imgCharacter = new Image();
imgCharacter.onload = function () {
renderMap();
}
imgCharacter.src = 'char.png';
function renderMap() {
var startX = playerX - (screenW / 2);
var startY = playerY - (screenH / 2);
maxX = playerX + (screenW / 2);
maxY = playerY + (screenH / 2);
$.getJSON('mapa3.json', function (json) {
for (x = startX; x < maxX; x = x + 32) {
for (y = startY; y < maxY; y = y + 32) {
intTile = json.layers[0].data[((y / 32) * 100) + (x / 32)];
context.putImageData(getTile(intTile - 1), x - startX, y - startY);
}
}
});
var posX = (screenW - imgCharacter.width) / 2;
var posY = (screenH - imgCharacter.height) / 2;
context.drawImage(imgCharacter, posX, posY)
}
Thank you to markE for letting me know the onload function also needs to go outside renderMap, I overlooked it the first time
Load all images and other data before draw and storage them inside array.
Better use requestAnimationFrame.
Remember, getting JSON (or other data) can take some time.

redrawing canvas html5 without flickering

I've a screen being redraw every 25ms, and images are flickering, here is my code
var FRAME_RATE = 40;
var intervalTime = 1000/FRAME_RATE;
gameLoop();
function gameLoop(){
context.clearRect(0, 0, 640, 640);
renderMap();
window.setTimeout(gameLoop, intervalTime);
}
and here is renderMap() function
function renderMap(){
var startX = playerX - (screenW / 2);
var startY = playerY - (screenH / 2);
maxX = playerX + (screenW / 2);
maxY = playerY + (screenH / 2);
$.getJSON('mapa3.json', function(json){
for (x = startX; x < maxX; x=x+32){
for (y = startY; y < maxY; y=y+32){
intTile = json.layers[0].data[((y/32)* 100) + (x/32)];
context.putImageData(getTile(intTile - 1), x - startX, y - startY);
}
}
});
var imgCharacter = new Image();
imgCharacter.src = 'char.png';
var posX = (screenW - imgCharacter.width) / 2;
var posY = (screenH - imgCharacter.height) / 2;
imgCharacter.onload = function(){context.drawImage(imgCharacter, posX, posY)}
}
What changes do I need to make to the code to stop flickering?
I believe it is because you are loading the image each iteration. Try putting the var imgCharacter..., the following line, and the image's onload function outside of renderMap so it is only ran once
var imgCharacter = new Image();
imgCharacter.onload = function () {
renderMap();
}
imgCharacter.src = 'char.png';
function renderMap() {
var startX = playerX - (screenW / 2);
var startY = playerY - (screenH / 2);
maxX = playerX + (screenW / 2);
maxY = playerY + (screenH / 2);
$.getJSON('mapa3.json', function (json) {
for (x = startX; x < maxX; x = x + 32) {
for (y = startY; y < maxY; y = y + 32) {
intTile = json.layers[0].data[((y / 32) * 100) + (x / 32)];
context.putImageData(getTile(intTile - 1), x - startX, y - startY);
}
}
});
var posX = (screenW - imgCharacter.width) / 2;
var posY = (screenH - imgCharacter.height) / 2;
context.drawImage(imgCharacter, posX, posY)
}
Thank you to markE for letting me know the onload function also needs to go outside renderMap, I overlooked it the first time
Load all images and other data before draw and storage them inside array.
Better use requestAnimationFrame.
Remember, getting JSON (or other data) can take some time.

Categories