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>"
}
Related
I think the title is a little bit confusing so I will try to say it better.
Image you have this code:
#NadrzFrontView:before {
--beginHeight: var(--startHeight);
--endHeight: var(--finishHeight);
animation: 2s fillin ease forwards;
content: "";
position: absolute;
bottom: 0;
width: 300px;
height: 0;
background-color: #00FFF5;
display: inline-block;
}
#NadrzFrontView {
width: 300px;
height: 300px;
border-radius: 50%;
border: 3px solid black;
position: relative;
overflow: hidden;
}
<div id="NadrzFrontView" style="--startHeight: 0%; --finishHeight: 50%;"> </div>
It looks like this:
Now, you can determent left, top position and height of an element using this script:
function getOffset(el) {
var rect = el.getBoundingClientRect();
return {
left: rect.left + window.pageXOffset,
top: rect.top + window.pageYOffset,
width: rect.width || el.offsetWidth,
height: rect.height || el.offsetHeight
};
}
Ok, when we are able to find these then we go to our problem:
function SomeFunction() {
var thickness = 1;
var color = '#000000';
var off_nadrz = getOffset(document.getElementById('NadrzFrontView'));
var elem = document.getElementById('NadrzFrontView');
var pseudoStyle = window.getComputedStyle(elem, ':before');
var off_pseudo_elem = getOffset(elem);
off_pseudo_elem.top += parseInt(pseudoStyle.top, 10);
off_pseudo_elem.left += parseInt(pseudoStyle.left, 10);
off_pseudo_elem.height = parseInt(pseudoStyle.height, 10);
//finding middle of the circle
var x1 = off_nadrz.left + (off_nadrz.width / 2);
var y1 = off_nadrz.top + (off_nadrz.height / 2);
//draw point in the middle of circle
document.getElementById("AllLines").innerHTML += CreateHtmlPoint(color, x1, y1);
//fincding point on the side of an element
var x2; //I need to find this -- see more in examples
var y2; //I need to find this -- see more in examples
document.getElementById("AllLines").innerHTML += CreateHtmlPoint(color, x2, y2); //This does not work
}
function CreateHtmlPoint(color, cx, cy) {
cx -= 5; // - 5, because width of point is 10
cy -= 5; // - 5, because height of point is 10
return "<div style='padding:0px; z-index: 2; margin:0px; height: 10px; width: 10px; background-color:" + color + "; line-height:1px; position:absolute; left:" + cx + "px; top:" + cy + "px; border-radius: 50%;' />";
}
So, now example of an x2 and y2 would look like this:
Basically, we know on what coordinades is top of circle (off_nadrz.top), bottom of circle (off_nadrz.top + (off_nadrz.height / 2)) and height of an circle (off_nadrz.height). We also know same things of an psuedo_element (blue thing in the circle). From this we need to calculate x2 and y2.
Thanks for every suggestion because I am fighting with this problem for 2 days now...
you have only to apply the circumference formula:
var y2 = y1 - ( off_pseudo_elem.height - off_nadrz.height / 2 );
once you have y2, calculate x2:
var r = off_nadrz.height / 2; // if the figure is a circle, not an ellipse
var x2 = x1 + Math.sqrt( r * r - ( y2 - y1 ) * ( y2 - y1 ) );
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>
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 have arcs connecting nodes in a d3 force directed graph, the whole SVG is transformed with CSS. Now the arcs doesn't feel nice as its like lying in the ground, so I want to get them "stand up", or rotate X,Y,Z to get the effect.
I have set the transform origin to the center of the line connecting the nodes, but now I am stuck with finding the angles at which I have to rotate the arcs to make them stand up. Any idea/formula on finding the angles is much appreciated.
The code I am having right now inside the tick function looks like:
force.on("tick", function() {
path.attr("d", function (d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy) -200;
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
})
.attr('style', function(d){
var rotateX = 0, rotateY = 0, rotateZ = 0;
return "transform-origin:" + (d.source.x + d.target.x)/2 + "px " + (d.source.y + d.target.y)/2 + "px" +
";transform:rotateX("+rotateX+"deg) rotateY("+rotateY+"deg) rotateZ("+rotateZ+"deg)";
});
rotateX, rotateY and rotateZ angles are what I am looking for!
I have no practical knowledge of d3, so I have solved the problem for a standard javascript layout.
Hopefully the procedure should work the same.
On the demo, click 2 times to set the begin and end of the arc. Then click again to see it rotating in 3d.
You can repeat the cycle how many times you want.
In the transform calculus we just calculate the angle in the plane with atan2 and the horizontal and vertical differences. The real trick is to set the 90 degrees that will get the element vertical after (in notation) the plane rotation.
Note that in the snippet I am not applying 90 degress, but 80, so that the arc is still visible when viewed from above.
var sequence = 0;
var x1, y1, x2, y2;
function getCursorPosition(event) {
var x = event.clientX;
var y = event.clientY;
var ele = document.getElementById('container');
if (sequence == 0) {
x1 = x;
y1 = y;
sequence = 1;
ele.classList.remove("animate");
} else if (sequence == 1) {
x2 = x;
y2 = y;
sequence = 2;
Compute();
} else {
ele.classList.add("animate");
sequence = 0;
}
}
function Compute() {
var ele = document.getElementById('inner');
var width = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
ele.style.width = width + "px ";
ele.style.height = width / 2 + "px ";
ele.style.left = x1 + "px ";
ele.style.top = y1 + "px ";
var angle = Math.atan2(y2 - y1, x2 - x1);
var deg = angle * 180.0 / Math.PI;
ele.style.transform = "rotate(" + deg + "deg) rotateX(80deg) "
/*
var style = "width:" + width + "px ";
style += "left: " + x1 + "px ";
style += "top: " + y1 + "px ";
ele.setAttribute("style",style);
*/
}
.container {
width: 600px;
height: 400px;
border: solid 1px green;
perspective: 1000px;
transform-style: preserve-3d;
position: absolute;
background-image: repeating-linear-gradient(white 0px, wheat 50px, white 100px);
}
#inner {
width: 100px;
height: 50px;
border-radius: 0px 0px 100px 100px;
background-color: green;
position: absolute;
transform-origin: left top;
transform-style: preserve-3d;
}
.animate {
animation: rota 15s 1;
}
#keyframes rota {
from {
transform: perspective(1000px) rotateX(0deg);
}
to {
transform: perspective(1000px) rotateX(360deg);
}
}
<div class="container" id="container" onclick="getCursorPosition(event)">
<div id="inner">
</div>
</div>
With a canvas you can draw a line with javascript like this,
<html>
<canvas id="myCanvas" width="500" height="300" style="border:1px solid #d3d3d3;"></canvas>
<script>
var c=document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.moveTo(20,20);
ctx.lineTo(100,100);
ctx.stroke();
</script>
</html>
How can i do the same thing, but by using a div tag instead of a canvas?
The reason i want to do this is beacuse the canvas does not seem to work on IE and i know that Google graphs make use of div tags and not canvases to draw graphs, so it might be possible.
I tried replacing the canvas with a div, but it does not work.
Using Jquery:
<div id='rPaper'></div>
Jquery
x1 = 50, y1 = 50,
x2 = 350, y2 = 50;
drawnode(x1, y1);
drawnode(x2, y2);
drawline(x1, y1, x2, y2);
function drawnode(x, y) {
var ele = ""
var style = "";
style += "position:absolute;";
style += "z-index:100;"
ele += "<div class='relNode' style=" + style + ">";
ele += "<span> Test Node</span>"
ele += "<div>"
$('#rPaper').show();
var node = $(ele).appendTo('#rPaper');
var width = node.width();
var height = node.height();
var centerX = width / 2;
var centerY = height / 2;
var startX = x - centerX;
var startY = y - centerY;
node.css("left", startX).css("top", startY);
}
function drawline(ax, ay, bx, by) {
console.log('ax: ' + ax);
console.log('ay: ' + ay);
console.log('bx: ' + bx);
console.log('by: ' + by);
if (ax > bx) {
bx = ax + bx;
ax = bx - ax;
bx = bx - ax;
by = ay + by;
ay = by - ay;
by = by - ay;
}
console.log('ax: ' + ax);
console.log('ay: ' + ay);
console.log('bx: ' + bx);
console.log('by: ' + by);
var angle = Math.atan((ay - by) / (bx - ax));
console.log('angle: ' + angle);
angle = (angle * 180 / Math.PI);
console.log('angle: ' + angle);
angle = -angle;
console.log('angle: ' + angle);
var length = Math.sqrt((ax - bx) * (ax - bx) + (ay - by) * (ay - by));
console.log('length: ' + length);
var style = ""
style += "left:" + (ax) + "px;"
style += "top:" + (ay) + "px;"
style += "width:" + length + "px;"
style += "height:1px;"
style += "background-color:black;"
style += "position:absolute;"
style += "transform:rotate(" + angle + "deg);"
style += "-ms-transform:rotate(" + angle + "deg);"
style += "transform-origin:0% 0%;"
style += "-moz-transform:rotate(" + angle + "deg);"
style += "-moz-transform-origin:0% 0%;"
style += "-webkit-transform:rotate(" + angle + "deg);"
style += "-webkit-transform-origin:0% 0%;"
style += "-o-transform:rotate(" + angle + "deg);"
style += "-o-transform-origin:0% 0%;"
style += "-webkit-box-shadow: 0px 0px 2px 2px rgba(0, 0, 0, .1);"
style += "box-shadow: 0px 0px 2px 2px rgba(0, 0, 0, .1);"
style += "z-index:99;"
$("<div style='" + style + "'></div>").appendTo('#rPaper');
}
Demo
// right top -> left bottom
x1 = 850, y1 = 150,
x2 = 550, y2 = 250;
drawnode(x1, y1);
drawnode(x2, y2);
drawline(x1, y1, x2, y2);
Demo
// right bottom -> left top
x1 = 750, y1 = 150,
x2 = 550, y2 = 50;
drawnode(x1, y1);
drawnode(x2, y2);
drawline(x1, y1, x2, y2);
Demo
// left top -> right bottom
x1 = 150, y1 = 150,
x2 = 350, y2 = 350;
drawnode(x1, y1);
drawnode(x2, y2);
drawline(x1, y1, x2, y2);
Demo
// vertical line: down -> up
x1 = 150, y1 = 350,
x2 = 150, y2 = 150;
drawnode(x1, y1);
drawnode(x2, y2);
drawline(x1, y1, x2, y2);
Demo
Rendered some lines using div tag. Please refer below code
<div style="width: 112px; height: 47px; border-bottom: 1px solid black; -webkit-transform: translateY(-20px) translateX(5px) rotate(27deg); position: absolute;/* top: -20px; */"></div>
<div style="width: 112px; height: 47px; border-bottom: 1px solid black; -webkit-transform: translateY(20px) translateX(5px) rotate(-26deg); position: absolute;top: -33px;left: -13px;"></div>
hope it helps.
fiddle link :
http://jsfiddle.net/NATnr/45/
Thanks,
Siva
You can create a tag like p, or div, set width whatever you wanted, add top border and append it to the div within you want to create a line.
You can use CSS3 2D Transforms http://jsfiddle.net/dmRhL/:
.line{
width: 150px;
transform: translate(50px,100px) rotate(30deg);
-ms-transform: translate(50px,100px) rotate(30deg); /* IE 9 */
-webkit-transform: translate(50px,100px) rotate(30deg); /* Safari and Chrome */
}
But looks like your problem is the old IE browsers that that will probably not help.
You can try using excanvas - a JS library that simulates the canvas element using IE's VML renderer.
Or some 2D drawing framework that will use canvas or SVG depending on browser support. You can find a full list at http://en.wikipedia.org/wiki/JavaScript_graphics_library
Other answers are very better than this... This uses PURE CSS, if you need.
<head>
<style>
#i1,#i2,#i3,#i4,#i5,#i6,#i7,#i8{border-right:2px solid black; height:2px;}
#i1{width:30px;}#i2{width:31px;}#i3{width:32px;}#i4{width:33px;}#i5{width:34px;}#i6{width:35px;}#i7{width:36px;}#i8{width:37px;}
</style>
</head>
<div id="i1"></div>
<div id="i2"></div>
<div id="i3"></div>
<div id="i4"></div>
<div id="i5"></div>
<div id="i6"></div>
<div id="i7"></div>
<div id="i8"></div>
And if you need to draw axis-parallel lines, you can put width or height as 1px and increase the other.
fiddle here.