Как нарисовать фигуру(многоугольник, линию) поверх изображения d3.js
Вот в чем вопрос: как нарисовать изображение (картинку) (1.png) или (1.jpg), а поверх неё многоугольник?(прямую).Вот мой код:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<style>
html,body{
overflow-y:hidden;
}
</style>
</head>
<body>
<script>
var R1=360.0;
var R2=300.0;
var R3=220.0;
var delta=400.0;
var p=(2*Math.PI)/366;
var x1 = [366+1];
var y1 = [366+1];
var x2 = [366+1];
var y2 = [366+1];
var x3 = [366+1];
var y3 = [366+1];
for(var i=0;i<=367;i++){
y1[i]=R1*(Math.sin(i*p))+delta;
x1[i]=R1*(Math.cos(i*p))+delta;
y2[i]=R2*(Math.sin(i*p))+delta;
x2[i]=R2*(Math.cos(i*p))+delta;
y3[i]=R3*(Math.sin(i*p))+delta;
x3[i]=R3*(Math.cos(i*p))+delta;
}
var a="111";
var b="12";
var c="131";
var d="23";
var e="33";
var f="48";
var W1="";
var canvas = d3.select("body")
.append("svg")
.attr("height", 1366)
.attr("width", 800);
for (var i =0;i<=365;i++){
var W=[8];
W[0]=(x1[i]).toString();
W[1]=(y1[i]).toString();
W[2]=(x1[i+1]).toString();
W[3]=(y1[i+1]).toString();
W[4]=(x2[i+1]).toString();
W[5]=(y2[i+1]).toString();
W[6]=(x2[i]).toString();
W[7]=(y2[i]).toString();
var
//W1="55,55 100,100 300,555 777,888"; Такой формат должен быть везде.
W1=(W[0]+","+W[1]+" "+W[2]+"," +W[3]+" "+W[4]+","+W[5]+" "+W[6]+","+W[7]);//Здесь уже все работает
canvas.append("polygon")
.attr("points", W1)
.style("fill", "yellow")
.style("stroke", "black")
.style("strokeWidth", "5px");
}
var polygon=canvas.append("polygon")
.attr("points", [a,b,c,d,e,f])
.style("fill", "blue")
.style("stroke", "black")
.style("strokeWidth", "10px")
// while(true){
//
window.addEventListener("wheel", function(ev) {
var dir = Math.sign(ev.deltaY);
if(dir==1){
a+=dir;
b+=dir;
c+=dir;
e+=dir;
f+=dir;
}
else if(dir==-1){
a=a-1;
b=b-1;
c=c-1;
e=e-1;
f=f-1;
}
polygon.attr("points", [a,b,c,d,e,f]);
});
</script>
</body>
Ответы (3 шт):
Автор решения: Stranger in the Q
→ Ссылка
Вот, наверное как-то так:
let points = [];
let transform = {};
let dragged = null;
let selected = points[points.length-1];
let line = d3.line().curve(d3.curveLinear);
let svg = d3.select("svg");
let img = d3.select("svg image");
let canvas = svg.append('g');
let path = canvas.append("path")
.datum(points);
svg.on("mousedown", mousedown)
.on("mousemove", mousemove)
d3.select(window)
.on("mouseup", mouseup)
.on("resize", adjustSize);
window.oncontextmenu = () => false;
svg.call(createZoom());
adjustSize();
redraw();
function toggleElement(selector, isVisible) {
return d3.select(selector)
.node()
.classList
.toggle('hidden', isVisible)
}
function applyTransform() {
transform = d3.event.transform;
canvas.attr("transform", transform);
}
function createZoom() {
return d3.zoom()
.filter(() => d3.event.button === 2)
.scaleExtent([1, 1])
.on("zoom", applyTransform);
}
function adjustSize() {
let w = window.innerWidth;
let h = window.innerHeight;
svg.attr("viewBox", `0 0 ${w} ${h}`);
}
function redraw() {
canvas.select("path").attr("d", line);
var circle = canvas.selectAll("circle.knob")
.data(points, d => d);
circle.exit().remove();
let newNodes = circle.enter()
.append("circle")
.classed('knob', true)
.attr("r", 1e-6)
.on("mousedown", d => {
selected = dragged = d;
redraw();
})
.on("dblclick", deletePoint)
.transition()
.duration(250)
.attr("r", 6.5);
circle.merge(newNodes)
.classed("selected", d => d === selected)
.attr("cx", d => d[0])
.attr("cy", d => d[1]);
if (d3.event) {
d3.event.preventDefault();
d3.event.stopPropagation();
}
}
function mousedown() {
if (d3.event.button !== 0)
return;
points.push(selected = dragged =
d3.mouse(canvas.node()));
redraw();
}
function mousemove() {
if (!dragged)
return;
let m = d3.mouse(canvas.node());
dragged[0] = m[0];
dragged[1] = m[1];
redraw();
}
function mouseup() {
if (!dragged)
return;
mousemove();
dragged = null;
}
function deletePoint(d) {
if (!selected)
return;
let i = points.indexOf(selected);
points.splice(i, 1);
selected = points.length ?
points[i > 0 ? i - 1 : 0] : null;
redraw();
}
body,svg{
position: absolute;
margin: 0;
width: 100vw;
height: 100vh;
overflow: hidden;
}
path {
fill: none;
stroke-width: 3.2;
stroke: red;
}
circle {
pointer-events: all;
stroke: red;
stroke-width: 1.5px;
fill: #fff;
fill-opacity: .2;
cursor: pointer;
}
.selected {
fill: #ff7f0e;
stroke: #ff7f0e;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
<image xlink:href="https://picsum.photos/800/800" width=800 height=800 />
</svg>
Автор решения: Stranger in the Q
→ Ссылка
Вы про это?
<svg width=400 height=400 >
<image xlink:href="https://picsum.photos/id/58/400/400" width=400 height=400 />
<rect x=100 y=50 width=200 height=200 fill=none stroke=red></rect>
</svg>
Автор решения: Arthur Alunts
→ Ссылка
Нашел ура, спасибо. добаление картинки 1.svg, которая лежит рядом с js файлом.
<!DOCTYPE html>
<meta charset="utf-8">
<title>My_Calendar_Project_v_1.0.0.0 </title>
<html>
<script src="https://d3js.org/d3.v5.min.js"></script>
<body>
<script>
var canvas = d3.select("body")
.append("svg")
.attr("height", 1024)// размеры
.attr("width", 768)// размеры
var image1=canvas.append("svg:image")
// .attr("xlink:href", "1.svg")
.attr("xlink:href", "https://picsum.photos/id/58/400/400")
.attr("x",0) //отступ
.attr("y",0) //отступ
var polygon24=canvas.append("polygon")
for(var i=0;i<=24;i++){
polygon24=canvas.append("polygon")
.attr("points", [100,100,200,200,32,102])
.style("fill", "yellow")
.style("stroke", "black")
.style("strokeWidth", "1px")
}
</script>
</html>