<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Privacy</title> <link rel="stylesheet" href="style5.css"> <style> * { margin: 0; padding: 0; box-sizing: border-box; } html, body { width: 100%; height: 100%; } h3 { color: black; padding-left: 30px; padding-top: 20px; } a:link, a:visited { background-color: #000000; color: white; padding: 14px 25px; text-align: center; text-decoration: none; display: inline-block; } div { height: 20%; text-align: center; font-size: 36px; padding: 20px; } svg { display: block; width: 50%; height: 50%; margin-left:auto; margin-right:auto; } .footer { position: fixed; left: 0; bottom: 0; width: 100%; height: 6%; color: white; background-color: black; text-align: center; } </style> </head> <header><br> <h1>PRIVACY?</h1> <p><span class="blink">Is privacy guaranteed in social networks?</blink></a></p> </header> <body> <br><br> <svg id="canvas" align="center"></svg> </body> <div class="wrapper"> <div class="push"></div> </div> <footer class="footer"><a href="privacy-iframes.html">VIDEOS (4)</a><a href="privacy-iframes.html">ARTICLES (4)</a><a href="privacy-iframes.html">BOOKS (1)</a> <script> //find the element with id =message(in dom), return via function: document.getelementbyid, store it in var var svg = document.getElementById('canvas'); var padding = 15; var circleRadius = 15; /** * Returns a random number between min (inclusive) and max (exclusive) * from: https://stackoverflow.com/questions/1527803/generating-random-whole-numbers-in-javascript-in-a-specific-range */ function getRandomArbitrary(min, max) { return Math.floor(Math.random() * (max - min) + min); } /** * Returns randomly either "true" or "false" with 50% chance for each one. * @returns {boolean} */ function getRandomBoolean() { return getRandomArbitrary(0, 2) === 1; } //when we execute sleep (...ms), program waits for (...ms) function sleep(time) { return new Promise(resolve => { setTimeout(() => { resolve(); }, time); }); } //The parseInt() function parses a string argument and returns an integer of the specified size of svg in pixels function pickARandomCirclePosition() { var w = parseInt(window.getComputedStyle(svg).width); var h = parseInt(window.getComputedStyle(svg).height); var x = getRandomArbitrary(padding + circleRadius, w - circleRadius - padding); var y = getRandomArbitrary(padding + circleRadius, h - circleRadius - padding); //return an object which has 2 properties, named x,y and value the value of var x,y return { x: x, y: y }; } //======================================================================// // new code 2019.03.02: const messages = [ "FOSDEM video", "BBC article", "INSTITURE OF NETWORK CULTURES article", "DMYTRI KLEINER video", "MASTODON video", "LAINBLOG article", "RADICAL NETWORKS Scuttlebutt video", "MANUEL CASTELLS PRESS book", "HOMEBREWSERVER article" ]; const clickedCircles = []; const links = []; const positions = []; class Question { constructor(text) { // Create property "text". this.text = text; const position = pickARandomCirclePosition(); /*const position = positionsFromJson[positionFromJsonIndex++];*/ positions.push(position); const htmlCircle = this.createCircle(position); const htmlText = this.createText(position, text); const onMouseenterShowText = () => { htmlText.style.display = 'block'; }; const onMouseleaveHideText = () => { htmlText.style.display = 'none'; }; htmlCircle.addEventListener('mouseleave', onMouseleaveHideText); htmlCircle.addEventListener('mouseenter', onMouseenterShowText); htmlCircle.addEventListener('mouseenter', () => { htmlCircle.style.fill = 'red'; }); htmlCircle.addEventListener('mouseleave', () => { htmlCircle.style.fill = 'black'; }); /*htmlCircle.addEventListener('click', () => { htmlText.style.display = 'block'; htmlCircle.removeEventListener('mouseenter', onMouseenterShowText); htmlCircle.removeEventListener('mouseleave', onMouseleaveHideText); });*/ htmlCircle.addEventListener('click', () => { //if(!clickedCircles.includes(htmlCircle)) { clickedCircles.push(htmlCircle); //} this.linkClickedWithPreviouslyClicked(); //this.linkClickedWithAllPreviouslyClicked(); }); } createCircle(position) { const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); circle.style.fill = 'black'; circle.setAttribute('cx', position.x); circle.setAttribute('cy', position.y); circle.setAttribute('r', circleRadius); svg.appendChild(circle); return circle; } createText(position, textContent) { const text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); text.setAttribute('x', position.x + 2*circleRadius); text.setAttribute('y', position.y + circleRadius/2); text.textContent = textContent; text.style.display = 'none'; text.style.fontStyle = "italic"; text.style.fontStyle = "italic"; text.style.fontFamily = "Courier"; text.style.fontWeight = "bold"; text.style.fontSize = "large"; svg.appendChild(text); return text; } createLine(position1, position2) { const line = document.createElementNS('http://www.w3.org/2000/svg', 'line'); line.setAttribute('x1', position1.x); line.setAttribute('y1', position1.y); line.setAttribute('x2', position2.x); line.setAttribute('y2', position2.y); line.setAttribute('stroke', 'black'); svg.appendChild(line); return line; } linkClickedWithPreviouslyClicked() { const length = clickedCircles.length; if(length < 2) { return; } const circle1Pos = this.getCircleCenterPosition(clickedCircles[length - 1]); const circle2Pos = this.getCircleCenterPosition(clickedCircles[length - 2]); if(this.linkAlreadyExists(circle1Pos, circle2Pos)) { return; } const htmlLine = this.createLine(circle1Pos, circle2Pos); links.push(this.getLinkAsString(circle1Pos, circle2Pos)); } getCircleCenterPosition(htmlCircle) { return { x: htmlCircle.cx.baseVal.value, y: htmlCircle.cy.baseVal.value, }; } getLinkAsString(circle1Pos, circle2Pos) { const pos1AsString = circle1Pos.x + "," + circle1Pos.y; const pos2AsString = circle2Pos.x + "," + circle2Pos.y; const linkAsString = pos1AsString + "-" + pos2AsString; return linkAsString; } linkAlreadyExists(circle1Pos, circle2Pos) { return links.includes(this.getLinkAsString(circle1Pos, circle2Pos)); } } async function network() { for(let i = 0; i < messages.length; i++) { const message = messages[i]; new Question(message); //"await" works only inside async functions const delayBetweenQuestionCreations = 50; await sleep(delayBetweenQuestionCreations); } console.log(JSON.stringify(positions)); } network(); </script> </html>