GithubHelp home page GithubHelp logo

brim's Introduction

Brim

NPM version Bower version

View (minimal-ui) manager for iOS 8.

Try it and tweet it if you like it.

Using Brim with iOS simulator.

Contents

minimal-ui

In iOS 7.1, a property, minimal-ui, has been added for the viewport meta tag key that allows minimizing the top and bottom bars in Safari as the page loads. While on a page using minimal-ui, tapping the top bar brings the bars back. Tapping back in the content dismisses them again.

The minimal-ui viewport property is no longer supported in iOS 8. However, the minimal-ui itself is not gone. User can enter the minimal-ui with a "touch-drag down" gesture.

There are several pre-conditions and obstacles to manage the view state, e.g. for minimal-ui to work, there has to be enough content to enable user to scroll; for minimal-ui to persist, window scroll must be offset on page load and after orientation change. However, there is no way of calculating the dimensions of the minimal-ui using the screen variable, and thus no way of telling when user is in the minimal-ui in advance.

Features

Brim solves all of the issues associated with determining the state of the UI and controlling the persistence. Specifically:

  • Determines when user is in the minimal-ui.
  • Determines when the view changes.
  • Provides a UI to instruct user to enter the minimal-ui.
  • Locks user in the minimal-ui (following the spec defined in the iOS 7.1).
  • Makes the view persist when page is reloaded or device orientation changes.

Setup

You need to create two elements: mask and main. Mask is displayed to the user when page is in the full view. The role of the element is to instruct user to enter the minimal-ui. Main element is shown when mask is hidden.

  • These elements must be direct and sole descendants of <body>.
  • The IDs must be brim-mask and brim-main.
  • Do not apply styling that would affect the position or the dimensions of these elements.

The Underlying Implementation

When page is loaded, Brim will create a treadmill element. Treadmill element is used to give user space to scroll. Presence of the treadmill element ensures that user can enter the minimal-ui view and that it continues to persist if user reloads the page or changes device orientation. It is invisible to the user the entire time. This element has ID brim-treadmill.

Upon loading the page or after changing the orientation, Brim is using Scream to detect if page is in the minimal-ui view (page that has been previously in minimal-ui and has been reloaded will remain in the minimal-ui if content height is greater than the viewport height).

When page is in the minimal-ui, Brim will disable scrolling of the document (it does this in a safe way that does not affect the contents of the main element). Disabling document scrolling prevents accidentally leaving the minimal-ui when scrolling upwards. As per the original iOS 7.1 spec, tapping the top bar brings back the rest of the chrome.

When page is in the full view, Brim will show the mask element.

Quick Start

<!DOCTYPE html>
<html>
<head>
    <script src="./bower_components/scream/dist/scream.js"></script>
    <script src="./bower_components/brim/dist/brim.js"></script>
    <script>
    window.addEventListener('DOMContentLoaded', function () {
        var scream,
            brim;

        scream = gajus.Scream({
            width: {
                portrait: 320,
                landscape: 640
            }
        });

        brim = gajus.Brim({
            viewport: scream
        });
    });
    </script>
</head>
<body>
    <div id="brim-mask">
        <!-- Content displayed to the user when in full view. -->
    </div>
    <div id="brim-main">
        <!-- Content displayed to the user when in minimal view.  -->
    </div>
</body>
</html>

Styling

If mask element does not have active content, it is advisable to disable pointer events:

#brim-mask {
    pointer-events: none;
}

Do not set style that would change position or dimensions of the mask or the main element.

Do not style the treadmill.

Events

viewchange

Invoked on page load and when view changes.

brim.on('viewchange', function (e) {
    // Invoked when view changes.

    // @var {String} 'full', 'minimal'
    e.viewName;
});

Detecting iOS 8

Brim does not have a use case outside of iOS 8, though it does not restrict itself. I recommend using platform.js to target the platform:

if (platform.os.family == 'iOS' && parseInt(platform.os.version, 10) >= 8) {
    // Use Scream & Brim.
}

Download

Using Bower:

bower install brim

Using NPM:

npm install brim

brim's People

Contributors

gajus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

brim's Issues

Combining brim with a 100% width/height canvas seems to disable swipe gesture.

Hi,

I tried using brim together with canvas but it seems like the canvas kills user input.
Reproduce by putting a canvas with 100% width and height inside brim-main, maybe I've missed something obvious here but I can't get it to work. I would like to use brim together with a HTML5 canvas game. Thank you for any help!

User can zoom (pinch-out) the mask element and break brim

Let's consider the brim demo:

when the minimal-ui is disabled and the mask element is displayed the user can do a pinch-out (zoom-in) gesture.

This results in the ui switching to minimal, viewport content being zoomed but brim does not recognize that the UI is not minimal.

Is there a way to let the user scroll the mask element but forbid zoom gesture ?

How to use with ES6

Hi,
I've got some problems to get brim running under ES6. When I import the modules as followed gajun.Scream is undefined. Therefore I cannot init a new instance of Brim:

import Scream from 'scream';
import Brim from 'Brim';

let scream = Scream({
    width: {
        portrait: 320,
        landscape: 640
    }
});

let brim = Brim({
    viewport: scream
});

I get this error message: brim.js:16 Uncaught TypeError: Right-hand side of 'instanceof' is not an object

What is the correct way to use brim with ES6?
Thanks

Use ESHint

Remove "jshint" dev dependency from package.json and the gulp task.

sh:

npm install gulp-eslint --save-dev

gulpfile.js:

var eslint = require('gulp-eslint');

gulp.task('lint', function () {
    return gulp
        .src(['./src/*.js', './src/cinemas/*/*.js', './tests/*.js'])
        .pipe(eslint())
        .pipe(eslint.format())
        .pipe(eslint.failOnError());
});

.eslintrc:

{
    "rules": {
        "no-console": 0,
        "no-extra-parens": 2,
        "no-reserved-keys": 2,
        "no-eq-null": 2,
        "no-extend-native": 2,
        "no-process-env": 2,
        "no-self-compare": 2,
        "no-void": 2,
        "no-warning-comments": [1, { "terms": ["todo", "@toto"], "location": "start" }],
        "vars-on-top": 2,
        "wrap-iife": [2, "inside"],
        "global-strict": [2, "always"],
        "new-cap": 0,
        "no-shadow": 0,
        "no-mixed-requires": 0,
        "no-new-require": 2,
        "brace-style": [2, "1tbs"],
        "comma-style": [2, "last"],
        "func-style": [2, "expression"],
        "no-inline-comments": 2,
        "no-lonely-if": 2,
        "no-multiple-empty-lines": 2,
        "no-nested-ternary": 2,
        "one-var": 2,
        "operator-assignment": [2, "always"],
        "padded-blocks": [2, "never"],
        "quote-props": [2, "as-needed"],
        "quotes": [2, "single"],
        "space-after-keywords": [2, "always"],
        "space-before-blocks": [2, "always"],
        "space-in-brackets": [2, "never"],
        "space-in-parens": [2, "never"],
        "space-unary-ops": [2, { "words": true, "nonwords": false }],
        "spaced-line-comment": [2, "always"],
    },
    "env":{
        "mocha": true,
        "node": true
    }
}

Mask is causing flickering when page is loaded in MAH

Mask is shown on page load. This causes flickering (you can see mask for a millisecond) if page is loaded in MAH. There is no way to know if the page is loaded in MAH until the resize event. This appears to be a bug in Safari. If brim.mask() invocation is wrapped in setImmediate(), then flickering will be as issue when page is loaded not in MAH.

Questions about using brim

Hi Gajus,

Couple of questions about brim:-

  1. In the demo index.html you have the test:-

    || platform.ua.indexOf('like Mac OS X') != –1

    Am I reading this correctly, it allows brim to work even though iOS is < 8? What was your intention? I tried the demo on iphone 4 with iOS 7 and did not get the "This demo has been designed for iOS 8." display.

  2. When you establish the scream variable you declare the width for an iPhone 5s like this:-

    scream = gajus.Scream({
        width: {
            portrait: 320,
            landscape: 568
        }
    });

    Does this have any impact on which devices brim works on? The demo seems to work on my iPad2 which is of course 768x1024. Or do I have to specify/target each device’s resolution somehow? If it's not relevant, can I safely call gajus.Scream() without a config?

Relavant in iOS 9?

Was talking to a colleague about how the CSS vh in iOS 9 now includes the back/forward bottom toolbar and was wondering if the new OS had any meaning to this project. Felt like y'all might know. Thanks in advance!

MeteorJs

I would love to use this for Meteor JS.

How would I do so?

Avoid mask with explanation

We're using iscroll in a project to work around some bugs in Mobile Safari. This disables the "minimal-ui" completely, since the main element never "scrolls", but is moved by iscroll. Brim seems like it could fix that for us, but having a mask element with an explenation that the user must scroll to remove it is an obstacle that we don't want to impose on our users. Is there any way of avoiding that?

How to install Scream for use with Brim?

Hi,

We are developing an HTML5 app and the minimal-ui is a must for us.
But it seems that installing Scream on the server is very complicated.
Is it a must? Is it possible to just copy the Scream JS file, or it must be installed by server-side installation with NodeJS etc...

Thank you!

iPad Pro not recognised

When emulating an iPad Pro, the "device not recognised" error is thrown. The issue that it links to has been closed, so I am creating a new one. I am using xCode to emulate the device.

The user agent is as follows:

Mozilla/5.0 (iPad; CPU OS 9_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13C75 Safari/601.1

Mouse/touch events near bottom of screen

If you touch near the bottom of the screen on an iPhone 5 Safari, the display reverts to the full view. Is that Safari's built-in behavior? Or is that a brim setting?

If it's the former, I'm guessing there's no way to intervene. I have some buttons near the bottom edge because I'm trying to use most of the viewing area for an image that can be panned and zoomed.

Thanks to anyone who knows or has experienced the same thing.
-Dave

Auto minimal-ui?

Is it possible to automatically enter minimal-ui (without user interaction)?

If not, is there a way to remember/save minimal-ui setting, so a user does not need to interact on every page (for example on a website with multiple pages - loading a new page resets minimal-ui).

Using brim in landscape mode only

Got a basic brim implementation going. Seems to mostly do what I want it to do, but I only need it to work in landscape mode.

Is this possible with the script today?

Thanks for your hard work on this!

IPhone X resizing

Hi, I am having some trouble with iPhone X resizing. The minimal ui is invoked correctly, but the brim-main element is not resized accordingly, so I am left with a chunk of blank space where the bottom nav bar was previously located. It is worth noting that this only happens on initial load, so if I go to landscape and back to portrait, the resizing is done correctly regardless of how many times the minimal ui is invoked.

I'm passing the width configuration as shown below.

const scream = Scream({
   width: {
	portrait: screen.width,
	landscape: screen.height
   }
});

Would highly appreciate any help. Thanks!

Problem with scrollable elements in the main section

If I have a scrollable div inside the 'main' content div it can't scroll when in MinimalUI state because the Brim TouchMove handler is calling e.preventDefault (I assume to block scrolling that might knock the UI out of MinimalUI mode).

I think that TouchHandler probably needs to detect the scrollParent (parentElement.scrollHeight > parentElement.offsetHeight) and only block if the scroll parent element is the body etc.

Problem overflow-y scroll and brim

Is it possible to somehow allow scrolling content inside div when use brim.js?
I try add <div style="width:100%;height:100%;overflow-y:scroll;-webkit-overflow-scrolling:touch;">content</div> in brim-main, but scroll don't work..

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.