Im having issues with this code created. The problem im having is when i click to stop the line from drawing its has a 50% chance it will work first time However It only seems work correctly if you are doing straight lines only, but i want it to work from any direction and im not 100% sure why its not working line that.
(Im using 1.12.4 jquery as im adding this into WordPress thats what is runs off)
$(function() {
var x1 = null,
y1 = null;
var offsetX = 0,
offsetY = 0;
var moveLineId = "moveLine";
function createLine(x1, y1, x2, y2, id) {
var length = Math.sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)));
var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
var transform = 'rotate(' + angle + 'deg)';
offsetX = (x1 > x2) ? x2 : x1;
offsetY = (y1 > y2) ? y2 : y1;
var line = $('<div>')
.appendTo('#demo')
.addClass('line')
.css({
'position': 'absolute',
'-webkit-transform': transform,
'-moz-transform': transform,
'transform': transform
})
.width(length)
.offset({
left: offsetX,
top: offsetY
});
if(id != null) line.attr('id', id);
return line;
}
$('#demo').click(function(event) {
$(".line").removeAttr('id');
var x = event.pageX,
y = event.pageY;
if (x1 == null) {
x1 = x;
y1 = y;
} else {
x1 = y1 = null;
}
})
.delegate('.line', 'click', function(event) {
event.preventDefault();
$(this).toggleClass('active');
x1 = y1 = null;
return false;
});
$('#demo').mousemove(function(event) {
var x = event.pageX,
y = event.pageY;
if (x1 != null) {
$("#" + moveLineId).remove();
createLine(x1, y1, x, y, moveLineId)
} else {
x1 = y1 = null;
}
})
});
div.line {
transform-origin: 0 100%;
height: 3px;
/* Line width of 3 */
background: #000;
/* Black fill */
}
#demo {
border: 1px dashed #ccc;
height: 400px;
}
div.transforming-on-corner {
transform-origin: 0% 0%;
}
<script src="https://code.jquery.com/jquery-1.12.4.min.js"
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
crossorigin="anonymous"></script>
<h3> click two point to draw a line :</h3>
<div id="demo" class="wide">
</div>
Instead of click events, listen to mousedown and mouseup events to start / stop drawing the line.
$(function() {
var x1 = null,
y1 = null;
var offsetX = 0,
offsetY = 0;
var moveLineId = "moveLine";
// Use "mousedown" here so the start of a line is registered as soon as you press the mouse button.
$('#demo').on("mousedown", function(event) {
$(".line").removeAttr('id');
var x = event.pageX,
y = event.pageY;
if (x1 == null) {
x1 = x;
y1 = y;
} else {
x1 = y1 = null;
}
})
.delegate('.line', 'mouseup', function(event) {
// Use "mouseup" here so the start of a line is registered as soon as you release the mouse button.
event.preventDefault();
$(this).toggleClass('active');
x1 = y1 = null;
return false;
});
$('#demo').mousemove(function(event) {
var x = event.pageX,
y = event.pageY;
if (x1 != null) {
$("#" + moveLineId).remove();
createLine(x1, y1, x, y, moveLineId)
} else {
x1 = y1 = null;
}
});
function createLine(x1, y1, x2, y2, id) {
var length = Math.sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)));
var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
var transform = 'rotate(' + angle + 'deg)';
offsetX = (x1 > x2) ? x2 : x1;
offsetY = (y1 > y2) ? y2 : y1;
var line = $('<div>')
.appendTo('#demo')
.addClass('line')
.css({
'position': 'absolute',
'-webkit-transform': transform,
'-moz-transform': transform,
'transform': transform
})
.width(length)
.offset({
left: offsetX,
top: offsetY
});
if (id != null) line.attr('id', id);
return line;
}
});
div.line {
transform-origin: 0 100%;
height: 3px;
background: #000;
}
#demo {
border: 1px dashed #ccc;
height: 400px;
}
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<div id="demo" class="wide"></div>
Related
I am wondering if there was any way to clear an HTML page without using a canvas.
I am attempting to make a simple program using JavaScript without a canvas, which draws a line from the center of the window to wherever your mouse is pointing. I can successfully draw a new line whenever and wherever the mouse is moving, but do not know how to clear the page without making a canvas and using clearRect().
Is there any way to clear the page without a canvas?
Just in case anyone finds it helpful, here is my code:
window.addEventListener('mousemove', function (e){
linedraw(window.innerWidth/2, window.innerHeight/2, e.x, e.y)
});
function linedraw(x1, y1, x2, y2) {
if (x2 < x1) {
tmp = x2 ; x2 = x1 ; x1 = tmp
tmp = y2 ; y2 = y1 ; y1 = tmp
}
lineLength = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
m = (y2 - y1) / (x2 - x1)
degree = Math.atan(m) * 180 / Math.PI
document.body.innerHTML += "<div class='line' style='transform-origin: top left; transform: rotate(" + degree + "deg); width: " + lineLength + "px; height: 1px; background: black; position: absolute; top: " + y1 + "px; left: " + x1 + "px;'></div>"
}
Instead of appending a new div, just replace the html on every mouse move.
window.addEventListener('mousemove', function (e){
linedraw(window.innerWidth/2, window.innerHeight/2, e.x, e.y)
});
function linedraw(x1, y1, x2, y2) {
if (x2 < x1) {
tmp = x2 ; x2 = x1 ; x1 = tmp
tmp = y2 ; y2 = y1 ; y1 = tmp
}
lineLength = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
m = (y2 - y1) / (x2 - x1)
degree = Math.atan(m) * 180 / Math.PI
// `document.body.innerHTML = ` instead of `document.body.innerHTML += `
document.body.innerHTML = "<div class='line' style='transform-origin: top left; transform: rotate(" + degree + "deg); width: " + lineLength + "px; height: 1px; background: black; position: absolute; top: " + y1 + "px; left: " + x1 + "px;'></div>"
}
im trying to get the line drawing to show on first click. So you are able to see where the line will end on second click. At the moment you cant see the line until you click a second point but i cant work out what im missing so that the line shows up on the first click and it carries on displaying until the second click.
$(function() {
var x1 = null,
y1 = null;
var offsetX = 0,
offsetY = 0;
function createLine(x1, y1, x2, y2) {
var length = Math.sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)));
var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
var transform = 'rotate(' + angle + 'deg)';
offsetX = (x1 > x2) ? x2 : x1;
offsetY = (y1 > y2) ? y2 : y1;
var line = $('<div>')
.appendTo('#demo')
.addClass('line')
.css({
'position': 'absolute',
'-webkit-transform': transform,
'-moz-transform': transform,
'transform': transform
})
.width(length)
.offset({
left: offsetX,
top: offsetY
});
return line;
}
$('#demo').click(function(event) {
var x = event.pageX,
y = event.pageY;
if (x1 == null) {
x1 = x;
y1 = y;
} else {
createLine(x1, y1, x, y);
x1 = y1 = null;
}
})
.delegate('.line', 'click', function(event) {
event.preventDefault();
$(this).toggleClass('active');
x1 = y1 = null;
return false;
});
});
div.line {
transform-origin: 0 100%;
height: 3px;
/* Line width of 3 */
background: #000;
/* Black fill */
}
#demo {
border: 1px dashed #ccc;
height: 400px;
}
div.transforming-on-corner {
transform-origin: 0% 0%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3> click two point to draw a line :</h3>
<div id="demo" class="wide">
</div>
One thing you can do is draw a unique line on the $('#demo').mousemove event after your first click. On each move remove that line by referencing its id (ex: #moveLine) and draw the new one at your mouse position. Once you click to draw a new line it will clear the id of the old line so it becomes permanent.
$(function() {
var x1 = null,
y1 = null;
var offsetX = 0,
offsetY = 0;
var moveLineId = "moveLine";
function createLine(x1, y1, x2, y2, id) {
var length = Math.sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)));
var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
var transform = 'rotate(' + angle + 'deg)';
offsetX = (x1 > x2) ? x2 : x1;
offsetY = (y1 > y2) ? y2 : y1;
var line = $('<div>')
.appendTo('#demo')
.addClass('line')
.css({
'position': 'absolute',
'-webkit-transform': transform,
'-moz-transform': transform,
'transform': transform
})
.width(length)
.offset({
left: offsetX,
top: offsetY
});
if(id != null) line.attr('id', id);
return line;
}
$('#demo').click(function(event) {
$(".line").removeAttr('id');
var x = event.pageX,
y = event.pageY;
if (x1 == null) {
x1 = x;
y1 = y;
} else {
x1 = y1 = null;
}
})
.delegate('.line', 'click', function(event) {
event.preventDefault();
$(this).toggleClass('active');
x1 = y1 = null;
return false;
});
$('#demo').mousemove(function(event) {
var x = event.pageX,
y = event.pageY;
if (x1 != null) {
$("#" + moveLineId).remove();
createLine(x1, y1, x, y, moveLineId)
} else {
x1 = y1 = null;
}
})
});
div.line {
transform-origin: 0 100%;
height: 3px;
/* Line width of 3 */
background: #000;
/* Black fill */
}
#demo {
border: 1px dashed #ccc;
height: 400px;
}
div.transforming-on-corner {
transform-origin: 0% 0%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3> click two point to draw a line :</h3>
<div id="demo" class="wide">
</div>
I want to find out if it is possible to get multiple drawing lines just like this Fiddle project -
However with out using the canvas, instead using a normal div box with a css background image?
below code using canvas
var canvas = new fabric.Canvas('c', { selection: false });
var line, isDown;
canvas.on('mouse:down', function(o){
isDown = true;
var pointer = canvas.getPointer(o.e);
var points = [ pointer.x, pointer.y, pointer.x, pointer.y ];
line = new fabric.Line(points, {
strokeWidth: 5,
fill: 'red',
stroke: 'red',
originX: 'center',
originY: 'center'
});
canvas.add(line);
});
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
line.set({ x2: pointer.x, y2: pointer.y });
canvas.renderAll();
});
canvas.on('mouse:up', function(o){
isDown = false;
});
Thanks
I made some correction to the example to draw in all direction , and that's only with css3 :
Note that you have to define to point (two clicks ) to draw a line .
See below snippet :
$(function() {
var x1 = null,
y1 = null;
var offsetX = 0,
offsetY = 0;
function createLine(x1, y1, x2, y2) {
var length = Math.sqrt(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)));
var angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
var transform = 'rotate(' + angle + 'deg)';
offsetX = (x1 > x2) ? x2 : x1;
offsetY = (y1 > y2) ? y2 : y1;
var line = $('<div>')
.appendTo('#demo')
.addClass('line')
.css({
'position': 'absolute',
'-webkit-transform': transform,
'-moz-transform': transform,
'transform': transform
})
.width(length)
.offset({
left: offsetX,
top: offsetY
});
return line;
}
$('#demo').click(function(event) {
var x = event.pageX,
y = event.pageY;
if (x1 == null) {
x1 = x;
y1 = y;
} else {
createLine(x1, y1, x, y);
x1 = y1 = null;
}
})
.delegate('.line', 'click', function(event) {
event.preventDefault();
$(this).toggleClass('active');
x1 = y1 = null;
return false;
});
});
div.line {
transform-origin: 0 100%;
height: 3px;
/* Line width of 3 */
background: #000;
/* Black fill */
}
#demo {
border: 1px dashed #ccc;
height: 400px;
}
div.transforming-on-corner {
transform-origin: 0% 0%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3> click two point to draw a line :</h3>
<div id="demo" class="wide">
</div>
Right now I have a circle that goes from the bottom to the top of a canvas.
I attached a click event to the canvas and it console logs the coordinates of the click.
The ball also console logs the coordinates of where it is.
How can I add a circle element to 'elements' and how do I compare the canvas click event to the circle diameters coordinates.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius = 10;
var x = canvas.width/6;
var y = canvas.height-30;
var dx = 0;
var dy = -2;
canvas.addEventListener('click', function(event) {
var x = event.pageX - elemLeft;
var y = event.pageY - elemTop;
console.log("CLICKED: (x,y) ", x, y);
elements.forEach(function(element) {
if (y > canvas.y && y < canvas.y + canvas.ballRadius && x > canvas.x && x < canvas.x + canvas.ballRadius) {
alert('clicked an element');
}
});
}, false);
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI*2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBall();
console.log("Ball moving: (x,y) ", x, ", ", y)
if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
dx = -dx;
}
if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) {
dy = -dy;
}
x += dx;
y += dy;
}
setInterval(draw, 100);
https://jsfiddle.net/aL9amevj/
You can use css to render a circle, .animate() to animate element, check if animation animation.currentTime is less than half of animation.effect.computedTiming.duration / 2 .finished to reset element to original state.
.circle {
position: relative;
border-radius: 50%;
width: 50px;
height: 50px;
background: blue;
left: calc(100vw - 100px);
top: calc(100vh - 100px);
}
<button>click</button>
<div class="circle" style="animation-fill-mode:forwards"></div>
<script>
var score = 0;
var button = document.querySelector("button");
var circle = document.querySelector(".circle");
button.addEventListener("click", function() {
this.setAttribute("disabled", "disabled");
var curr = circle.animate([{
left: "0px",
top: "0px"
}], {
duration: 10000,
iterations: 1
});
circle.onclick = (e) => {
console.log(e.pageX, e.pageY);
var t = curr.currentTime <
curr.effect.computedTiming.duration / 2;
if (t) {
score += 1;
}
curr.cancel();
circle.style.display = "none";
circle.onclick = null;
alert((t ? "added 1 " : "did not add 1 ")
+ "to score: " + score);
}
curr.finished.then(() => {
circle.onclick = null;
setTimeout(function() {
button.removeAttribute("disabled");
}, 10)
}).catch(e => {
console.log(e);
button.removeAttribute("disabled");
circle.style.display = "block";
})
});
</script>
The code snippet below calculates the speed of the mouse cursor on the screen. It appears to work correctly, however, I have some questions about how it works.
var div = document.body.children[0],
isOverElem, cX, cY, pX, pY, cTime, pTime;
div.addEventListener('mouseover', function(event) {
if (isOverElem) return;
isOverElem = true;
pX = event.pageX;
pY = event.pageY;
pTime = Date.now();
this.addEventListener('mousemove', move);
});
div.addEventListener('mouseout', function(event) {
if ( event.relatedTarget && !this.contains(event.relatedTarget) ) {
isOverElem = false;
this.removeEventListener('mousemove', move);
this.innerHTML = '';
}
});
function move(event) {
var speed;
cX = event.pageX;
cY = event.pageY;
cTime = Date.now();
if (pTime == cTime) return; // mouseover with mousemove
speed = Math.sqrt( Math.pow(pX - cX, 2) + Math.pow(pY - cY, 2) ) / (cTime - pTime);
this.innerHTML = 'Mouse speed: ' + speed;
setTimeout(function() {
pX = cX;
pY = cY;
pTime = cTime;
}, 10);
}
div {
width: 80%;
height: 200px;
padding: 10px;
line-height: 200px;
font-size: 1.5em;
border: 2px solid red;
}
<div></div>
I don't understand the following line:
speed = Math.sqrt( Math.pow(pX - cX, 2) + Math.pow(pY - cY, 2) ) / (cTime - pTime);
Why can't this just use (pX - cX)/(cTime - pTime)? Why does it require a more complicated equation that includes Math.sqrt and Math.pow? I am interested in the algorithm and whether the script is correct.
(pX - cX) / (cTime - pTime) would be the horizontal speed.
(pY - cY) / (cTime - pTime) would be the vertical speed.
If you go horizontally and then vertically, you would travel more distance then if you would have gone straight from X to Y.
So, to get the minimal distance between X and Y, you have to use the distance formula.