Code Monkey home page Code Monkey logo

react-wavify's Introduction

React Wavify

img img img img img

A simple React component which creates an animated wave.

Live Demo

This component is heavily adapted from Mikołaj Stolarski's awesome Codepen and is functionally similar to Benjamin Grauwin's Wavify plug-in.

img

Installation

Yarn

yarn add react-wavify

npm

npm install react-wavify

Usage

import React from 'react'
import Wave from 'react-wavify'

const App = () => (
  <Wave fill='#f79902'
        paused={false}
        style={{ display: 'flex' }}
        options={{
          height: 20,
          amplitude: 20,
          speed: 0.15,
          points: 3
        }}
  />
)

Simply add the Wave component to the React application using JSX.

The wave's width will scale to fit the parent container.

Props

Fill

The fill property can be set to anything that a SVG path can accept (usually gradients or colors). Default: #FFF

Paused

The paused property controls the play state of the animation. Default: false

If set to true the wave animation will pause.

Options

The component supports a variety of options to affect how the wave is rendered.

Any omitted options will be set to the default value.

  • height - Height of the wave relative to the SVG element. Default: 20
  • amplitude - Amplitude of the rendered wave. Default: 20
  • speed - Speed that the wave animation plays at. Default: 0.15
  • points - Amount of points used to form the wave. Can not be less than 1. Default: 3

Pass Through Props

Any other props such as id, className or style will be passed through to the root of the component.

Other props such as opacity or stroke will be passed to the SVG path element.

Any other elements can be passed inside the SVG component itself.

Inner <defs> elements can be used to add gradients, clipping paths, or masks.

Using a Gradient
<Wave fill="url(#gradient)">
  <defs>
    <linearGradient id="gradient" gradientTransform="rotate(90)">
      <stop offset="10%"  stopColor="#d4af37" />
      <stop offset="90%" stopColor="#f00" />
    </linearGradient>
  </defs>
</Wave>

img

Using a Clipping Path
<Wave fill="#e62315" mask="url(#mask)" options={{ points: 20, speed: 0.2, amplitude: 40 }}>
  {/* Example adapted from https://developer.mozilla.org/en-US/docs/Web/SVG/Element/mask */}
  <mask id="mask">
    <path d="M10,35 A20,20,0,0,1,50,35 A20,20,0,0,1,90,35 Q90,65,50,95 Q10,65,10,35 Z" fill="white" />
  </mask>
</Wave>

img

Using a Mask
<Wave mask="url(#mask)" fill="#1277b0" >
  <defs>
    <linearGradient id="gradient" gradientTransform="rotate(90)">
      <stop offset="0" stopColor="white" />
      <stop offset="0.5" stopColor="black" />
    </linearGradient>
    <mask id="mask">
      <rect x="0" y="0" width="2000" height="200" fill="url(#gradient)"  />
    </mask>
  </defs>
</Wave>

img

react-wavify's People

Contributors

dependabot[bot] avatar greenkeeper[bot] avatar johnamii avatar nxsxd avatar woofers 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

react-wavify's Issues

Action required: Greenkeeper could not be activated 🚨

🚨 You need to enable Continuous Integration on Greenkeeper branches of this repository. 🚨

To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because it uses your CI build statuses to figure out when to notify you about breaking changes.

Since we didn’t receive a CI status on the greenkeeper/initial branch, it’s possible that you don’t have CI set up yet. We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.

If you have already set up a CI for this repository, you might need to check how it’s configured. Make sure it is set to run on all new branches. If you don’t want it to run on absolutely every branch, you can whitelist branches starting with greenkeeper/.

Once you have installed and configured CI on this repository correctly, you’ll need to re-trigger Greenkeeper’s initial pull request. To do this, please click the 'fix repo' button on account.greenkeeper.io.

Put it behind text element

I want to achieve something like in this codepen with this library.
I Tried absolutely positioning the text in front of the wave, but how do I clip the wave so it's just visible through the text only.

Any guidance would be really appritiated

Small Gap

There is a small gap between the wave and my component. It only happend in Mobile view. I've tried added style={{ display: 'flex' }} and style={{ lineHeight: 0 }} but it does not affect the gap.

Loremipsumdolor

Warning: Wave: Support for defaultProps will be removed from function components in a future major release.

Hello!

I'm receiving this warning:

Warning: Wave: Support for defaultProps will be removed from function components in a future major release. 
Use JavaScript default parameters instead.

Which I suppose come from this file:
https://github.com/woofers/react-wavify/blob/main/src/index.js

As a temporal solution I rewrited the component, which works for me but is not tested:

/**
 * From: https://github.com/woofers/react-wavify/blob/main/src/wave.js
 */

import React, {
  CSSProperties,
  PropsWithChildren,
  useEffect,
  useRef,
  useState,
} from "react";

type Point = { x: number; y: number };

export interface WaveOptions {
  height?: number;
  amplitude?: number;
  speed?: number;
  points?: number;
}

export interface WaveProps {
  id?: string;
  paused?: boolean;
  style?: CSSProperties;
  className?: string;
  fill?: string;
  svgId?: string;
  svgPathId?: string;
  svgProps?: React.SVGProps<SVGPathElement>;
  options?: WaveOptions;
}

interface WaveState {
  points: Point[];
  lastUpdate: number;
  elapsed: number;
  step: number;
}

const Wave: React.FC<PropsWithChildren<WaveProps>> = ({
  children,
  ...props
}) => {
  const {
    id,
    fill = "#fff",
    style,
    paused = false,
    className,
    svgId,
    svgPathId,
    svgProps,
  } = props;
  const options = {
    height: 20,
    amplitude: 20,
    speed: 0.15,
    points: 3,
    ...props.options,
  };

  const containerRef = useRef<HTMLDivElement>(null);
  const [path, setPath] = useState("");
  let { current: frameId } = useRef<number>(null);
  const { current: state } = useRef<WaveState>({
    lastUpdate: 0,
    elapsed: 0,
    step: 0,
    points: [],
  });

  const getWidth = () => containerRef.current?.offsetWidth || 0;
  const getHeight = () => containerRef.current?.offsetHeight || 0;

  function draw() {
    if (!paused) {
      const now = Date.now();
      state.elapsed += now - state.lastUpdate;
      state.lastUpdate = now;
    }
    const scale = 1000;
    state.step = (state.elapsed * Math.PI) / scale;
    const points = calculateWavePoints(options, state.step, getWidth());
    const path = buildPath(points, getWidth(), getHeight());
    setPath(path);
  }

  function updateCallback() {
    draw();
    if (frameId) {
      resume();
    }
  }

  function resume() {
    frameId = window.requestAnimationFrame(updateCallback);
    state.lastUpdate = Date.now();
  }

  useEffect(() => {
    if (!frameId) {
      resume();
    }
    return () => {
      if (frameId) {
        window.cancelAnimationFrame(frameId);
        frameId = 0;
      }
    };
  }, []);

  return (
    <div
      style={{ width: "100%", display: "inline-block", ...style }}
      className={className}
      id={id}
      ref={containerRef}
    >
      <svg
        width="100%"
        height="100%"
        version="1.1"
        xmlns="http://www.w3.org/2000/svg"
        id={svgId}
      >
        {children}
        <path
          {...Object.assign({}, { d: path, fill }, svgProps)}
          id={svgPathId}
        />
      </svg>
    </div>
  );
};

function calculateWavePoints(
  options: Required<WaveOptions>,
  step: number,
  width: number
) {
  const points: Point[] = [];
  for (let i = 0; i <= Math.max(options.points, 1); i++) {
    const scale = 100;
    const x = (i / options.points) * width;
    const seed = (step + (i + (i % options.points))) * options.speed * scale;
    const height = Math.sin(seed / scale) * options.amplitude;
    const y = Math.sin(seed / scale) * height + options.height;
    points.push({ x, y });
  }
  return points;
}

function buildPath(points: Point[], width: number, height: number) {
  let svg = `M ${points[0].x} ${points[0].y}`;
  const initial = {
    x: (points[1].x - points[0].x) / 2,
    y: points[1].y - points[0].y + points[0].y + (points[1].y - points[0].y),
  };
  const cubic = (a: Point, b: Point) =>
    ` C ${a.x} ${a.y} ${a.x} ${a.y} ${b.x} ${b.y}`;
  svg += cubic(initial, points[1]);
  let point = initial;
  for (let i = 1; i < points.length - 1; i++) {
    point = {
      x: points[i].x - point.x + points[i].x,
      y: points[i].y - point.y + points[i].y,
    };
    svg += cubic(point, points[i + 1]);
  }
  svg += ` L ${width} ${height}`;
  svg += ` L 0 ${height} Z`;
  return svg;
}

export default Wave;

Multiple waves demo

Hey, this is a really cool project, love it!

I think it would be nice to add a demo where you have multiple waves stacked to create an "ocean" effect like in this code pen: https://codepen.io/tedmcdo/pen/PqxKXg
I'm pretty sure this would be possible using your library.

Module not found

image

image

./node_modules/react-wavify/lib/react-wavify.min.js
Module not found: Can't resolve 'R:\projects\brook-react\node_modules\babel-loader\lib\index.js' in 'R:\projects\brook-react'

How to fix it?

question about the wave

Hello I have a question how I could put the wave at the bottom of my page because as you can see on my screen there is a space between the wave and the bottom of my page.

Thanks.

image

Invariant Violation

Hello, i'm trying to apply your library to my react mobile app. When i apply the example code in various ways to make it work, i get this error : Invariant Violation: View config getter callback for component path must be a function (received undefined). Make sure to start component names with a capital letter.

This is the code:
import React, { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, StyleSheet } from 'react-native';
import Wave from 'react-wavify'
function HomepageScreen({ navigation }) {
return (

<Wave fill='#f79902'
paused={false}
style={{ display: 'flex' }}
options={{
height: 20,
amplitude: 20,
speed: 0.15,
points: 3
}}>

);
};

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#333',
padding: 20,
justifyContent: 'center',
},
title: {
fontSize: 36,
marginBottom: 20,
textAlign: 'center',
},
});

export default HomepageScreen;

The only way i don't get an error is if i don't have a return. but then i don't see the wave on my screen

An in-range update of rollup is breaking the build 🚨

The devDependency rollup was updated from 1.3.0 to 1.3.1.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

rollup is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • .github/main.workflow: Workflow Error
  • .github/main.workflow: Workflow Error

Release Notes for v1.3.1

2019-02-27

Bug Fixes

  • Correctly reexport the default export from entry chunks (#2727)

Pull Requests

Commits

The new version differs by 3 commits.

  • e9abb56 1.3.1
  • 55ef193 Update changelog
  • 45518c2 Take chunk export mode into account when reexporting default, resolves #2721 (#2727)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of rollup is breaking the build 🚨

The devDependency rollup was updated from 1.9.2 to 1.9.3.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

rollup is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • Install Demo: Cancelled
  • Install: Failed!

Release Notes for v1.9.3

2019-04-10

Bug Fixes

  • Simplify return expressions that are evaluated before the surrounding function is bound (#2803)

Pull Requests

  • #2803: Handle out-of-order binding of identifiers to improve tree-shaking (@lukastaegert)
Commits

The new version differs by 3 commits.

  • 516a06d 1.9.3
  • a5526ea Update changelog
  • c3d73ff Handle out-of-order binding of identifiers to improve tree-shaking (#2803)

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Could not find a declaration file for module 'react-wavify'

After installation with my React project using npm install react-wavify --save . I tried testing react wavify inside one of my components. However it gives me an error below when I tried to test it just like in the npm react wavify page.

Could not find a declaration file for module 'react-wavify'. 'E:/work/node_modules/react-wavify/dist/react-wavify.min.js' implicitly has an 'any' type.

package.json

  "dependencies": {
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-scripts": "3.4.1",
    "react-typed": "^1.2.0",
    "react-wavify": "^1.2.3"
  },
  "devDependencies": {
    "@material-ui/core": "^4.9.8",
    "@material-ui/icons": "^4.9.1",
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.5.0",
    "@testing-library/user-event": "^7.2.1",
    "@types/jest": "^24.9.1",
    "@types/node": "^12.12.30",
    "@types/react": "^16.9.25",
    "@types/react-dom": "^16.9.5",
    "typescript": "^3.7.5"
  }

I can't change options dynamically

It seems that when I set the height as variable and change it in the state of the component, the height of the wave doesn't change and stays the same as the initial value.

An in-range update of rollup is breaking the build 🚨

The devDependency rollup was updated from 1.14.2 to 1.14.3.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

rollup is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • Install: Failed!

Release Notes for v1.14.3

2019-06-06

Bug Fixes

  • Generate correct external imports when importing from a directory that would be above the root of the current working directory (#2902)

Pull Requests

Commits

The new version differs by 4 commits.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

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.