Deviceful BETA

Deviceful Documentation

1Installation

We recommend using npm to add Deviceful to your project. Be sure to follow the next steps too.


    # Using npm
    npm i deviceful
      

2Configure

Deviceful comes with a folder of mandatory assets, these assets are available within the package. The easiest way to make use of these is to use Webpack along with copy-webpack-plugin which will automatically copy these assets to your own public folder.


    const CopyWebpackPlugin = require("copy-webpack-plugin");
    ...
    new CopyWebpackPlugin([
    {
        from: "node_modules/deviceful/public",
        to: "public",
    },
  

If you would prefer not to use Webpack, be sure to copy the contents inside node_modules/deviceful/public into your own public folder in the root of your project.

Confused? Check out these starter packs

non-npm starter npm starter with Webpack

3Initiate

Once you've installed Deviceful into your project, simply import it and create a new Deviceful class.


    import Deviceful from "deviceful";

    const device = new Deviceful({...});

    device.mount();
          

By default, Deviceful will try and find a #deviceful element to append the canvas into. However, we recommend giving Deviceful a parent for more control.


    ...
    const device = new Deviceful({
      parent: '.main-laptop'
    });

    // Start your Deviceful instance by running the mount() method

    device.mount();
          

4Basic configuration

There are a few things that need to be configured for Deviceful to work. A link to your design screenshot, the screenshots image height, and the device you want to display it in (default is 'laptop').

Basic laptop


    ...
    const device = new Deviceful({
      parent: '.docs-laptop',
      device: 'laptop',
      screenshot: './link/to/screenshot.jpg',
      screenshotHeight: 2402
    });
          

Important The best size for the laptop is 1440x900px for a full screen, non scrolling screenshot. If the screenshot is designed to scroll, the width would be 1440px and the height would be any height, but set within the Deviceful class as seen above.

Basic phone


    ...
    const device = new Deviceful({
      parent: '.docs-phone',
      device: 'phone',
      screenshot: './link/to/screenshot.jpg',
      screenshotHeight: 2792
    });
          

Important The best size for the phone is 414x790px for a full screen, non scrolling screenshot. If the screenshot is designed to scroll, the width would be 414px and the height would be any height, but set within the Deviceful class as seen above.

5Basic animation

Using a laptop as an example, here are a few ways to animate the device in a basic way.


    // Open and close the device, this works for the laptop only.

    device.open(); 
    device.close(); 

    // Swivel the device

    device.swivel({
      to: -30, // Degrees to swivel to
      duration: 600, // in milliseconds
      easing: 'swingTo' // A full list of available easing options is found in the Advanced Animations section below
    });

    // Scroll the screenshot

    device.scroll({
      direction: 'down', // 'up' or 'down'
      duration: 2000, // in milliseconds
      easing: 'easeOutQuad' // default
    })
              

You can call these at any point via functions, for this example, let's use buttons. These can of course be combined and called at the same time.

6Advanced Animations

Animation Tracks

Along with basic animations, you can write your own animations to play via functions, or on load.

Advanced animations use the device.animate() method. This method MUST take an array of objects, even if you're just providing one single object. Each object in this array can be considered an animation track that animates either the model or the camera, providing either a rotation movement or a position movement, along the axis you choose.

A single animation track looks like this, this object includes all available properties of a single animation track. Looking closely, this is the same animation as using the device.swivel() shorthand, in that it rotates the model on the Y axis.


    {
      object: 'model',
      move: 'rotation',
      axis: 'y',
      to: -30,
      duration: 1000,
      easing: 'swingTo',
      delay: 0 // optional
    }
                    

Instead of using the to property, you can instead use from. This will teleport the object to the from position, and animate it to it's current position. This is useful for animations that run when the device loads, as it will end up in the default position instead of animating to a new position. With that in mind, here's a full animation using that technique.

Creating an array of these animation tracks will create a custom animation. Here's one we will call driveIn. All of these animation tracks will run at the same time as a single, fluid animation.


    ...
    const driveIn = [
    {
      object: "model", // Swivel the device from -30 to 0 degrees
      move: "rotation",
      axis: "y",
      duration: 1500,
      easing: "swingTo",
      from: -30,
    },
    {
      object: "camera", // Move the camera down by 3 units
      move: "position",
      axis: "y",
      duration: 2000,
      easing: "easeOutQuad",
      from: 3,
    },
    {
      object: "camera", // Move the camera forward by 20 units
      move: "position",
      axis: "z",
      duration: 2000,
      easing: "easeOutQuad",
      from: 20,
    },
    {
      object: "camera", // Rotate the camera on the X axis from -5 to 0 degrees
      move: "rotation",
      axis: "x",
      duration: 2000,
      easing: "easeOutQuad",
      from: -5,
    },
  ],

  // To use that animation by calling it:

  device.animate(driveIn);

  // To use an animation on load, set it as the onLoadAnimation in the Deviceful configuration

  const device = new Deviceful({
    parent: '.advanced-laptop',
    screenshot: ...,
    screenshotHeight: ...,
    onLoadAnimation: driveIn

  })
            

Note: A from animation WON'T run a track if that axis, model and movement combination is currently being used. For that reason, mixing to and from animation tracks in the same animation can have strange side effects if the user is able to interfere with an animation (for instance running it again via a button).

Remember the home page? The phone on the home page is a great example of custom animations at work. Check out the Deviceful starter project to see the code behind that animation.

Check out these starter packs

non-npm starter npm starter with Webpack

Compounding animations

Animations don't have to be absolute values, you can create a compounding animation track that will add or subtract a value to it's current value, for instance:


    const bumpRotation = [
    {
        object: 'model',
        movement: 'rotation',
        axis: y,
        to: 36,
        easing: 'easeOutQuad',
        compound: true
    }]

    // The swivel shorthand can be a compound too

    device.swivel({
        compound: true
    });
                        
                    

Careful, Compounding animations will always run from the current location, this means that rotating in 90 degree increments won't always land you back at 0 degrees on the fourth click if the function is rerun (...the button spammed...) before the animation is completed. Best not to give your users too much control over these ones.

Available easing options

  • linear
  • easeInQuad
  • easeOutQuad
  • easeInOutQuad
  • easeInCubic
  • easeOutCubic
  • easeInOutCubic
  • easeInQuart
  • easeOutQuart
  • easeInOutQuart
  • easeInQuint
  • easeOutQuint
  • easeInOutQuint
  • easeInSine
  • easeOutSine
  • easeInOutSine
  • easeInExpo
  • easeOutExpo
  • easeInOutExpo
  • easeInCirc
  • easeOutCirc
  • easeInOutCirc
  • easeOutBounce
  • easeInBack
  • easeOutBack
  • easeInOutBack
  • elastic
  • swingFromTo
  • swingFrom
  • swingTo
  • bounce
  • bouncePast
  • easeFromTo
  • easeFrom
  • easeTo

7Things you need to know

Your responsive breakpoints and the canvas

Deviceful renders a 3D environment inside a canvas. This canvas is automatically added to the parent element you provide. There are a couple things to know about how this environment will respond to the viewport. Unlike an image or a block element, the device will scale in size only when the height of the parent changes. So the basic rule of thumb is, set the width of the parent to 100%, and the height should change in your @media breakpoints.

Careful, never directly adjust the size of the canvas element itself.

The background

The canvas renders with a transparent background, so your background color is simply color of the parent element set via CSS.

8All the extras

Here's a full list of the Deviceful options

Properties


    const device = new Deviceful({
      parent: "#deviceful",     // The parent element
      device: "laptop",         // Either 'phone' or 'laptop'
      screenshot: '',           // A path to your screenshot
      screenshotHeight: 900,    // The height of the screenshot in pixels
      initialDeviceRotation: 0, // Rotate the device on the Y axis (regardless of loading animation)
      initialDevicePosition: 0, // Offset the device on the X axis, handle with care, you may find responsiveness more diffcult
      enableFloor: true,        // You can disable this to remove the floor shadow
      cameraDistance: null,     // Overrides the camera distance if set. Default camera distance is 27
      cameraHeight: null,       // Overrides the camera height if set. Default camera distance is -2
      onLoadAnimation: null,    // Takes an array of animation tracks, see Advanced Animation for more.
      toggleSpeed: 1,           // Factor for open() and close(), 0.5 will be half as fast
      openOnLoad: true,         // By default, the laptop opens when its loaded
      scrollOnLoad: null,       // Takes an animation track object: {direction: 'down', duration: 2000}
      autoHeight: false,        // Experimental! Automatically adjust the height by a recommended ratio
      
    })
            

Methods



    // All methods are shown with defaults and/or alternative options

    // Scroll the screenshot

    device.scroll({
        direction: "down",      // or "up"
        duration: 1000,         // in milliseconds
        easing: 'easeOutQuad'   // see Advanecd Animations for a list of available easings
    });

    // Swivel the device

    device.swivel({
        to: -30, // in degrees
        duration: 1000 // in milliseconds
    });

    // Open and close the device (laptop only)

    device.open();
    device.close();

    /**
     * Create tables in the console that display the model and cameras position and rotation
     * Useful for debugging or writing animations
     */

     device.getCurrentPositions();

     /**
     * Takes an array of animation track objects, learn more in the Advanced Animations section
     */

     device.animate();


          

Deviceful is not free, but it is non-restrictive. Please pay for it if you try it, like it and find it useful for your project.