material-shapes-svg
TypeScript icon, indicating that this package has built-in type declarations

1.0.13 • Public • Published

Material Shapes Svg

An implementation of Material Design Shape for the web extending Svg.js and Svg.filter.js

Demo

SVG Button and Rectangle with CutOut

Install

npm install material-shapes-svg

Shapes

Chamfer Rectangle

Creates a rectangle with cut corners.

svgjs.Doc.chamferRect(
width: number,
height: number,
chamferAllLength: number,
): svgjs.MDSChamferRect

svgjs.Doc.chamferRect(
width: number,
height: number,
chamferTopLeftLength: number,
chamferTopRightLength: number,
chamferBottomRightLength: number,
chamferBottomLeftLength: number
): svgjs.MDSChamferRect

Change the chamfer length later after the ChamferRect has been created using the chamfer method

svgjs.MDSChamferRect.chamfer(
width: number,
height: number,
chamferAllLength: number,
): svgjs.MDSChamferRect

svgjs.MDSChamferRect.chamfer(
width: number,
height: number,
chamferTopLeftLength: number,
chamferTopRightLength: number,
chamferBottomRightLength: number,
chamferBottomLeftLength: number
): svgjs.MDSChamferRect

svgjs.MDSChamferRect extends svgjs.Path

<!-- HTML -->
<div class="example-chamfer"></div>
/* CSS: for size example */
.example-chamfer {
    width: 160px;
    height: 40px;
}
import * as svgjs from 'svg.js';
import 'material-shapes-svg';
 
// Find example div
const div: HTMLElement = document.querySelector('div.example-chamfer');
const width: number = div.offsetWidth;
const height: number = div.offsetHeight;
const chamferLength: number = 8;
 
// Create container
const container: svgjs.Doc = svgjs(div).size(width, height);
 
// Draw the chamfer rectangle
container.chamferRect(width, height, chamferLength);

Elevation

Creates a Material Elevation based on the shape.

svgjs.Shape.elevation( z: svgjs.zDepth ): svgjs.Filter

svgjs.Filter.elevate( z: svgjs.zDepth ): svgjs.Filter

<!-- HTML -->
<div class="example-diamond"></div>
/* CSS: Make sure shadows dont get clipped */
.example-diamond .mds-svg {
    overflow: visible;
}
 
.example-diamond {
    width: 64px;
    height: 64px;
}
import * as svgjs from 'svg.js';
import 'svg.filter.js';
import 'material-shapes-svg';
 
// find example div
const div: HTMLElement = document.querySelector('div.example-diamond');
const width = element.offsetWidth;
const height = element.offsetHeight;
 
const container: svgjs.Doc = svgjs(element).size(width, height).addClass('mds-svg');
 
// Diamond Shape
const diamond: svgjs.Path = container.path(`
    M${width*0.5} 0
    L${width} ${height*0.5}
    L${width*0.5} ${height}
    L0 ${height*0.5}
    Z
`).fill('#fff');
 
const elevation: svgjs.Filter = diamond.elevation(8);

Ripple

Creates a Material Pressed State aka ripple

svgjs.Shape.ripple( contrast?: svgjs.MDSContrast ): svgjs.MDSRipple

svgjs.MDSRipple.expand( x: number, y: number ): svgjs.MDSRipple

svgjs.MDSRipple.reset(): svgjs.MDSRipple

If you need to update the extents of the ripple use updateMinMax, such as parent container resized.

svgjs.MDSRipple.updateMinMax( width: number, height: number ): svgjs.MDSRipple

svgjs.MDSRipple.contrast: svgjs.MDSContrast ( 'light' | 'dark' )

svgjs.MDSRipple extends svgjs.Circle

<!-- HTML -->
<div class="example-ripple">
    <div class="mds-background"></div>
    <div class="example-text">Click me</div>
    <div class="mds-ripple"></div>
</div>
/* CSS */
.example-ripple {
    width: 160px;
    height: 36px;
    position: relative;
}
.example-ripple .mds-background,
.example-ripple .mds-wash,
.example-ripple .mds-ripple {
    position: absolute;
    overflow: visible;
    top: 0;
    left: 0;
}
 
.example-ripple .example-text {
    line-height: 36px;
    height: 36px;
    color: #222;
    position: relative;
    text-align: center;
}
import * as svgjs from 'svg.js';
import 'material-shapes-svg';
 
// Find example div
const div: HTMLElement = document.querySelector('div.example-diamond');
const width = div.offsetWidth;
const height = div.offsetHeight;
 
// Find background div
const backgroundElement: HTMLElement = <HTMLElement>div.getElementsByClassName('mds-background')[0];
 
// Find ripple div
const rippleElement: HTMLElement = <HTMLElement>div.getElementsByClassName('mds-ripple')[0];
 
// Create containers
const backgroundContainer: svgjs.Doc = svgjs(backgroundElement).size(width, height).addClass('mds-svg');
const rippleContainer: svgjs.Doc = svgjs(rippleElement).size(width, height).addClass('mds-svg');
 
// Draw a shape that can show off mask effect
const chamferRect: svgjs.MDSChamferRect = backgroundContainer.chamferRect(width, height, 10)
.fill('#ccc');
// You need a separate copy of shape for ripple
const rippleRect: svgjs.MDSChamferRect = rippleContainer.chamferRect(width, height, 10)
.fill('#000');
 
// Add ripple shape
const ripple: svgjs.MDSRipple = rippleRect.ripple('dark');
 
// Add interactions for demo
div.onmousedown = (event: MouseEvent) => {
    ripple.expand(event.offsetX, event.offsetY);
}
div.onmouseup = () => {
    ripple.reset();
}

Rect Cut Out

Creates cut outs for rectangles. Such as Material App Bottom Bar. See the Inset FAB under the anatomy section.

svgjs.Shape.circleCutOut(
width: number,
height: number,
cutOutSize: number,
alignX: svgjs.CutOutAlignX,
alignY: svgjs.CutOutAlignY,
padding: number,
roundedEdge: number,
showCutOut: boolean
): svgjs.MDSRectCutOut

svgjs.Shape.triangleCutOut(
width: number,
height: number,
cutOutSize: number,
alignX: svgjs.CutOutAlignX,
alignY: svgjs.CutOutAlignY,
padding: number,
showCutOut: boolean
): svgjs.MDSRectCutOut

svgjs.Shape.customCutOut(
width: number, // Width of rect
height: number, // Height of rect
cutOutSize: number, // Size of cutout
customCutOutOpen: string, // Relative svg.path data
customCutOutClosed: string, // Relative svg.path data
alignX: svgjs.CutOutAlignX,
alignY: svgjs.CutOutAlignY,
padding: number,
showCutOut: boolean
): svgjs.MDSRectCutOut

svgjs.MDSRectCutOut.showCutOut( alignX: svgjs.CutOutAlignX ): svgjs.MDSRectCutOut

svgjs.MDSRectCutOut.hideCutOut(): svgjs.MDSRectCutOut

If you need to update the extents of the Rect use resize, such as parent container resized.

svgjs.MDSRectCutOut.resize( width: number,
height: number
): svgjs.MDSRectCutOut

svgjs.MDSRectCutOut.CutOutAlignX: svgjs.CutOutAlignX ( 'start' | 'center' | 'end' )

svgjs.MDSRectCutOut.CutOutAlignY: svgjs.CutOutAlignX ( 'top' | 'bottom' )

svgjs.MDSRectCutOut extends svgjs.Path

<!-- HTML -->
<div class="example-rect-cutout"></div>
/* CSS: for size example */
.example-rect-cutout {
    width: 100%;
    height: 56px;
}
import * as svgjs from 'svg.js';
import 'material-shapes-svg';
 
// Find example div
const div: HTMLElement = document.querySelector('div.example-rect-cutout');
const width: number = div.offsetWidth;
const height: number = div.offsetHeight;
const padding: number = 16;
const roundedEdge: number = 4;
const fabDiameter: number = 56 + 16; // fab plus cutout padding
const cutOutAlignX = 'end';
const cutOutAlignY = 'top';
const showCutOut = true;
 
// Create container
const container: svgjs.Doc = svgjs(div).size(width, height);
 
// Draw the rectangle with circular cutout
const rectCutOut: svgjs.MDSRectCutOut = container.circleCutOut(
    width,
    height,
    fabDiameter,
    cutOutAlignX,
    cutOutAlignY,
    padding,
    roundedEdge,
    showCutOut
);

For custom shapes use relative path data

const cutOutSize = 80;
 
const radius = `28 28`
const concave = `0 0 0`
 
const openCutOut = `
${radius} ${concave} 14 21
${radius} ${concave} 52 0
${radius} ${concave} 14 -21
l 0 0`;
 
const closedCutOut = `
a 23 0 ${concave} 0 0
a 24 0 ${concave} 0 0
a 23 0 ${concave} 0 0
l 0 0`;
 
const rectCutOut: svgjs.MDSRectCutOut = container.customCutOut(
    width,
    height,
    cutOutSize,
    openCutOut,
    closedCutOut,
    cutOutAlignX,
    cutOutAlignY,
    padding,
    showCutOut
)

RoadMap

Custom Chamfer Shapes supply a shape to cutout of chamfered corners

Rect CutOut refactor circle and triangle to use similar method to custom.

Demo Site more examples

Package Sidebar

Install

npm i material-shapes-svg

Weekly Downloads

2

Version

1.0.13

License

MIT

Unpacked Size

235 kB

Total Files

7

Last publish

Collaborators

  • derekmoss