{"__browser":{"device":"unknown_device","mobile":false,"name":"unknown browser","platform":"unknown_platform","version":"0"},"__constants":{},"__CPDATA":{"domain_iframe":"https://cdpn.io","environment":"production","host":"codepen.io","iframe_allow":"accelerometer; ambient-light-sensor; camera; display-capture; encrypted-media; geolocation; gyroscope; microphone; midi; payment; vr; web-share","iframe_sandbox":"allow-forms allow-modals allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-top-navigation-by-user-activation allow-downloads allow-presentation"},"__graphql":{"data":{"data":{"sessionUser":{"id":"VoDkNZ","name":"Captain Anonymous","title":"Captain Anonymous","avatar":"https://assets.codepen.io/t-1/user-default-avatar.jpg?format=auto&version=0","currentContext":{"id":"VoDkNZ","title":"Captain Anonymous","name":"Captain Anonymous","avatar":"https://assets.codepen.io/t-1/user-default-avatar.jpg?format=auto&version=0","username":"anon","__typename":"User"},"currentTeamId":null,"username":"anon","admin":false,"anon":true,"pro":false,"verified":false,"teams":[],"__typename":"User"}}},"url":"https://codepen.io/graphql","api":"cprails","cpedata":{"action":"show","controller":"live_fullpage"}},"__user":{"anon":true,"base_url":"/anon/","current_team_id":0,"current_team_hashid":null,"hashid":"VoDkNZ","id":1,"itemType":"user","name":"Captain Anonymous","paid":false,"tier":0,"username":"anon","created_at":null,"email_verified":null,"collections_count":0,"collections_private_count":0,"followers_count":0,"followings_count":0,"pens_count":0,"pens_private_count":0,"projects_count":0,"projects_private_count":0},"__firebase":{"config":{"apiKey":"AIzaSyBgLAe7N_MdFpuVofMkcQLGwwhUu5tuxls","authDomain":"codepen-store-production.firebaseapp.com","databaseURL":"https://codepen-store-production.firebaseio.com","disabled":false,"projectId":"codepen-store-production"},"token":"eyJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJodHRwczovL2lkZW50aXR5dG9vbGtpdC5nb29nbGVhcGlzLmNvbS9nb29nbGUuaWRlbnRpdHkuaWRlbnRpdHl0b29sa2l0LnYxLklkZW50aXR5VG9vbGtpdCIsImNsYWltcyI6eyJvd25lcklkIjoiVm9Ea05aIiwiYWRtaW4iOmZhbHNlfSwiZXhwIjoxNjg2Mzk5ODE3LCJpYXQiOjE2ODYzOTYyMTcsImlzcyI6ImZpcmViYXNlLWFkbWluc2RrLThva3lsQGNvZGVwZW4tc3RvcmUtcHJvZHVjdGlvbi5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInN1YiI6ImZpcmViYXNlLWFkbWluc2RrLThva3lsQGNvZGVwZW4tc3RvcmUtcHJvZHVjdGlvbi5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInVpZCI6IlZvRGtOWiJ9.sCzr7wR42KoTxzbh6YU9TlgWn-tLpppdMxtRwXoqzOIJKsRzX1sOzQrHhqeZMTwhZFzbVpHRq48XzfoCrpeaad-jueCwlXkpf2eRAgagXIdelfSCH2IH7X54Fo-DCO9jX7H0wM1WQbdq06vyG8NRK7r-qFhYblEDgsD6a9R579l01ixHd5eHTiv_6x72bIRZrNj3Ok_IcQ6Z4vyhaZCpts2c5s__Q3eSWRNrDXeDzBtadSy7rk1WstaQ1oYNuGmu7iATppUoLFLBJiBJx8ZCliMtAC2VAWFii_y3zx0G_P5j0HzQ4fnltjdzSM70e-LQbHPXUkk4l8WBjLghExjnxw"},"__pay_stripe_public_key":"pk_live_2GndomDfiklqpSNQn8FrGuwZSMIMzha7DkLJqlYe7IR0ihKAlKdiHg68JJc5eVPt68rzAjzAAVXcUwjySHRCsgjQQ00gtRBUFNH","__pay_braintree_env":"production","__item":"{\"id\":49393278,\"user_id\":3685267,\"html\":\"<div id=\\\"container\\\"><\\/div>\",\"css\":\"@import url(\\\"https:\\/\\/fonts.googleapis.com\\/css2?family=Merriweather:wght@700&display=swap\\\");\\nbody {\\n margin: 0;\\n justify-content: center;\\n display: flex;\\n background: #222831;\\n}\\n\\n#container {\\n width: 95vw;\\n height: 55vw;\\n background: #262c35;\\n margin-top: 5vw;\\n position: relative;\\n border-radius: 5px;\\n margin-bottom: 5vw;\\n}\\n\\n.element-name {\\n position: absolute;\\n left: 50%;\\n top: 40%;\\n transform: translate(-50%, -50%);\\n font-size: 1.5vw;\\n font-family: \\\"Merriweather\\\", serif;\\n font-weight: 700;\\n}\\n.element-number {\\n position: absolute;\\n left: 50%;\\n top: 15%;\\n transform: translate(-50%, -50%);\\n font-size: 0.6vw;\\n}\\n\\n.legend {\\n position: absolute;\\n left: 50%;\\n top: 50%;\\n transform: translate(-50%, -50%);\\n font-size: 0.8vw;\\n font-family: \\\"Merriweather\\\", serif;\\n font-weight: 700;\\n}\\n\\n.svg {\\n width: 100%;\\n height: 100%;\\n}\\n\",\"js\":\"let elements;\\nconst { PI, sin, cos, random } = Math;\\nconst TAU = 2 * PI;\\nconst range = (n, m = 0) =>\\n Array(n)\\n .fill(m)\\n .map((i, j) => i + j);\\nconst map = (value, sMin, sMax, dMin, dMax) => {\\n return dMin + ((value - sMin) \\/ (sMax - sMin)) * (dMax - dMin);\\n};\\nconst polar = (ang, r = 1, [x = 0, y = 0] = []) => [\\n x + r * cos(ang),\\n y + r * sin(ang)\\n];\\nconst container = d3.select(\\\"#container\\\");\\n\\nconst setStyle = (el, attrs) =>\\n Object.entries(attrs).reduce((acc, [key, val]) => acc.style(key, val), el);\\nconst setAttrs = (el, attrs) =>\\n Object.entries(attrs).reduce((acc, [key, val]) => acc.attr(key, val), el);\\n\\nconst clipCords = range(6).map((i) => {\\n const ang = map(i, 0, 6, 0, TAU);\\n return polar(ang + PI \\/ 2, 50);\\n});\\nconst clipPathD = `M${[...clipCords, clipCords[0]]\\n .map(([x, y]) => `L${x},${y}`)\\n .join(\\\"\\\")\\n .slice(1)}`;\\n\\nconst svgRoot = container.append(\\\"svg\\\");\\nsetAttrs(svgRoot, { width: \\\"0px\\\", height: \\\"0px\\\" });\\nconst defs = svgRoot.append(\\\"defs\\\");\\nconst clipPath = defs.append(\\\"clipPath\\\");\\nsetAttrs(clipPath, { id: \\\"clipPath\\\" });\\nconst clipPathPath = clipPath.append(\\\"path\\\");\\nsetAttrs(clipPathPath, { d: clipPathD });\\n\\nclass Atom {\\n constructor(parent, color) {\\n this.element = parent.append(\\\"circle\\\");\\n setAttrs(this.element, { cx: 0, cy: 0, r: 4, fill: `${color}88` });\\n\\n this.seed1 = random() * TAU;\\n this.seed2 = random() * TAU;\\n }\\n\\n updatePosition(t) {\\n const cx = 25 * sin(this.seed1 + t);\\n const cy = 25 * sin(this.seed2 + t);\\n setAttrs(this.element, { cx, cy });\\n }\\n}\\n\\nclass Element {\\n constructor(x, y, name, number, phase, color) {\\n this.root = container.append(\\\"div\\\");\\n setStyle(this.root, {\\n width: \\\"5vw\\\",\\n height: \\\"5vw\\\",\\n transform: `translate(${x}vw, ${y}vw)`,\\n position: \\\"absolute\\\"\\n });\\n\\n this.phase = phase;\\n\\n this.svg = this.root.append(\\\"svg\\\");\\n setAttrs(this.svg, { viewBox: \\\"0 0 100 100\\\", class: \\\"svg\\\" });\\n this.group = this.svg.append(\\\"g\\\");\\n setAttrs(this.group, { transform: \\\"translate(50,50)\\\" });\\n\\n this.border = this.group.append(\\\"path\\\");\\n setAttrs(this.border, { d: clipPathD, fill: \\\"none\\\", stroke: `${color}88` });\\n\\n if (phase === \\\"Solid\\\") {\\n this.solid = this.group.append(\\\"rect\\\");\\n setAttrs(this.solid, {\\n x: -50,\\n y: 18,\\n width: 100,\\n height: 60,\\n fill: `${color}88`,\\n style: \\\"clip-path: url(#clipPath)\\\"\\n });\\n }\\n\\n if (phase === \\\"Liquid\\\") {\\n this.liquidPathA = this.group.append(\\\"path\\\");\\n setAttrs(this.liquidPathA, {\\n d: \\\"\\\",\\n fill: `${color}88`,\\n style: \\\"clip-path: url(#clipPath)\\\"\\n });\\n this.liquidPathB = this.group.append(\\\"path\\\");\\n setAttrs(this.liquidPathB, {\\n d: \\\"\\\",\\n fill: `${color}44`,\\n style: \\\"clip-path: url(#clipPath)\\\"\\n });\\n }\\n\\n if (phase === \\\"Gas\\\") {\\n this.atoms = range(5).map(() => new Atom(this.group, color));\\n }\\n\\n this.name = this.root.append(\\\"div\\\").text(name);\\n setAttrs(this.name, { class: \\\"element-name\\\" });\\n setStyle(this.name, { color: `${color}88` });\\n this.number = this.root.append(\\\"div\\\").text(number);\\n setAttrs(this.number, { class: \\\"element-number\\\" });\\n setStyle(this.number, { color: `${color}88` });\\n }\\n\\n update(t, path1, path2) {\\n if (this.phase === \\\"Liquid\\\") {\\n this.updateLiquid(path1, path2);\\n }\\n if (this.phase === \\\"Gas\\\") {\\n this.updateAtoms(t);\\n }\\n }\\n\\n updateLiquid(path1, path2) {\\n setAttrs(this.liquidPathA, { d: path1 });\\n setAttrs(this.liquidPathB, { d: path2 });\\n }\\n\\n updateAtoms(t) {\\n this.atoms.forEach((atom) => {\\n atom.updatePosition(t);\\n });\\n }\\n}\\n\\nconst categoryColors = {\\n \\\"diatomic nonmetal\\\": \\\"#3d7ea6\\\",\\n \\\"noble gas\\\": \\\"#bc6ff1\\\",\\n \\\"alkali metal\\\": \\\"#f05454\\\",\\n \\\"alkaline earth metal\\\": \\\"#ffa36c\\\",\\n metalloid: \\\"#64958f\\\",\\n \\\"polyatomic nonmetal\\\": \\\"#8d93ab\\\",\\n \\\"post-transition metal\\\": \\\"#c0e218\\\",\\n \\\"transition metal\\\": \\\"#fcf876\\\",\\n lanthanide: \\\"#949cdf\\\",\\n actinide: \\\"#16697a\\\"\\n};\\n\\nfunction createElements(data) {\\n elements = data.map((element, index) => {\\n const category = element.category;\\n const name = element.symbol;\\n const number = element.number;\\n const phase = element.phase;\\n const ix = element.xpos;\\n const iy = element.ypos;\\n const x = ix * 4.8 + ((iy + 1) % 2) * 2.5 - 2;\\n const y = iy * 4.5 - 4;\\n const color = categoryColors[category] || \\\"#93abd3\\\";\\n\\n return new Element(x, y, name, number, phase, color);\\n });\\n}\\n\\nlet step = 0;\\n\\nfunction animate() {\\n step = (step + 1) % 100;\\n const t = map(step, 0, 100, 0, TAU);\\n\\n const curve1 = range(10)\\n .map((i) => {\\n const ang = map(i, 0, 10, 0, TAU);\\n const x = map(i, 0, 10, -50, 50);\\n const y = 10 + 4 * sin(ang + t);\\n return `L${x},${y}`;\\n })\\n .join(\\\"\\\");\\n\\n const curve2 = range(10)\\n .map((i) => {\\n const ang = map(i, 0, 10, 0, TAU);\\n const x = map(i, 0, 10, -50, 50);\\n const y = 10 + 6 * sin(ang + t + PI);\\n return `L${x},${y}`;\\n })\\n .join(\\\"\\\");\\n\\n const path1 = `M50,10L50,50L-50,50L-50,10${curve1}`;\\n const path2 = `M50,10L50,50L-50,50L-50,10${curve2}`;\\n\\n elements.forEach((element) => {\\n element.update(t, path1, path2);\\n });\\n\\n requestAnimationFrame(animate);\\n}\\n\\nfetch(\\\"https:\\/\\/assets.codepen.io\\/3685267\\/periodic-table-data.json\\\")\\n .then((response) => response.json())\\n .then((data) => {\\n createElements(data.elements);\\n animate();\\n });\\n\",\"html_pre_processor\":\"none\",\"css_pre_processor\":\"none\",\"js_pre_processor\":\"none\",\"html_classes\":\"\",\"css_starter\":\"neither\",\"js_library\":null,\"created_at\":\"2021-01-07T03:17:10.000Z\",\"updated_at\":\"2021-01-07T03:21:55.000Z\",\"title\":\"Animated Periodic Table\",\"description\":\"Credits : [Periodic table data](https:\\/\\/github.com\\/Bowserinator\\/Periodic-Table-JSON) \",\"slug_hash\":\"oNzyeEv\",\"head\":\"<link rel=\\\"preconnect\\\" href=\\\"https:\\/\\/fonts.gstatic.com\\\">\\n<link href=\\\"https:\\/\\/fonts.googleapis.com\\/css2?family=Bowlby+One+SC&display=swap\\\" rel=\\\"stylesheet\\\">\",\"private\":false,\"slug_hash_private\":\"beddd7039ba00f2819a0de8a0b086143\",\"has_animation\":true,\"team_id\":0,\"css_prefix\":\"neither\",\"template\":false,\"parent_id\":0,\"comments_count\":0,\"custom_screenshot_filename\":null,\"loves_count\":0,\"pick\":false,\"popularity_score\":0,\"views_count\":0,\"pick_visible_at\":null,\"cpid\":\"0176dad9-1af0-713a-9f6a-541a5bf5a0b2\",\"is_new_editor_pen\":false,\"pen_hash\":null,\"hashid\":\"oNzyeEv\"}"}