1. 用js能畫一個三維圓嗎
能,而且能根據三維渲染原理得出物體體積、光影、光源方向、材質貼圖、深景等等,只是純js實現的3D如果復雜點的場景速度並不理想。
2. 如何利用 js+html 繪制 帶箭頭的 弧線
純js不好實現,但是配合html,css就有了近似的辦法.下面提供一個解決方案,已知兩個點的坐標,為它們畫一條帶箭頭的弧線.
<html>
<head>
<meta http-equiv = "content-type" content = "text/html; charset = gb2312">
<title>箭頭弧線</title>
<style type = "text/css">
span { position: absolute; width: 5px; height: 5px; background-color: #0000ff; display: block; border-radius: 50%; }
</style>
<script language = "javascript">
function locateO () {
var x0 = parseInt (spnA.style.left, 10), y0 = parseInt (spnA.style.top, 10), x1 = parseInt (spnB.style.left, 10), y1 = parseInt (spnB.style.top, 10), horizontalDistance = Math.abs (x1 - x0), verticalDistance = Math.abs (y1 - y0), x = Math.min (x0, x1) + horizontalDistance / 2, y = Math.min (y0, y1) + verticalDistance / 2, distance = Math.sqrt (Math.pow (horizontalDistance, 2) + Math.pow (verticalDistance, 2)), array = new Array (x0, y0, x1, y1, distance);
spnO.style.left = x;
spnO.style.top = y;
return array;
}
function getRadian (x0, y0, x1, y1) {
var horizontalDistance = Math.abs (x1 - x0), verticalDistance = Math.abs (y1 - y0), rate = horizontalDistance == 0 ? 0 : verticalDistance / horizontalDistance, radian;
if (y1 < y0) {
if (x1 > x0) {
radian = - Math.atan (rate);
} else if (x1 == x0) {
radian = - Math.PI / 2;
} else {
radian = - (Math.PI - Math.atan (rate));
}
} else if (y1 == y0) {
radian = x1 > left ? 0 : - Math.PI;
} else if (x1 < x0) {
radian = - (Math.PI + Math.atan (rate));
} else if (x1 == x0) {
radian = - Math.PI * 3 / 2;
} else {
radian = - 2 * Math.PI + Math.atan (rate);
}
return radian;
}
function getAngle (radian) {
var angle = - radian * 180 / Math.PI;
return angle;
}
function slantArc (x0, y0, x1, y1) {
var radian = getRadian (x0, y0, x1, y1), angle = 360 - getAngle (radian);
cnvArc.style.transform = "rotate(" + angle + "deg)";
}
function drawArc (x0, y0, width) {
var context = cnvArc.getContext ("2d"), radius = width / 2, height = radius / 2;
cnvArc.width = width + 10;
cnvArc.height = height;
cnvArc.style.left = x0;
cnvArc.style.top = y0 - height;
context.ellipse (radius + 5, height, radius, height / 2, 0, 0, Math.PI * 2);
context.strokeStyle = "#00ff00";
context.stroke ();
}
function hex (figure) {
return figure.toString (16);
}
function zeroize (cluster) {
if (cluster.length < 2) {
cluster = 0 + cluster;
}
return cluster;
}
function getColour (red, green, blue) {
return "#" + zeroize (hex (red)) + zeroize (hex (green)) + zeroize (hex (blue));
}
function printArc () {
var width = cnvArc.width, height = cnvArc.height, context = cnvArc.getContext ("2d"), imageData = context.getImageData (0, 0, width, height), data = imageData.data, coordinates = new Array (), cluster = "", i, red, green, blue, colour, index, x, y;
for (i = 0; i < data.length; i += 4) {
red = data [i];
green = data [i + 1];
blue = data [i + 2];
colour = getColour (red, green, blue);
index = i / 4;
y = parseInt (index / width, 10);
x = index % width;
if (x == 0) {
//console.log (y + " " + cluster);
cluster = "";
}
cluster += x + ":" + colour + " ";
if (colour == "#00ff00") {
coordinates.push (new Array (x, y));
}
}
return coordinates;
}
function sortCoordinates (coordinates, direction) {
var i = 0, flag, j, coordinate;
do {
flag = false;
for (j = 0; j < coordinates.length - 1 - i; j ++) {
if (direction && (coordinates [j] [0] > coordinates [j + 1] [0] || coordinates [j] [0] == coordinates [j + 1] [0] && coordinates [j] [1] > coordinates [j + 1] [1]) || ! direction && (coordinates [j] [0] < coordinates [j + 1] [0] || coordinates [j] [0] == coordinates [j + 1] [0] && coordinates [j] [1] > coordinates [j + 1] [1])) {
coordinate = coordinates [j];
coordinates [j] = coordinates [j + 1];
coordinates [j + 1] = coordinate;
flag = true;
}
}
i ++;
} while (flag);
}
function drawArrow (x0, y0, x1, y1) {
var context = cnvArc.getContext ("2d"), colour = "#00ff00", angle = (x1 - x0) / (y1 - y0);
context.strokeStyle = colour;
context.fillStyle = colour;
context.setLineDash ([3, 3]);
context.beginPath ();
context.arc (x0, y0, 1, 0, 2 * Math.PI);
context.translate (0, 0, 0);
context.moveTo (x0, y0);
context.lineTo (x1, y1);
context.fill ();
context.stroke ();
context.save ();
context.translate (x1, y1);
angle = Math.atan (angle);
context.rotate ((y1 >= y0 ? 0 : Math.PI) - angle);
context.lineTo (- 3, - 9);
context.lineTo (0, - 3);
context.lineTo (3, - 9);
context.lineTo (0, 0);
context.fill ();
context.restore ();
context.closePath ();
}
function initialize () {
var array = locateO (), x0 = array [0], y0 = array [1], x1 = array [2], y1 = array [3], width = array [4], direction = x1 > x0, coordinates, length, coordinate0, coordinate1, x2, y2, x3, y3;
drawArc (x0, y0, width);
coordinates = printArc ();
length = coordinates.length;
sortCoordinates (coordinates, direction);
coordinate0 = coordinates [length - 2];
x2 = coordinate0 [0];
y2 = coordinate0 [1];
coordinate1 = coordinates [length - 1];
x3 = coordinate1 [0];
y3 = coordinate1 [1];
drawArrow (x2, y2, x3, y3);
slantArc (x0, y0, x1, y1);
}
</script>
</head>
<body style = "margin: 0;" onload = "initialize ()">
<span id = "spnA" style = "left: 50px; top: 150px;"></span>
<span id = "spnB" style = "left: 850px; top: 350px;"></span>
<span id = "spnO"></span>
<canvas id = "cnvArc" style = "position: absolute; background-color: rgb(255, 255, 0, 0.01); z-index: 1; transform-origin: 0 100%;"></canvas>
</body>
</html>
復制進來的代碼都不帶縮進的嗎?
該代碼純手寫,不從第三方處盜用.僅供參考.