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.
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 ) );
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>"
}
Right now when I set position: absolute; in css it gives:
Uncaught TypeError: Cannot read property 'x' of undefined
at HTMLCanvasElement.getColor
It works when position: absolute; But I need the Canvas in fixed position.
My findPos() function to get the position of object:
function findPos(obj) {
var curleft = 0, curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return { x: curleft, y: curtop };
}
return undefined;
}
Please check the fiddle for my code: https://jsfiddle.net/ds6kug6r/8/
That's because according to the specs (2.1), fixed positioned elements don't have an offsetParent element.
But you don't need it anyway, instead use Element.getBoundingClientRect() which doesn't suffer from the padding edge issue.
function getColor(e) {
// getBoundingClientRect to retrieve the position of our canvas in the doc
var rect = this.getBoundingClientRect();
// we also need to use clientX and clientY values now
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
var coord = "x=" + x + ", y=" + y;
var c = this.getContext('2d');
var p = c.getImageData(x, y, 1, 1).data;
log(p);
}
/* Color Wheel */
var canvas = document.getElementById("picker");
var context = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 100;
var counterClockwise = false;
for (var angle = 0; angle <= 360; angle += 1) {
var startAngle = (angle - 2) * Math.PI / 180;
var endAngle = angle * Math.PI / 180;
context.beginPath();
context.moveTo(x, y);
context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
var gradient = context.createRadialGradient(x, y, 0, x, y, radius);
gradient.addColorStop(0, 'hsl(' + angle + ', 10%, 100%)');
gradient.addColorStop(1, 'hsl(' + angle + ', 100%, 50%)');
context.fillStyle = gradient;
context.fill();
}
document.getElementById("picker").addEventListener("click", getColor);
function log(m) {
document.getElementById("viz").style.backgroundColor = 'rgba(' + m + ')';
document.getElementById("log").append(m + '\n')
}
canvas {
position: fixed;
right: 10px;
bottom: 10px;
cursor: pointer;
}
#viz {
display: inline-block;
height: 20px;
width: 20px;
}
<canvas class="colorWheel" id="picker" width="200" height="200"></canvas>
<div>
Log: <span id="viz"></span>
<pre id="log"></pre>
</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>
I used below code to draw a line in circle,Now I want to draw 12 lines in different angles with same space & lines should be touched to the circle.
<!DOCTYPE html>
<html>
<head>
<style>
#straight{
height: 30px;
border-right: 1px solid blue;
-webkit-transform: rotate(**" for loop value must be displayed"** deg);
transform: rotate(**" for loop value must be displayed"** deg);
position: absolute;
top:40px;
left:400px;
}
#circle {
height: 30px;
width: 31px;
margin-left: 81px;
margin-top: 0px;
background-color: #fff;
border: 2px solid blue;
border-radius: 65px;
position:absolute;
}
</style>
</head>
<body>
<div>
<div id="circle">
<div style="position:relative; top:-40px; left:-385px;">
<div id="straight"></div>
</div>
</div>
</body>
</html>
Please help me & thanks in advance
Check this fiddle.
It uses a function DrawLine(x1,y1,x2,y2) to draw a line between the given co-ordinates.
Basically, it creates divs with thin width and rotate them according the slope.
Looks like a wheel with spokes.
Here is a wheel in action if you need.
Here is the snippet.
drawNLines(12, 40, 40, 40);
function drawNLines(N, centreX, centreY, radius) {
for (i = 0; i < N; i++) {
angle = 360 / N;
x2 = centreX + radius * Math.cos(Math.PI * angle * i / 180);
y2 = centreY + radius * Math.sin(Math.PI * angle * i / 180);
DrawLine(centreX, centreY, x2, y2);
}
}
function DrawLine(x1, y1, x2, y2) {
if (y1 < y2) {
var pom = y1;
y1 = y2;
y2 = pom;
pom = x1;
x1 = x2;
x2 = pom;
}
var a = Math.abs(x1 - x2);
var b = Math.abs(y1 - y2);
var c;
var sx = (x1 + x2) / 2;
var sy = (y1 + y2) / 2;
var width = Math.sqrt(a * a + b * b);
var x = sx - width / 2;
var y = sy;
a = width / 2;
c = Math.abs(sx - x);
b = Math.sqrt(Math.abs(x1 - x) * Math.abs(x1 - x) + Math.abs(y1 - y) * Math.abs(y1 - y));
var cosb = (b * b - a * a - c * c) / (2 * a * c);
var rad = Math.acos(cosb);
var deg = (rad * 180) / Math.PI
htmlns = "http://www.w3.org/1999/xhtml";
div = document.createElementNS(htmlns, "div");
div.setAttribute('style', 'border:1px solid black;width:' + width + 'px;height:0px;-moz-transform:rotate(' + deg + 'deg);-webkit-transform:rotate(' + deg + 'deg);position:absolute;top:' + y + 'px;left:' + x + 'px;');
document.getElementById("circle").appendChild(div);
}
#circle {
height: 80px;
width: 80px;
margin-left: 30px;
margin-top: 30px;
background-color: #fff;
border: 2px solid blue;
border-radius: 80px;
position: absolute;
}
<div id="circle"></div>
Hope this helps. :)