Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

HTML

            
              <svg width="202px" height="202px" viewBox="0 0 202 202" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <path fill="none" d="M201,1 L201,201 L1,201 L1,1 L201,1 Z M53.27053,71 L37.6666667,71 L37.6666667,134.333333 L53.27053,134.333333 L53.27053,86.6038647 C59.2367133,86.879227 66.1207733,91.1014493 66.1207733,99.9130433 L66.1207733,134.333333 L80.4396133,134.333333 L80.4396133,99.9130433 C80.4396133,91.1014493 87.32367,86.879227 93.2898567,86.6038647 L93.2898567,134.333333 L110.63768,134.333333 L110.63768,86.6038647 C116.603863,86.879227 123.487923,91.1014493 123.487923,99.9130433 L123.487923,134.333333 L137.806763,134.333333 L137.806763,99.9130433 C137.806763,91.1014493 144.69082,86.879227 150.657003,86.6038647 L150.657003,134.333333 L166.26087,134.333333 L166.26087,71 L150.657003,71 C142.120773,71 133.859903,75.589372 130.647343,80.178744 C127.434783,75.589372 119.173913,71 110.63768,71 L93.2898567,71 C84.7536233,71 76.4927533,75.589372 73.2801933,80.178744 C70.0676333,75.589372 61.8067633,71 53.27053,71 Z" stroke="#979797"></path>
</svg>
<a href="https://muffinman.io/javascript-keyboard-easter-egg">Read the blog post</a>
            
          
!

CSS

            
              svg {
  display: none;
}

canvas {
  display: block;
}

a {
  font-family: Helvetica, Arial, sans-serif;
  font-size: 15px;
  padding: 10px 16px;
  display: block;
  position: fixed;
  bottom: 0;
  right: 0;
  color: #ddd;
  transition: all 0.25s;
}

a:hover {
  color: #3498db;  
}

            
          
!

JS

            
              // --- Init threejs scene
// ----------------------

const scene = new THREE.Scene();

const ratio = window.innerWidth / window.innerHeight;
const renderer = new THREE.WebGLRenderer({ antialias: true });

renderer.setSize(window.innerWidth, window.innerHeight);

const camera = new THREE.PerspectiveCamera(100, ratio, 0.01, 1000);
camera.position.z = 300;

document.querySelector("body").appendChild(renderer.domElement);

// Resize and update camera
window.addEventListener('resize', function(e) {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(window.innerWidth, window.innerHeight);
});

// Axes helper
const axesHelper = new THREE.AxesHelper(500);
scene.add(axesHelper);



// --- Main part, load and parse SVG
// ---------------------------------

const svgMarkup = document.querySelector('svg').outerHTML;

// SVG Loader is not a part of the main three.js bundle 
// We need to load it separately, it is included in this pen's Settings > JavaScript
// https://threejs.org/docs/#examples/en/loaders/SVGLoader
const loader = new THREE.SVGLoader();
const svgData = loader.parse(svgMarkup);

// Group we'll use for all SVG paths
const svgGroup = new THREE.Group();
// When importing SVGs paths are inverted on Y axis
// it happens in the process of mapping from 2d to 3d coordinate system
svgGroup.scale.y *= -1;

const material = new THREE.MeshNormalMaterial();

// Loop through all of the parsed paths
svgData.paths.forEach((path, i) => {
  const shapes = path.toShapes(true);

  // Each path has array of shapes
  shapes.forEach((shape, j) => {
    // Finally we can take each shape and extrude it
    const geometry = new THREE.ExtrudeGeometry(shape, {
      depth: 20,
      bevelEnabled: false
    });

    // Create a mesh and add it to the group
    const mesh = new THREE.Mesh(geometry, material);

    svgGroup.add(mesh);
  });
});

// Meshes we got are all relative to themselves
// meaning they have position set to (0, 0, 0)
// which makes centering them in the group easy

// Get group's size
const box = new THREE.Box3().setFromObject(svgGroup);
const size = new THREE.Vector3();
box.getSize(size);

const yOffset = size.y / -2;
const xOffset = size.x / -2;

// Offset all of group's elements, to center them
svgGroup.children.forEach(item => {
  item.position.x = xOffset;
  item.position.y = yOffset;
});

// Finally we add svg group to the scene
scene.add(svgGroup);



// --- Animation loop
// ------------------

function animate() {
  renderer.render(scene, camera);

  // Rotate out group 
  svgGroup.rotation.y += 0.005;
  
  requestAnimationFrame(animate);
}

animate();

            
          
!
999px

Console