web-dev-qa-db-ja.com

すべてのマテリアルデザイン標高のシャドウ値の計算

最新のマテリアルデザインドキュメント( https://www.google.com/design/spec/what-is-material/elevation-shadows.html#elevation-shadows-elevation-Android- )an包括的なUI要素のセットは、それぞれの標高(dpのz-index)で参照されます。たとえば、switch1dpによって昇格されますが、dialog24dpによって昇格されます。現在、GoogleのUI要素のリストでは、10の異なる標高レベルを使用しています。高度によって要素の影が決まるため、10個の異なる影が必要になります。そして、それは私が迷っているところです。

各標高レベルの正しいシャドウ値(色、xオフセット、yオフセット、ぼかし、広がり)をどのように計算/推定しますか?

5つの異なる標高のシャドウ値を計算したさまざまなソースを見つけました( https://news.layervault.com/stories/42319-calculating-shadow-values-for-material-design )。ただし、5つの高度ステップだけでは十分ではなく、これらのそれぞれの値にどのように到達したかについての説明もありません。

22
Anthony Wijnen

朗報です!影の深度は、深度1から深度24まですべて取得しました。これは Angular Material から取得しました。これがお役に立てば幸いです。

.md-whiteframe-1dp {
    box-shadow:  0px 1px 3px 0px rgba(0, 0, 0, 0.2),
    0px 1px 1px 0px rgba(0, 0, 0, 0.14),
    0px 2px 1px -1px rgba(0, 0, 0, 0.12); }
.md-whiteframe-2dp {
    box-shadow:  0px 1px 5px 0px rgba(0, 0, 0, 0.2),
    0px 2px 2px 0px rgba(0, 0, 0, 0.14),
    0px 3px 1px -2px rgba(0, 0, 0, 0.12); }
.md-whiteframe-3dp {
    box-shadow:0px 1px 8px 0px rgba(0, 0, 0, 0.2),
    0px 3px 4px 0px rgba(0, 0, 0, 0.14),
    0px 3px 3px -2px rgba(0, 0, 0, 0.12); }
.md-whiteframe-4dp {
    box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.2),
    0px 4px 5px 0px rgba(0, 0, 0, 0.14),
    0px 1px 10px 0px rgba(0, 0, 0, 0.12); }
.md-whiteframe-5dp {
    box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2),
    0px 5px 8px 0px rgba(0, 0, 0, 0.14),
    0px 1px 14px 0px rgba(0, 0, 0, 0.12); }
.md-whiteframe-6dp {
    box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2),
    0px 6px 10px 0px rgba(0, 0, 0, 0.14),
    0px 1px 18px 0px rgba(0, 0, 0, 0.12); }
.md-whiteframe-7dp {
    box-shadow: 0px 4px 5px -2px rgba(0, 0, 0, 0.2),
    0px 7px 10px 1px rgba(0, 0, 0, 0.14),
    0px 2px 16px 1px rgba(0, 0, 0, 0.12); }
.md-whiteframe-8dp {
    box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2),
    0px 8px 10px 1px rgba(0, 0, 0, 0.14),
    0px 3px 14px 2px rgba(0, 0, 0, 0.12); }
.md-whiteframe-9dp {
    box-shadow: 0px 5px 6px -3px rgba(0, 0, 0, 0.2),
    0px 9px 12px 1px rgba(0, 0, 0, 0.14),
    0px 3px 16px 2px rgba(0, 0, 0, 0.12); }
.md-whiteframe-10dp {
    box-shadow: 0px 6px 6px -3px rgba(0, 0, 0, 0.2),
    0px 10px 14px 1px rgba(0, 0, 0, 0.14),
    0px 4px 18px 3px rgba(0, 0, 0, 0.12); }
.md-whiteframe-11dp {
    box-shadow: 0px 6px 7px -4px rgba(0, 0, 0, 0.2),
    0px 11px 15px 1px rgba(0, 0, 0, 0.14),
    0px 4px 20px 3px rgba(0, 0, 0, 0.12); }
.md-whiteframe-12dp {
    box-shadow: 0px 7px 8px -4px rgba(0, 0, 0, 0.2),
    0px 12px 17px 2px rgba(0, 0, 0, 0.14),
    0px 5px 22px 4px rgba(0, 0, 0, 0.12); }
.md-whiteframe-13dp {
    box-shadow: 0px 7px 8px -4px rgba(0, 0, 0, 0.2),
    0px 13px 19px 2px rgba(0, 0, 0, 0.14),
    0px 5px 24px 4px rgba(0, 0, 0, 0.12); }
.md-whiteframe-14dp {
    box-shadow: 0px 7px 9px -4px rgba(0, 0, 0, 0.2),
    0px 14px 21px 2px rgba(0, 0, 0, 0.14),
    0px 5px 26px 4px rgba(0, 0, 0, 0.12); }
.md-whiteframe-15dp {
    box-shadow: 0px 8px 9px -5px rgba(0, 0, 0, 0.2),
    0px 15px 22px 2px rgba(0, 0, 0, 0.14),
    0px 6px 28px 5px rgba(0, 0, 0, 0.12); }
.md-whiteframe-16dp {
    box-shadow: 0px 8px 10px -5px rgba(0, 0, 0, 0.2),
    0px 16px 24px 2px rgba(0, 0, 0, 0.14),
    0px 6px 30px 5px rgba(0, 0, 0, 0.12); }
.md-whiteframe-17dp {
    box-shadow: 0px 8px 11px -5px rgba(0, 0, 0, 0.2),
    0px 17px 26px 2px rgba(0, 0, 0, 0.14),
    0px 6px 32px 5px rgba(0, 0, 0, 0.12); }
.md-whiteframe-18dp {
    box-shadow: 0px 9px 11px -5px rgba(0, 0, 0, 0.2),
    0px 18px 28px 2px rgba(0, 0, 0, 0.14),
    0px 7px 34px 6px rgba(0, 0, 0, 0.12); }
.md-whiteframe-19dp {
    box-shadow: 0px 9px 12px -6px rgba(0, 0, 0, 0.2),
    0px 19px 29px 2px rgba(0, 0, 0, 0.14),
    0px 7px 36px 6px rgba(0, 0, 0, 0.12); }
.md-whiteframe-20dp {
    box-shadow: 0px 10px 13px -6px rgba(0, 0, 0, 0.2),
    0px 20px 31px 3px rgba(0, 0, 0, 0.14),
    0px 8px 38px 7px rgba(0, 0, 0, 0.12); }
.md-whiteframe-21dp {
    box-shadow: 0px 10px 13px -6px rgba(0, 0, 0, 0.2),
    0px 21px 33px 3px rgba(0, 0, 0, 0.14),
    0px 8px 40px 7px rgba(0, 0, 0, 0.12); }
.md-whiteframe-22dp {
    box-shadow: 0px 10px 14px -6px rgba(0, 0, 0, 0.2),
    0px 22px 35px 3px rgba(0, 0, 0, 0.14),
    0px 8px 42px 7px rgba(0, 0, 0, 0.12); }
.md-whiteframe-23dp {
    box-shadow: 0px 11px 14px -7px rgba(0, 0, 0, 0.2),
    0px 23px 36px 3px rgba(0, 0, 0, 0.14),
    0px 9px 44px 8px rgba(0, 0, 0, 0.12); }
.md-whiteframe-24dp {
    box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2),
    0px 24px 38px 3px rgba(0, 0, 0, 0.14),
    0px 9px 46px 8px rgba(0, 0, 0, 0.12); }
20
Scott Roa

ここに私が思いついた関数があり、それは良い結果をもたらすと私は信じています:

(Javascript)

function getShadow(object, dp)
{
    if (dp <= 0)
    {
        panel.style.boxShadow = "none";
        return;
    }

    panel.style.boxShadow = "0px " + dp + "px " + dp + "px " + "rgba(0, 0, 0, .38)";
}

Jfiddle: https://jsfiddle.net/crkb906z/

基本的に、ベースレイヤーからの距離はシャドウトップがどれだけ下にあるかであり、ぼかしに同じ値を使用して、マテリアルが高くなるにつれてぼやけます。

この結果をpolymerで使用される3つの影と比較しました。それらは非常に比較可能でした。ほとんどの人が提供する5つの層の影の間で一貫性を見つけることができないため、正確にどのように想像するか計算されることはそれほど重要ではありません。

編集

わかりました、5つの深度で利用可能なボックスシャドウ(それらは here から発生しましたが、Googleはこれをドキュメントから削除しました)を調べた後、より複雑な数式を考え出しました。そのリンクの例のように見える影:

function applyShadow(element, dp)
{
    if (dp == 0)
    {
        element.style.boxShadow = "none";
    }
    else
    {
        var shadow = "0px ";

        var ambientY = dp;
        var ambientBlur = dp == 1 ? 3 : dp * 2;
        var ambientAlpha = (dp + 10 + (dp / 9.38)) / 100;

        shadow += ambientY + "px " + ambientBlur + "px rgba(0, 0, 0, " + ambientAlpha + "), 0px ";

        var directY = (dp < 10 ? (dp % 2 == 0 ? dp - ((dp / 2) - 1) : (dp - ((dp - 1) / 2))) : dp - 4);
        var directBlur = dp == 1 ? 3 : dp * 2;
        var directAlpha = (24 - Math.round(dp / 10)) / 100;

        shadow += directY + "px " + directBlur + "px rgba(0, 0, 0, " + directAlpha + ")";

        element.style.boxShadow  = shadow;
    }
}

https://jsfiddle.net/crkb906z/1/ を更新して、違いを示しています。

14
Troncoso

Googleの公式のMDC Web標高に関するものはこれまでに投稿されたものとは異なるため、私はこの回答のみを投稿しています。

コピー元のソースファイルは次のとおりです。

https://github.com/material-components/material-components-web/blob/e02b4c9fa2bd026c695f3a71efce58d01f460269/packages/mdc-elevation/_variables.scss

Googleの公式box-shadow標高の値(SASS mixin):

//
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.Apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

@import "@material/animation/variables";

$mdc-elevation-baseline-color: black;
$mdc-elevation-umbra-opacity: .2;
$mdc-elevation-penumbra-opacity: .14;
$mdc-elevation-ambient-opacity: .12;

$mdc-elevation-umbra-map: (
  0: "0px 0px 0px 0px",
  1: "0px 2px 1px -1px",
  2: "0px 3px 1px -2px",
  3: "0px 3px 3px -2px",
  4: "0px 2px 4px -1px",
  5: "0px 3px 5px -1px",
  6: "0px 3px 5px -1px",
  7: "0px 4px 5px -2px",
  8: "0px 5px 5px -3px",
  9: "0px 5px 6px -3px",
  10: "0px 6px 6px -3px",
  11: "0px 6px 7px -4px",
  12: "0px 7px 8px -4px",
  13: "0px 7px 8px -4px",
  14: "0px 7px 9px -4px",
  15: "0px 8px 9px -5px",
  16: "0px 8px 10px -5px",
  17: "0px 8px 11px -5px",
  18: "0px 9px 11px -5px",
  19: "0px 9px 12px -6px",
  20: "0px 10px 13px -6px",
  21: "0px 10px 13px -6px",
  22: "0px 10px 14px -6px",
  23: "0px 11px 14px -7px",
  24: "0px 11px 15px -7px"
);

$mdc-elevation-penumbra-map: (
  0: "0px 0px 0px 0px",
  1: "0px 1px 1px 0px",
  2: "0px 2px 2px 0px",
  3: "0px 3px 4px 0px",
  4: "0px 4px 5px 0px",
  5: "0px 5px 8px 0px",
  6: "0px 6px 10px 0px",
  7: "0px 7px 10px 1px",
  8: "0px 8px 10px 1px",
  9: "0px 9px 12px 1px",
  10: "0px 10px 14px 1px",
  11: "0px 11px 15px 1px",
  12: "0px 12px 17px 2px",
  13: "0px 13px 19px 2px",
  14: "0px 14px 21px 2px",
  15: "0px 15px 22px 2px",
  16: "0px 16px 24px 2px",
  17: "0px 17px 26px 2px",
  18: "0px 18px 28px 2px",
  19: "0px 19px 29px 2px",
  20: "0px 20px 31px 3px",
  21: "0px 21px 33px 3px",
  22: "0px 22px 35px 3px",
  23: "0px 23px 36px 3px",
  24: "0px 24px 38px 3px"
);

$mdc-elevation-ambient-map: (
  0: "0px 0px 0px 0px",
  1: "0px 1px 3px 0px",
  2: "0px 1px 5px 0px",
  3: "0px 1px 8px 0px",
  4: "0px 1px 10px 0px",
  5: "0px 1px 14px 0px",
  6: "0px 1px 18px 0px",
  7: "0px 2px 16px 1px",
  8: "0px 3px 14px 2px",
  9: "0px 3px 16px 2px",
  10: "0px 4px 18px 3px",
  11: "0px 4px 20px 3px",
  12: "0px 5px 22px 4px",
  13: "0px 5px 24px 4px",
  14: "0px 5px 26px 4px",
  15: "0px 6px 28px 5px",
  16: "0px 6px 30px 5px",
  17: "0px 6px 32px 5px",
  18: "0px 7px 34px 6px",
  19: "0px 7px 36px 6px",
  20: "0px 8px 38px 7px",
  21: "0px 8px 40px 7px",
  22: "0px 8px 42px 7px",
  23: "0px 9px 44px 8px",
  24: "0px 9px 46px 8px"
);

/**
 * The css property used for elevation. In most cases this should not be changed. It is exposed
 * as a variable for abstraction / easy use when needing to reference the property directly, for
 * example in a `will-change` rule.
 */
$mdc-elevation-property: box-shadow !default;

/**
 * The default duration value for elevation transitions.
 */
$mdc-elevation-transition-duration: 280ms !default;

/**
 * The default easing value for elevation transitions.
 */
$mdc-elevation-transition-timing-function: $mdc-animation-standard-curve-timing-function !default;

上記に基づいて私がまとめたVanilla ES6 elevation関数は次のとおりです。

const umbraColor = 'rgba(0, 0, 0, 0.2)';
const penumbraColor = 'rgba(0, 0, 0, 0.14)';
const ambientColor = 'rgba(0, 0, 0, 0.12)';


const umbra = [
  "0px 0px 0px 0px",
  "0px 2px 1px -1px",
  "0px 3px 1px -2px",
  "0px 3px 3px -2px",
  "0px 2px 4px -1px",
  "0px 3px 5px -1px",
  "0px 3px 5px -1px",
  "0px 4px 5px -2px",
  "0px 5px 5px -3px",
  "0px 5px 6px -3px",
  "0px 6px 6px -3px",
  "0px 6px 7px -4px",
  "0px 7px 8px -4px",
  "0px 7px 8px -4px",
  "0px 7px 9px -4px",
  "0px 8px 9px -5px",
  "0px 8px 10px -5px",
  "0px 8px 11px -5px",
  "0px 9px 11px -5px",
  "0px 9px 12px -6px",
  "0px 10px 13px -6px",
  "0px 10px 13px -6px",
  "0px 10px 14px -6px",
  "0px 11px 14px -7px",
  "0px 11px 15px -7px"
];

const penumbra = [
  "0px 0px 0px 0px",
  "0px 1px 1px 0px",
  "0px 2px 2px 0px",
  "0px 3px 4px 0px",
  "0px 4px 5px 0px",
  "0px 5px 8px 0px",
  "0px 6px 10px 0px",
  "0px 7px 10px 1px",
  "0px 8px 10px 1px",
  "0px 9px 12px 1px",
  "0px 10px 14px 1px",
  "0px 11px 15px 1px",
  "0px 12px 17px 2px",
  "0px 13px 19px 2px",
  "0px 14px 21px 2px",
  "0px 15px 22px 2px",
  "0px 16px 24px 2px",
  "0px 17px 26px 2px",
  "0px 18px 28px 2px",
  "0px 19px 29px 2px",
  "0px 20px 31px 3px",
  "0px 21px 33px 3px",
  "0px 22px 35px 3px",
  "0px 23px 36px 3px",
  "0px 24px 38px 3px"
];

const ambient = [
  "0px 0px 0px 0px",
  "0px 1px 3px 0px",
  "0px 1px 5px 0px",
  "0px 1px 8px 0px",
  "0px 1px 10px 0px",
  "0px 1px 14px 0px",
  "0px 1px 18px 0px",
  "0px 2px 16px 1px",
  "0px 3px 14px 2px",
  "0px 3px 16px 2px",
  "0px 4px 18px 3px",
  "0px 4px 20px 3px",
  "0px 5px 22px 4px",
  "0px 5px 24px 4px",
  "0px 5px 26px 4px",
  "0px 6px 28px 5px",
  "0px 6px 30px 5px",
  "0px 6px 32px 5px",
  "0px 7px 34px 6px",
  "0px 7px 36px 6px",
  "0px 8px 38px 7px",
  "0px 8px 40px 7px",
  "0px 8px 42px 7px",
  "0px 9px 44px 8px",
  "0px 9px 46px 8px"
];

export default (z) => (
  `
    box-shadow: ${umbra[z]} ${umbraColor},
                ${penumbra[z]} ${penumbraColor},
                ${ambient[z]} ${ambientColor};
  `
);
4
anthonator

これがスタイラスに移植されたTroncosoの公式です。

elevation(dp)
  if dp == 0
    box-shadow none
  else
    dp = unit(dp, px)
    blur = (dp == 1 ? 3 : dp * 2)
    amba = (dp + 10 + (dp / 9.38)) / 100
    diry = (dp < 10 ? (dp % 2 == 0 ? dp - ((dp / 2) - 1) : (dp - ((dp - 1) / 2))) : dp - 4)
    dira = (24 - (round(dp / 10))) / 100
    box-shadow 0px dp blur rgba(0, 0, 0, amba), 0px diry blur rgba(0, 0, 0, dira)
3
Joshua Kifer

そのためのscssライブラリがあります: SCSS-Material-Shadows

これが demo です

計算全体をscss-fileで確認できます。

主な用途は、mdElevation()と呼ばれるミックスインです。 mdElevationElement()は、見つかったすべてのMaterial要素の事前定義された標高値の便利な実装です here

標高遷移中の動的効果のために、scssにmdElevationTransition()を追加できます。パラメータとして、2つの標高間のデルタを使用します。

詳細については、githubページにアクセスしてください。

2
FaustmannChr

GoogleのMaterial Design Liteからいくつかの影を得ました。このコードが役立つと思います。

.shadow--2dp {
    box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
}

.shadow--3dp {
    box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), 0 3px 3px -2px rgba(0, 0, 0, 0.2), 0 1px 8px 0 rgba(0, 0, 0, 0.12);
}

.shadow--4dp {
    box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.2);
}

.shadow--6dp {
    box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1px rgba(0, 0, 0, 0.2);
}

.shadow--8dp {
    box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.2);
}

.shadow--16dp {
    box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), 0 6px 30px 5px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.2);
}

.shadow--24dp {
    box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2);
}
1
Scott Roa

次のJS関数は標高レベルを受け取り、GoogleのMaterialコンポーネントに非常に近い結果を返します。

export const getShadow = (elevation=1) => {
    const extraEl = elevation-1
    const getSize = (v1, v24) => `${v1+Math.round(((v24-v1)/23)*extraEl)}px`
    const getShade = (y, blur, spread, alpha) => 
        `0 ${getSize(y[0], y[1])} ${getSize(blur[0], blur[1])} ${getSize(spread[0], spread[1])} rgba(0,0,0,${alpha})`

    return `box-shadow: ${getShade([2,11], [1,15], [-1,-7], 0.2)}, ${getShade([1,24], [1,38], [0,3], 0.14)}, ${getShade([1,9], [3,46], [0,8], 0.12)};`
}

デモ

const getShadow = (elevation=1) => {
        const extraEl = elevation-1
        const getSize = (v1, v24) => `${v1+Math.round(((v24-v1)/23)*extraEl)}px`
        const getShade = (y, blur, spread, alpha) => 
                `0 ${getSize(y[0], y[1])} ${getSize(blur[0], blur[1])} ${getSize(spread[0], spread[1])} rgba(0,0,0,${alpha})`

        return `box-shadow: ${getShade([2,11], [1,15], [-1,-7], 0.2)}, ${getShade([1,24], [1,38], [0,3], 0.14)}, ${getShade([1,9], [3,46], [0,8], 0.12)};`
}

const appDiv = document.getElementById('app');
appDiv.innerHTML = `<div style="margin: 50px; width: 100px; height: 100px; ${getShadow(12)}">Hello world</div>`;
<div id="app"></div>

標高の最初と最後(24番目)のレベルの値を使用します。

0
Ben Carp

これは、Sassのわずかに変更されたポートです。

@mixin shadow($dp: 1) {
    @if $dp == 0 { box-shadow: none; }
    @else {
        $blur: if($dp == 1, 3, $dp * 2);
        $amba: ($dp + 11) / 100;
        $diry: $dp - floor($dp / 4);
        $dirb: floor(($dp + 5) / 2);
        $dira: (24 - (round($dp / 10))) / 100;
        box-shadow: 0px #{$dp + 'px'} #{$blur + 'px'} rgba(0, 0, 0, $amba), 0px #{$diry + 'px'} #{$dirb + 'px'} rgba(0, 0, 0, $dira);
    }
}
0
Spencer