Related
It is my first day using javascript.
I am trying to start with a simple task is to add a sin-wave to the plot then remove it. (The remove function does NOT work but, the add function does work)
I am also trying to use a slide bar to change the frequency of the wave
'''
<script crossorigin src="https://unpkg.com/react#18/umd/react.production.min.js">
</script>
<script crossorigin src="https://unpkg.com/react-dom#18/umd/react-
dom.production.min.js"></script>
<script src="https://unpkg.com/#babel/standalone/babel.min.js"></script>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id="tester" style="width:600px;height:250px;"></div>
<div><button onclick="create_sin()">add</button></div>
<div><button onclick="remove()">remove</button></div>
<div class="slidecontainer">
<input type="range" min="1" max="100" value="50" class="slider" id="myRange">
</div>
</body>
<script>
var x1 = []
var y1 = []
//fill the arrays of the sin wave
function create_sin() {
if (x1.length != 0) { return }
var screen_size = 40
var period = 4
var freq = 1 / period
var omega = 2 * Math.PI * freq
var step_size = 4 / screen_size
var counter = 0
while (counter <= 40) {
x1.push(counter)
y1.push(Math.sin(omega * counter))
counter = counter + step_size
}
Plotly.redraw(TESTER)
}
function remove() {
x1 = []
y1 = []
Plotly.redraw(TESTER)
}
TESTER = document.getElementById('tester')
Plotly.newPlot(TESTER, [{
x: x1,
y: y1,
line: { shape: 'spline' },
}], {
margin: { t: 0 }
})
</script>
</html>
'''
I'm trying to make a colour selector in JavaScript, so far it works (in Firefox, not chrome) if you select a value in the slider and then refresh the page - displaying the colour in a HTML tag.
However, I want it to refresh the colour real-time, so that the canvas changes colour as you adjust the sliders. I imagine I've made a really simple error, but I just can't figure it out - I would very much appreciate any help/advice!
Example of code on my web page.
I've messed around with using .onchange etc, plus declaring "outputR.value" in the rbg() call, but none of this works. I imagine I need an update function - but I'm not sure where to even start on that.
var sliderR = document.getElementById("myRangeR");
var sliderG = document.getElementById("myRangeG");
var sliderB = document.getElementById("myRangeB");
var outputR = document.getElementById("demoR");
var outputG = document.getElementById("demoG");
var outputB = document.getElementById("demoB");
sliderR.oninput = function() {
outputR.innerHTML = this.value;
}
sliderG.oninput = function() {
outputG.innerHTML = this.value;
}
sliderB.oninput = function() {
outputB.innerHTML = this.value;
}
outputR.innerHTML = sliderR.value;
outputG.innerHTML = sliderG.value;
outputB.innerHTML = sliderB.value;
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb("+sliderR.value+","+sliderG.value+","+sliderB.value+")";
ctx.fillRect(0, 0, 80, 80);
<p>
<div class="slidecontainer">
<p>Red: <span id="demoR"></span>/255</p>
<input type="range" min="0" max="255" value="128" class="slider" id="myRangeR">
<p>Green: <span id="demoG"></span>/255</p>
<input type="range" min="0" max="255" value="128" class="slider" id="myRangeG">
<p>Blue: <span id="demoB"></span>/255</p>
<input type="range" min="0" max="255" value="128" class="slider" id="myRangeB">
<canvas id="myCanvas"></canvas>
</div>
</p>
<script src="js/canvastest.js"></script>
Expected: HTML canvas element changes colour when sliders are moved.
Actual: Colours only change when page is refreshed (in Firefox), or not at all (chrome).
I'm not seeing a point in which you update the canvas itself. You would want to update the canvas when the value changes such as:
ctx.fillStyle = "rgb(" + [outputR, outputG, outputB].join(', ') + ")";
then rerender with ctx.fillRect(0, 0, 80, 80);.
This would give you something like the following:
var sliderR = document.getElementById("myRangeR");
var sliderG = document.getElementById("myRangeG");
var sliderB = document.getElementById("myRangeB");
var outputR = document.getElementById("demoR");
var outputG = document.getElementById("demoG");
var outputB = document.getElementById("demoB");
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
sliderR.oninput = function() {
outputR.innerHTML = this.value;
updateRect();
}
sliderG.oninput = function() {
outputG.innerHTML = this.value;
updateRect();
}
sliderB.oninput = function() {
outputB.innerHTML = this.value;
updateRect();
}
outputR.innerHTML = sliderR.value;
outputG.innerHTML = sliderG.value;
outputB.innerHTML = sliderB.value;
function updateRect() {
ctx.fillStyle = "rgb(" + [outputR, outputG, outputB].map(i => i.innerHTML).join(', ') + ")";
ctx.fillRect(0, 0, 80, 80);
}
updateRect();
st.js
First things first, you should not enclose your div or another p inside <p> tag. It's wrong structurally.
Now coming to your question, it is not re-rendering as the script is only getting executed on page load.
Try something like this:
var sliderR = document.getElementById("myRangeR");
var sliderG = document.getElementById("myRangeG");
var sliderB = document.getElementById("myRangeB");
var outputR = document.getElementById("demoR");
var outputG = document.getElementById("demoG");
var outputB = document.getElementById("demoB");
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
myfunc = () => {
outputR.innerHTML = sliderR.value;
outputG.innerHTML = sliderG.value;
outputB.innerHTML = sliderB.value;
ctx.fillStyle = "rgb("+sliderR.value+","+sliderG.value+","+sliderB.value+")";
ctx.fillRect(0, 0, 80, 80);
}
myfunc(); // for initialising values on first load
<div>
<div class="slidecontainer">
<p>Red: <span id="demoR"></span>/255</p>
<input type="range" min="0" max="255" value="128" class="slider" id="myRangeR" oninput="myfunc()" >
<p>Green: <span id="demoG"></span>/255</p>
<input type="range" min="0" max="255" value="128" class="slider" id="myRangeG" oninput="myfunc()">
<p>Blue: <span id="demoB"></span>/255</p>
<input type="range" min="0" max="255" value="128" class="slider" id="myRangeB" oninput="myfunc()">
<canvas id="myCanvas"></canvas>
</div>
</div>
Hope it helps!
I'm trying to figure out how to reproduce the behavior of the "border-radius" css property into an HTML canvas.
So i've already done something in Javascript in order to compute the correct borders of a given shape, using a specific radius (for each corner).
Here is the previous question if needed : Gecko - CSS layout border radius - Javascript conversion
I've managed to get close from the browser adaptation but there's still an issue, and it seems that it's the last, and the hard part!
Let's take an example in order to explain you the problem
Take a shape of 100px width & 100px height. Now apply the following radius to each corner :
Top left : 37px
Top right : 100px
Bottom right : 1px
Bottom left : 100px
So the css style for this will be border-radius : 37px 100px 1px 100px
Now let's consider using the code below in order to draw this shape in a canvas.
By using the function correctRadius(r, w, h) in order to avoid bad shapes, each corners will be computed like that :
=> {tl: 18.5, tr: 81.5, br: 0.5, bl: 81.5}
Here is a visual of this :
You will be able to test it in the following snippet
As you can see, the browser shape (green) is overlapped with the canvas shape (brown + 'pink' due to opacity). I've put some opacity on it in order to check the bad corners (pink).
The brown shape do not fit properly into the green shape, the top left corner is getting out of the base, and the bottom left and top right corners don't fit the green shape.
I've already tried to fix that but with no success, and also looked the sources of the Gecko layout engine (https://github.com/mozilla/gecko-dev) in this file : layout/painting/nsCSSRenderingBorders.cpp, but haven't found anything + i have no skills in C++
If anyone could help me to figure this out, or give me some advice, i'll be able to fix this and get the borders working
// Ctx
var ctx = document.getElementById("rounded-rect").getContext("2d");
ctx.translate(0, 0);
function correctRadius(r, w, h) {
var tl = r.tl;
var tr = r.tr;
var br = r.br;
var bl = r.bl;
r.tl -= Math.max(Math.max((tl + tr - w) / 2, 0),
Math.max((tl + bl - h) / 2, 0));
r.tr -= Math.max(Math.max((tr + tl - w) / 2, 0),
Math.max((tr + br - h) / 2, 0));
r.br -= Math.max(Math.max((br + bl - w) / 2, 0),
Math.max((br + tr - h) / 2, 0));
r.bl -= Math.max(Math.max((bl + br - w) / 2, 0),
Math.max((bl + tl - h) / 2, 0));
}
//Round rect func
ctx.constructor.prototype.fillRoundedRect =
function(xx, yy, ww, hh, rad, fill, stroke) {
correctRadius(rad, ww, hh);
if (typeof(rad) === "undefined") rad = 5;
this.beginPath();
this.moveTo(xx, yy);
this.arcTo(xx + ww, yy, xx + ww, yy + hh, rad.tr);
this.arcTo(xx + ww, yy + hh, xx, yy + hh, rad.br);
this.arcTo(xx, yy + hh, xx, yy, rad.bl);
this.arcTo(xx, yy, xx + ww, yy, rad.tl);
if (stroke) this.stroke(); // Default to no stroke
if (fill || typeof(fill) === "undefined") this.fill(); // Default to fill
};
ctx.fillStyle = "red";
ctx.strokeStyle = "#ddf";
var copy = document.getElementById('copy');
var tl = document.getElementById('tl');
var tr = document.getElementById('tr');
var bl = document.getElementById('bl');
var br = document.getElementById('br');
var last = [];
setInterval(function() {
/* 1.Top left */
/* 2. Top right */
/* 3. Bottom right */
/* 4. Bottom left */
var bordersCSSProps = [
"border-top-left-radius",
"border-top-right-radius",
"border-bottom-right-radius",
"border-bottom-left-radius"
],
elementBorders = [],
elementStyle = getComputedStyle(copy);
var changed = false;
for (var i = 0; i < 4; ++i) {
elementBorders[i] = elementStyle.getPropertyValue(bordersCSSProps[i]);
if (elementBorders[i] !== last[i]) {
changed = true;
last[i] = elementBorders[i];
}
}
if (changed) {
var borders = [].concat(elementBorders).map(function(a) {
return parseInt(a)
});
var rad = {
tl: borders[0],
tr: borders[1],
br: borders[2],
bl: borders[3]
};
ctx.clearRect(0, 0, 600, 500);
ctx.fillRoundedRect(120, 120, 100, 100, rad);
}
}, 1E3 / 60);
function elemBordersSet() {
var borders = [tl.value, tr.value, br.value, bl.value].join('px ') + 'px';
copy.style.borderRadius = borders;
}
tl.oninput = elemBordersSet;
tr.oninput = elemBordersSet;
bl.oninput = elemBordersSet;
br.oninput = elemBordersSet;
html,
body {
margin: 0;
padding: 0;
}
<div style="display:inline-block; position: absolute;
left:120px;top:120px; width: 100px; height: 100px; background:green;
border-radius: 100px 49px 1px 1px;" id="copy">
</div>
<canvas style="opacity:0.5; z-index:1; display: inline-block; position: absolute; left:0; top:0;" id="rounded-rect" width="600" height="500">
</canvas>
<div style="margin-top:250px; position:absolute; z-index:5">
<label>
Top left
<input type="range" min="1" max="100" value="0" class="slider" id="tl"></label><br/>
<label>
Top right
<input type="range" min="1" max="100" value="0" class="slider" id="tr"></label><br/>
<label>
Bottom left
<input type="range" min="1" max="100" value="0" class="slider" id="bl"></label><br/>
<label>
Bottom right
<input type="range" min="1" max="100" value="0" class="slider" id="br"></label><br/>
</div>
Found the solution !
We just need to compute a scaleRatio :
First, we get the maxRadiusWidth (r.tl + r.tr, r.bl + r.br) & maxRadiusHeight (r.tl + r.bl, r.tr + r.br)
and then a widthRatio = (w / maxRadiusWidth) & heightRatio = (h / maxRadiusHeight) with the size of the shape (WIDTH & HEIGHT)
Then we take the lower of theses two variables : Math.min(Math.min(widthRatio, heightRatio), 1) in order to not get out of the shape & we make sure that
the ratio is below 1.
Finally, we simply need to multiply each corner by this ratio in order to get the correct size !
r.tl = tl*scaleRatio;
r.tr = tr*scaleRatio;
r.br = br*scaleRatio;
r.bl = bl*scaleRatio;
See snippet below ;)
// Ctx
var ctx = document.getElementById("rounded-rect").getContext("2d");
ctx.translate(0, 0);
function correctRadius(r, w, h) {
var
maxRadiusWidth = Math.max(r.tl + r.tr, r.bl + r.br),
maxRadiusHeight = Math.max(r.tl + r.bl, r.tr + r.br),
widthRatio = w / maxRadiusWidth,
heightRatio = h / maxRadiusHeight,
scaleRatio = Math.min(Math.min(widthRatio, heightRatio), 1);
for (var k in r)
r[k] = r[k] * scaleRatio;
}
//Round rect func
ctx.constructor.prototype.fillRoundedRect =
function(xx, yy, ww, hh, rad, fill, stroke) {
correctRadius(rad, ww, hh);
if (typeof(rad) === "undefined") rad = 5;
this.beginPath();
this.moveTo(xx, yy);
this.arcTo(xx + ww, yy, xx + ww, yy + hh, rad.tr);
this.arcTo(xx + ww, yy + hh, xx, yy + hh, rad.br);
this.arcTo(xx, yy + hh, xx, yy, rad.bl);
this.arcTo(xx, yy, xx + ww, yy, rad.tl);
if (stroke) this.stroke(); // Default to no stroke
if (fill || typeof(fill) === "undefined") this.fill(); // Default to fill
};
ctx.fillStyle = "red";
ctx.strokeStyle = "#ddf";
var copy = document.getElementById('copy');
var tl = document.getElementById('tl');
var tr = document.getElementById('tr');
var bl = document.getElementById('bl');
var br = document.getElementById('br');
var last = [];
setInterval(function() {
/* 1.Top left */
/* 2. Top right */
/* 3. Bottom right */
/* 4. Bottom left */
var bordersCSSProps = [
"border-top-left-radius",
"border-top-right-radius",
"border-bottom-right-radius",
"border-bottom-left-radius"
],
elementBorders = [],
elementStyle = getComputedStyle(copy);
var changed = false;
for (var i = 0; i < 4; ++i) {
elementBorders[i] = elementStyle.getPropertyValue(bordersCSSProps[i]);
if (elementBorders[i] !== last[i]) {
changed = true;
last[i] = elementBorders[i];
}
}
if (changed) {
var borders = [].concat(elementBorders).map(function(a) {
return parseInt(a)
});
var rad = {
tl: borders[0],
tr: borders[1],
br: borders[2],
bl: borders[3]
};
ctx.clearRect(0, 0, 600, 500);
ctx.fillRoundedRect(120, 120, 100, 200, rad);
}
}, 1E3 / 60);
function elemBordersSet() {
var borders = [tl.value, tr.value, br.value, bl.value].join('px ') + 'px';
copy.style.borderRadius = borders;
}
tl.oninput = elemBordersSet;
tr.oninput = elemBordersSet;
bl.oninput = elemBordersSet;
br.oninput = elemBordersSet;
<div style="display:inline-block; position: absolute;
left:120px;top:120px; width: 100px; height: 200px; background:green;
border-radius: 33px 71px 40px 100px;" id="copy">
</div>
<canvas style="z-index: 1;opacity:0.4;display: inline-block; position: absolute; left:0; top:0;" id="rounded-rect"
width="600"
height="500">
</canvas>
<div style="position: absolute; z-index: 5;margin-top: 330px;">
<label>
Top left
<input type="range" min="1" max="500" value="0" class="slider" id="tl"></label><br/>
<label>
Top right
<input type="range" min="1" max="500" value="0" class="slider" id="tr"></label><br/>
<label>
Bottom left
<input type="range" min="1" max="500" value="0" class="slider" id="bl"></label><br/>
<label>
Bottom right
<input type="range" min="1" max="500" value="0" class="slider" id="br"></label><br/>
</div>
I've already looked at some other posts about that but still can't figure out why the formula isn't working.
To calculate the bounding box of a rotated rectangle :
w' = sin(a)*h + cos(a)*w;
h' = sin(a)*w + cos(a)*h;
The problem is that I'm getting weird behaviours where w' and h' are not precise at all.
// calculate rotation angle of shape
function getRotationDegrees(obj) {
var matrix = obj.css("-webkit-transform") ||
obj.css("-moz-transform") ||
obj.css("-ms-transform") ||
obj.css("-o-transform") ||
obj.css("transform");
if (matrix !== 'none') {
var values = matrix.split('(')[1].split(')')[0].split(',');
var a = values[0];
var b = values[1];
var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
} else {
var angle = 0;
}
if (angle < 0) angle += 360;
return angle;
}
var shape = $('.shape'),
shapeLeft = shape.position().left,
shapeTop = shape.position().top,
shapeWidth = shape.width(),
shapeHeight = shape.height(),
angle = getRotationDegrees(shape),
// formula below
height = Math.abs(shapeWidth * Math.sin(angle)) + Math.abs(shapeHeight * Math.cos(angle)),
width = Math.abs(shapeHeight * Math.sin(angle)) + Math.abs(shapeWidth * Math.cos(angle));
$('#g1').css('width', width);
$('#g2').css('height', height);
.elements,
.element {
position: absolute
}
#s2 {
background: #333333;
top: 60px;
left: -25px;
width: 300px;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="layout" style="position:relative; margin-top:50px; margin-left:70px;">
<div class="elements">
<div id="g1" class="element" style="background:red;left:-35px;top:-10px;height:2px;"></div>
<div id="g2" class="element" style="background:red;left:-35px;top:-10px;width:2px;"></div>
<div id="s2" class="element shape" style="transform: rotate(8deg);"></div>
</div>
</div>
What am I doing wrong ?
Two sources of error:
(Minor) Rounding of the angle. (Don't know what you meant by "already a round number")
(Major) You use the result of getRotationDegrees directly in Math.cos / sin. These functions require radians, i.e. the result directly returned by Math.atan2.
The snippet below adds the other two edges of the bounding box, and also the correct positional offset. I added a slider to change the rotation angle, in order to illustrate that this code is robust.
function getMatrix(obj) {
var matrix = obj.css("-webkit-transform") ||
obj.css("-moz-transform") ||
obj.css("-ms-transform") ||
obj.css("-o-transform") ||
obj.css("transform");
return (matrix == 'none') ? null : matrix.split('(')[1].split(')')[0].split(',');
}
// calculate rotation angle of shape
function getRotationRadians(matrix) {
var angle = matrix ? Math.atan2(matrix[1], matrix[0]) : 0;
if (angle < 0) angle += 2.0 * Math.PI;
return angle;
}
// calculate translation
function getTranslation(matrix) {
return matrix ? [matrix[4], matrix[5]] : [0, 0];
}
// calculate bounding box
function getBoundingBox(shape) {
var shapeLeft = shape.position().left,
shapeTop = shape.position().top,
shapeWidth = shape.width(),
shapeHeight = shape.height();
var matrix = getMatrix(shape);
var angle = getRotationRadians(matrix);
var height = Math.abs(shapeWidth * Math.sin(angle)) + Math.abs(shapeHeight * Math.cos(angle));
var width = Math.abs(shapeHeight * Math.sin(angle)) + Math.abs(shapeWidth * Math.cos(angle));
var trans = getTranslation(matrix);
var left = trans[0] - (width * 0.5);
var top = trans[1] - (height * 0.5);
return {'x': left, 'y': top, 'w': width, 'h': height};
}
formatBox($('.shape'));
function formatBox(shape) {
var box = getBoundingBox(shape);
var offx = 124, offy = 109;
var g1 = $('#g1'), g2 = $('#g2'), g3 = $('#g3'), g4 = $('#g4');
g1.css('width', box.w);
g2.css('height', box.h);
g3.css('width', box.w);
g4.css('height', box.h);
g1.css('left', offx + box.x);
g2.css('left', offx + box.x);
g3.css('left', offx + box.x);
g4.css('left', offx + box.x + box.w);
g1.css('top', offy + box.y);
g2.css('top', offy + box.y);
g3.css('top', offy + box.y + box.h);
g4.css('top', offy + box.y);
}
var angleInp = document.getElementById("angleInp");
angleInp.addEventListener("change", function() {
var shape = $('.shape');
shape.css('transform', 'rotate(' + angleInp.value + 'deg)');
formatBox(shape);
}, false);
.elements,
.element {
position: absolute
}
#s2 {
background: #333333;
top: 60px;
left: -25px;
width: 300px;
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="slider">
<input class="bar" type="range" id="angleInp" min="0" max="360" value="15" onchange="angleInp.value=value"/>
</div>
<div class="layout" style="position:relative; margin-top:50px; margin-left:70px;">
<div class="elements">
<div id="g1" class="element" style="background:red;left:0px;top:0px;height:2px;"></div>
<div id="g2" class="element" style="background:red;left:0px;top:0px;width:2px;"></div>
<div id="g3" class="element" style="background:red;left:0px;top:0px;height:2px;"></div>
<div id="g4" class="element" style="background:red;left:0px;top:0px;width:2px;"></div>
<div id="s2" class="element shape" style="transform: rotate(15deg);"></div>
</div>
</div>
Hello I have been trying to figure something out for a couple days, I'm hoping someone may be able to shed some light on the situation.
I've been trying to code out a learning project. The goal is basically a gantt chart where I'd like to plot some events on eventually.
I am drawing out the timeline on a canvas, right now I have the "Seconds" lines being drawn 50px apart, with 4 shorter lines between them representing 200ms spaces.enter code here
var aTime = "00:1:00.0";
var h, m, s, ms, totalSeconds, thecanvas = null;
// within the loop at line 76 I'm trying ( i * secondsSpacing ) to get the X
//position to draw the lines for each second.
//Why would this not drawing the lines 50 pixels apart?
var secondsSpaceing = 50;
var spaceTime = 44;
var mousePositioning = { x:0, y:0};
var zoom1a = 1;
function drawStroke(sX, sY, eX, eY, color) {
thecontext.strokeStyle=color;
thecontext.lineWidth=1;
thecontext.beginPath();
thecontext.moveTo(sX,sY);
thecontext.lineTo(eX,eY);
thecontext.stroke();
}
function secToMinSec(seconds) {
var min = Math.floor(seconds / 60);
var sec = Math.ceil(seconds % 60);
sec = (sec < 10) ? "0" + sec : sec;
return new Array(min, sec);
}
var mouseXY = function(eve) {
if(!eve) var eve = window.event;
var totalOffsetX = 0;
var totalOffsetY = 0;
var canvasX = 0;
var canvasY = 0;
var canvas = this;
do{
totalOffsetX += canvas.offsetLeft;
totalOffsetY += canvas.offsetTop;
}
while(canvas = canvas.offsetParent)
canvasX = eve.pageX - totalOffsetX;
canvasY = eve.pageY - totalOffsetY;
return {'x':canvasX, 'y':canvasY}
}
$(document).ready(function() {
thecanvas = document.getElementById("thecanvas");
thecontext = thecanvas.getContext("2d");
HTMLCanvasElement.prototype.xy = mouseXY;
$(thecanvas).mousemove(function(e) {
mousePositioning = thecanvas.xy(e);
$("#output").html( "X = " + mousePositioning.x +
"<br> Y = " + mousePositioning.y );
});
var splitTimeStrMS = aTime.split('.');
var splitTimeStr = splitTimeStrMS[0].split(':');
h = parseInt(splitTimeStr[0]);
m = parseInt(splitTimeStr[1]);
s = parseInt(splitTimeStr[2]);
ms = parseFloat(splitTimeStrMS[1]);
var X = 60;
totalSeconds = (h * X * X) + (m * X) + s;
var divided = Math.ceil(totalSeconds / zoom1a);
var timeChartArray = new Array();
for(var i = 0; i <= divided; i++) {
timeChartArray.push(i * zoom1a);
}
var neededCanvasWidth = Math.ceil(timeChartArray.length * secondsSpaceing);
var timeStr = null;
var lineColor = "#000000";
if(neededCanvasWidth > ($("#thecanvas").attr("width"))) {
$("#thecanvas").attr("width", neededCanvasWidth);
thecontext.font="normal 12px Arial";
thecontext.fillStyle = lineColor;
for(var i = 0; i < timeChartArray.length; i++) {
//draw the line
var xline = parseFloat(i * secondsSpaceing);
drawStroke(xline, 0, xline, 8, lineColor);
//draw the time text
var timeStr = secToMinSec( timeChartArray[i] );
var timeFormatted = timeStr[0] + ":" + timeStr[1];
var timeXpos = (xline - 10);
if(timeFormatted != "0:00") {
thecontext.fillText(timeFormatted, timeXpos,24);
}
}
}
});
#canvasOut {position:relative; width:100%; width:700px; background:#222222;
overflow:visible; }
#thecanvas {position:relative; height:140px; background:#fff; }
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="canvasOut">
<canvas width="200" id="thecanvas"></canvas>
</div>
<div id="output">
</div>
<div id="output2">
</div>
If you move the mouse over the one second mark, you will see it is at x:50, two second mark is x:100 but then the three second mark is x:149, the same pattern continues and I keep losing seconds. By the fifth second, it should be at x:250 but its lost two seconds and is x:248. I'm still trying to figure this out myself but hopeful someone can shed some light as it's becoming discouraging. Thanks for reading.
EDIT: the code snippet worked in the editor, but I noticed when I press the "Run snippet" button that it's not showing the mouse position as it did in the editor, and on jsFiddle.
Here is a link to the project on jsFiddle:
https://jsfiddle.net/4y0q2pdw/19/
Thanks again
Check this.I saw that every 1 sec the function subtracted 4px. So I replace the
var xline = parseFloat(i * secondsSpaceing);
with the
var xline =parseFloat((i * secondsSpaceing)+3.6*i);
Initially I set instead of 3.6 the integer 4 but the function added then 1 or 2px after the 8 seconds line.So to be more accurate I replace the 4 by 3.6 that is more accurate.