5

I am using the code showed below to create 46 small circles within a wrapper (div) draw-shapes;

let elem = document.getElementById('draw-shapes');
let params = { width: 1024, height: 768 };
let two = new Two(params).appendTo(elem);

for (let i = 1; i < 47; i++) {
  circle = two.makeCircle(x, y, radius);
  circle.fill = 'green';
  circle.stroke = 'white';
  circle.linewidth = 1;
  circle.id = i;
}

All drawings are made with the Two.js library. I read in the documentation I can change the id of the created element, but I also need to assign a class to each element. I have tried everything from pure js setAttribute to jQuery .attr and .addClass methods, but none of them worked, so I started to wonder if this is even possible to do? If someone knows a way, please let me know how. Thank.

Jakub Moz
  • 127
  • 10
  • Post at least one of the attempts you made and someone can help you find out what went wrong. – user2314737 Feb 23 '19 at 09:44
  • 1
    Maybe the issue is related to this one? https://stackoverflow.com/questions/35399675/add-an-html-class-to-a-dom-element-controlled-by-two-js – Vladimir Bogomolov Feb 23 '19 at 09:45
  • Possible duplicate of [Add an HTML class to a DOM element controlled by two.js](https://stackoverflow.com/questions/35399675/add-an-html-class-to-a-dom-element-controlled-by-two-js) – AndrewL64 Feb 23 '19 at 09:46
  • @AndrewL64 what you mean? It's Two.js so the html is just
    ??
    – Jakub Moz Feb 23 '19 at 10:08

1 Answers1

2

There is not internal utility or property to get to the DOM node of each Two element.

But the id you specify is indeed added as two-<specified-id> to the actual node.

So you can use the normal document.getElementById.

So in your case

let elem = document.getElementById('draw-shapes');
let params = {
  width: 300,
  height: 300
};
let two = new Two(params).appendTo(elem);

for (let i = 1; i < 20; i++) {
  const circle = two.makeCircle(i * 10, i * 10, 40);
  circle.fill = 'green';
  circle.stroke = 'white';
  circle.linewidth = 1;
  circle.id = `two-circle-${i}`;
}
two.update();

// add classname to every fifth element;
for (let i = 1; i < 20; i += 5) {
  const circleNode = document.getElementById(`two-circle-${i}`);
  circleNode.classList.add('classname');

  circleNode.addEventListener('mouseover', function() {
    const path = two.scene.getById(this.id)
    path.scale = 1.2;
    two.update();
  });

  circleNode.addEventListener('mouseout', function() {
    const path = two.scene.getById(this.id)
    path.scale = 1;
    two.update();
  });
}
.classname {
  stroke-width: 5;
  stroke: red;
  fill:yellow;
  cursor:pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/two.js/0.6.0/two.js"></script>

<div id="draw-shapes"></div>
Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • I am getting error -> uncaught TypeError: Cannot read property 'classList' of null when using your example. – Jakub Moz Feb 23 '19 at 10:07
  • @JakubMoz indeed. You need to call `update` before the nodes are in the DOM. Updated code with a working example. – Gabriele Petrioli Feb 23 '19 at 10:20
  • Worked like a charm. Thank you. – Jakub Moz Feb 23 '19 at 15:20
  • Just a quick question. I wanted to add a class to these elements, because I wanted to add box-shadow or drop-shadow to them to create an effect of outer glow, but none box-shadow: or filer: drop-shadow(); works in the css. – Jakub Moz Feb 23 '19 at 16:03
  • @JakubMoz see https://stackoverflow.com/questions/6088409/svg-drop-shadow-using-css3 for applying drop shadow. (*you need to do it through svg, not CSS*) – Gabriele Petrioli Feb 23 '19 at 21:57
  • Thanks, but I managed to do it via css with only adding drop-shadow to the svg element in css. – Jakub Moz Feb 24 '19 at 00:22
  • @JakubMoz cool. that will only work on chrome and firefox though, right ? – Gabriele Petrioli Feb 24 '19 at 00:41
  • Firefox, Chrome, Opera, Edge, IE 11, IE 10 and can't test on lower IE because I can't install it on Win10 – Jakub Moz Feb 24 '19 at 01:38
  • I will just quickly ask here instead of posting another question. Is there a way to scale the circle on hover without breaking the position? Like on this picture https://i.imgur.com/ejhHL7M.png on hover circle I want it to be like 20% or 30% . I have tried transform:scale(1.3); but it breaks the position even with transform origin it doesn't work. – Jakub Moz Feb 24 '19 at 02:10
  • @JakubMoz use the [`.scale`](https://two.js.org/#path-scale) property of the Two.js paths. Updated answer with the functionality. – Gabriele Petrioli Feb 24 '19 at 08:50
  • Thank you for the answer. Do I have the ability to scale specific path circle like some circles for ex 5,6,7 should have different scale on hover than others. – Jakub Moz Feb 24 '19 at 13:27
  • I ended up adding separate div behind the whole two scene and using jquery.hover() I detect position on hovered element and place the div at the same position stimulating hover effect. I think it's even better because I am not setup/redraw the whole scene each time I hover an element which will consume lots of cpu because I have like 500+ nodes and that much lines. – Jakub Moz Feb 24 '19 at 18:14