Branding option for Cubik using links of a network diagram inside letters, extension from previous version.
Based on the force-directed graph and applying a linear gradient. In addition use of SVG text as a clipping mask.
Branding option for Cubik using links of a network diagram inside letters, extension from previous version.
Based on the force-directed graph and applying a linear gradient. In addition use of SVG text as a clipping mask.
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <style> | |
| svg { | |
| background-color: #1e1e23; | |
| } | |
| .links line { | |
| stroke: url(#gradient); | |
| } | |
| #alpha { | |
| fill: rgb(255,255,255); | |
| } | |
| #base { | |
| fill: #1e1e23; | |
| mask: url(#mask); | |
| } | |
| .title { | |
| font-family: 'Open Sans', sans-serif; | |
| font-size: 16em; | |
| text-anchor: middle; | |
| } | |
| .outline { | |
| fill:none; | |
| stroke: url(#gradient); | |
| stroke-width: 2px; | |
| } | |
| </style> | |
| <svg width="960" height="500"></svg> | |
| <script src="https://d3js.org/d3.v4.0.0-alpha.40.min.js"></script> | |
| <script> | |
| var svg = d3.select("svg"), | |
| width = +svg.attr("width"), | |
| height = +svg.attr("height"), | |
| title = "Cubik", | |
| numberOfNodes = 1000, | |
| logoSquareSize = 63, | |
| logoX = 40, | |
| logoY = 138, | |
| titleX = width * 0.6, | |
| titleY = height * 0.65; | |
| svg.append("linearGradient") | |
| .attr("id", "gradient") | |
| .attr("gradientUnits", "userSpaceOnUse") | |
| .selectAll("stop") | |
| .data([ | |
| {offset: "0%", color: "#ec5f97"}, | |
| {offset: "100%", color: "#f39551"} | |
| ]) | |
| .enter().append("stop") | |
| .attr("offset", function(d) { return d.offset; }) | |
| .attr("stop-color", function(d) { return d.color; }); | |
| var mask = svg.append("defs") | |
| .append("mask") | |
| .attr("id", "mask") | |
| .attr("x", 0) | |
| .attr("y", 0) | |
| .attr("width", "100%") | |
| .attr("height", "100%"); | |
| mask.append("rect") | |
| .attr("id", "alpha") | |
| .attr("width", "100%") | |
| .attr("height", "100%"); | |
| mask.append("text") | |
| .attr("class", "title") | |
| .attr("x", titleX) | |
| .attr("y", titleY) | |
| .text(title); | |
| var maskRect = mask.append("rect") | |
| .attr("class", "mask-logo-rect") | |
| .attr("x", logoX) | |
| .attr("y", logoY) | |
| .attr("height", logoSquareSize) | |
| .attr("width", logoSquareSize); | |
| var simulation = d3.forceSimulation() | |
| .force("link", d3.forceLink().id(function(d) { return d.id; })) | |
| .force("charge", d3.forceManyBody()) | |
| .force("center", d3.forceCenter(width / 2, height / 2)); | |
| var nodes = d3.range(numberOfNodes).map(function(i){ return {id: i}; }); | |
| var links = []; | |
| d3.range(numberOfNodes).forEach(function(i){ | |
| links.push({source: i, target: (i + 1) % numberOfNodes}); | |
| links.push({source: i, target: i * 7 % numberOfNodes}); | |
| }); | |
| var link = svg | |
| .append("g") | |
| .attr("class", "links") | |
| .selectAll("line") | |
| .data(links) | |
| .enter().append("line"); | |
| simulation | |
| .nodes(nodes) | |
| .on("tick", ticked); | |
| simulation | |
| .force("link") | |
| .links(links); | |
| svg.append("rect") | |
| .attr("id", "base") | |
| .attr("width", "100%") | |
| .attr("height", "100%"); | |
| svg.selectAll(".logo-rect") | |
| .data(d3.range(9)) | |
| .enter().append("rect") | |
| .attr("class", "logo-rect outline") | |
| .attr("x", function(d,i){ return i % 3 * logoSquareSize + logoX; }) | |
| .attr("y", function(d,i){ return Math.floor(i / 3) * logoSquareSize + logoY }) | |
| .attr("height", logoSquareSize) | |
| .attr("width", logoSquareSize); | |
| svg.append("text") | |
| .attr("class", "title outline") | |
| .attr("x", titleX) | |
| .attr("y", titleY) | |
| .text(title); | |
| setInterval(moveNodes, 5000); | |
| function ticked() { | |
| link | |
| .attr("x1", function(d) { return d.source.x; }) | |
| .attr("y1", function(d) { return d.source.y; }) | |
| .attr("x2", function(d) { return d.target.x; }) | |
| .attr("y2", function(d) { return d.target.y; }); | |
| } | |
| function moveNodes() { | |
| maskRect | |
| .transition() | |
| .duration(1000) | |
| .attr('x', function(){ return Math.floor( Math.random() * 3) * logoSquareSize + logoX; }) | |
| .attr('y', function(){ return Math.floor( Math.random() * 3) * logoSquareSize + logoY }); | |
| nodes.forEach(function(d){ | |
| d.vx = Math.random() * 2 - 2; | |
| d.vy = Math.random() * 2 - 2; | |
| }); | |
| simulation.alphaTarget(0.1).restart(); | |
| } | |
| </script> |