Categories
HTML

How to Insert MP4 Video in HTML

Inserting MP4 videos in our HTML code is easy.

All we have to do is to use the video tag as follows:

<video src='https://file-examples.com/wp-content/uploads/2017/04/file_example_MP4_640_3MG.mp4' controls></video>

We have the controls attribute to show the video play controls in our video element.

src has the path to the video. It can be either a URL or a relative path.

Once we have that, we’ll see the video displayed with the play button on the bottom left.

Categories
HTML

How to Change HTML Video Playback Speed

We can create our own HTML video player where can control the playback speed.

First, we create the video tag as follows:

<video src='https://file-examples.com/wp-content/uploads/2017/04/file_example_MP4_640_3MG.mp4' controls></video>

We have the controls attribute so that we can see the playback controls.

Then we can add buttons to let us adjust the speed of the playback:

<video src='https://file-examples.com/wp-content/uploads/2017/04/file_example_MP4_640_3MG.mp4' controls></video>

<button id='1x'>
  1x
</button>
<button id='15x'>
  1.5x
</button>
<button id='2x'>
  2x
</button>

Now we can move onto the JavaScript portion of our code.

We can use event delegation to get the ID of the button that’s clicked and then set the playbackRate property of the video element accordingly:

const video = document.querySelector('video');
document.onclick = (e) => {
  if (e.target.id === '1x') {
    video.playbackRate = 1;
  }
  if (e.target.id === '15x') {
    video.playbackRate = 1.5;
  }
  if (e.target.id === '2x') {
    video.playbackRate = 2;
  }
}

We get the video element with document.querySelector and then we set the playbackRate property of the video according to the ID of the button that’s clicked according to the value of e.target.id.

Now we can create our own video player where we can adjust the playback speed of the video.

Categories
JavaScript React

Reacting to Observables with MobX-React

We can use MobX with MobX-React to manage the state by watching MobX observables and changing the observable data.

In this article, we’ll look at how to create an Observable and use it in React components directly.

Creating Observables and Using Them in React Components

We have to install the mobx and mobx-react packages to create Observables and use them within React components.

To do this, we can write the following:

npm i mobx mobx-react

Then we can create our Observable object and a React component that uses it as follows:

import React from "react";  
import ReactDOM from "react-dom";  
import { observer } from "mobx-react";  
import { observable } from "mobx";

const countData = observable({  
  count: 0  
});

const App = observer(({ countData }) => (  
  <>  
    <button onClick={() => countData.count++}>Increment</button>  
    <p>{countData.count}</p>  
  </>  
));  
const rootElement = document.getElementById("root");  
ReactDOM.render(<App countData={countData} />, rootElement);

In the code above, we created the countData Observable object by writing:

const countData = observable({  
  count: 0  
});

We’ll be able to get the latest state within our React component and then pass it in as a prop for our React component.

To make our React component watch for the latest value from our Observable object and let us change its value from within the component, we write:

const App = observer(({ countData }) => (  
  <>  
    <button onClick={() => countData.count++}>Increment</button>  
    <p>{countData.count}</p>  
  </>  
));  
const rootElement = document.getElementById("root");  
ReactDOM.render(<App countData={countData} />, rootElement);

The code above gets the countData prop from the countData Observable. Then in the onClick handler, we just pass in the function to change its value.

Then when we reference the App component in the last line, we just pass in the countData Observable object as the value of the countData prop.

countData.count++ will change the state of the Observable, which then the latest value will be obtained from the prop.

We can use the countData Observable object with class components as follows:

import React from "react";  
import ReactDOM from "react-dom";  
import { observer } from "mobx-react";  
import { observable } from "mobx";const countData = observable({  
  count: 0  
});

@observer  
class App extends React.Component {  
  render() {  
    return (  
      <>  
        <button onClick={() => countData.count++}>Increment</button>  
        <p>{countData.count}</p>  
      </>  
    );  
  }  
}

const rootElement = document.getElementById("root");  
ReactDOM.render(<App countData={countData} />, rootElement);

The only difference is that it’s a class component with a render method and that we use the observer decorator instead of the observer function.

Using Context to Pass Observables Around

We can use the React Context API to pass the values of an Observable to another component.

For instance, we can write the following code:

import React, { useContext } from "react";  
import ReactDOM from "react-dom";  
import { observer } from "mobx-react";  
import { observable } from "mobx";

const countData = observable({  
  count: 0  
});

const CountContext = React.createContext();

const Counter = observer(() => {  
  const countData = useContext(CountContext);  
  return (  
    <>  
      <button onClick={() => countData.count++}>Increment</button>  
      <p>{countData.count}</p>  
    </>  
  );  
});

const App = ({ countData }) => (  
  <CountContext.Provider value={countData}>  
    <Counter />  
  </CountContext.Provider>  
);

const rootElement = document.getElementById("root");  
ReactDOM.render(<App countData={countData} />, rootElement);

In the code above, we have the CountContext . We create it by writing:

const CountContext = React.createContext();

Then in App , we included the CountContext component, so that we can get the countData Observable value by passing in the countData prop with the value set to the countData Observable.

In the Counter component, we call the observer function with a function component inside.

Inside the component, we use the useContext hook to get the value from CountContext .

Then in the handler function, we passed into the onClick prop of the button, we changed the count ‘s value, which will automatically change the value in the countData Observable object and set as the value of countData.count .

Therefore, when we click the Increment button, the number below it will go up.

Storing Observables in Local Component State

We can also use Observables as a local state in a React component.

To do this, we can use the useState hook by passing in a function that returns an Observable object as follows:

import React, { useState } from "react";  
import ReactDOM from "react-dom";  
import { observer } from "mobx-react";  
import { observable } from "mobx";const App = observer(() => {  
  const \[countData\] = useState(() =>  
    observable({  
      count: 0  
    })  
  ); return (  
    <>  
      <button onClick={() => countData.count++}>Increment</button>  
      <p>{countData.count}</p>  
    </>  
  );  
});  
const rootElement = document.getElementById("root");  
ReactDOM.render(<App />, rootElement);

In the code above, we used the useState hook by passing in a function that returns an Observable object with the count property. We then assigned that to the countData variable.

Once we did that, countData.count will be updated by the onClick handler and when we click the Increment button, we’ll see the countData.count value update automatically.

If we click the Increment button, then the value will go up.

We don’t really need to use MobX Observable objects to store local state unless complex computations are involved, since MobX will optimize for those.

Likewise, we can use MobX to store local state with class components as follows:

import React, { useState } from "react";  
import ReactDOM from "react-dom";  
import { observer } from "mobx-react";  
import { observable } from "mobx";@observer  
class App extends React.Component {  
  @observable count = 0; render() {  
    return (  
      <>  
        <button onClick={() => this.count++}>Increment</button>  
        <p>{this.count}</p>  
      </>  
    );  
  }  
}  
const rootElement = document.getElementById("root");  
ReactDOM.render(<App />, rootElement);

In the code above, we have this.count , which is an Observable field. In the onClick listener, we just modify this.count directly, and then it’ll be reflected in the this.count in between the p tag.

@observer implements memo orshouldComponentUpdate automatically so that there won’t be any unnecessary re-renders.

Conclusion

We can use MobX Observable to store a React app’s state or a React component’s state.

To use it for storing React app’s state, we can either pass an Observable to a component as a prop or we can use the Context API to send the data to different components.

We can also use it to store local state by either using the useState hook in function components and using the observable decorator within a class component.

Categories
JavaScript

JavaScript Events Handlers — Mouse Wheel and Media Events

In JavaScript, events are actions that happen in an app. They’re triggered by various things like inputs being entered, forms being submitted, and changes in an element like resizing, or errors that happen when an app is running, etc. We can assign an event handler to handle these events. Events that happen to DOM elements can be handled by assigning an event handler to properties of the DOM object for the corresponding events. In this article, we’ll look at how to use the onwheel for handling scroll wheel events, onpause and onplay for handling pause and play events for media elements.

onwheel

The onwheel property of a DOM object lets us assign an event handler function to it to handle the wheel event. The event is fired when the mouse wheel is rotated. It’s not the same as onscroll since scrolling doesn’t always involve using the mouse wheel.

For example, we can use the onwheel event handler function to change the size of a box when we rotate the mouse wheel. To do this, first, we add a div to the HTML code that makes a box which we can change the size for:

<div>Make me bigger or smaller by rotating the mouse wheel.</div>

Then we style the div element by changing the size, position, and color of it as we do in the following code:

div {  
  width: 100px;  
  height: 100px;  
  background: lightblue;  
  padding: 5px;  
  transition: transform .3s;  
  margin: 0 auto;  
  margin-top: 100px;  
}

Finally, we add the JavaScript code which makes use of the onwheel event handler function to scale the div element depending on the scroll direction of the mouse wheel:

let scale = 1;
const zoom = (event) => {  
  event.preventDefault();  
  if (event.deltaY < 0) {  
    scale *= event.deltaY * -1.1;  
  } else {  
    scale /= event.deltaY * 1.1;  
  }  
  scale = Math.min(Math.max(.1, scale), 3);  
  el.style.transform = `scale(${scale})`;  
}

const el = document.querySelector('div');  
document.onwheel = zoom;

In the code above, if we move the mouse wheel counter-clockwise, then the div gets bigger. Otherwise, it gets smaller. It does this by getting the deltaY property from the event object. When deltaY is negative, which means the mouse wheel is scrolling counter-clockwise, so we multiply it by -1.1 to make the scale variable positive and we multiply the existing scale value with this number to increase the size of the div . Otherwise, we divide instead so that the div shrinks.

After the if statement, we restrict the scale variable to be between .1 and 3 so that it won’t get infinitely big or infinitesimally small. Finally, we assign the scale value to the transform property by running el.style.transform = `scale(${scale})`; .

onpause

The pause event is fired when media playback has been paused. To handle this event, we can assign an event handler function to the onpause property a DOM element.

The pause event is sent when a request to pause an activity is handled and the activity has entered a paused state. This is most common when we pause audio or video by manually pausing media playback or calling the pause() method to do the same thing. The event is fired once the pause() method returns and after the media element’s paused property has been changed to true .

For example, we can log whether a video is paused or not by writing some code. First, we add the HTML code for the video element as we have below:

<video controls src='https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4'></video>

Then in the JavaScript code, we can assign our event handler function to the onpause property of the video DOM object:

const video = document.querySelector('video');
video.onpause = (event) => {  
  console.log('video paused');  
};

After that, we should see the ‘video paused’ message when we pause a video.

The ‘video paused’ message will also show if we call the pause method on the video DOM object. For example, if we write the following code instead of what we have above:

const video = document.querySelector('video');  
video.play();  
setTimeout(() => {  
  video.pause();  
}, 2000)

video.onpause = (event) => {  
  console.log('video paused');  
};

Then the video will play for 2 seconds and the pause will be called on the video DOM object, which then will trigger the pause event to fire. Then we’ll see the ‘video paused’ message logged.

onplay

The onplay property of a DOM media element like audio or video lets us assign and event handler function to these objects. It handles the play event which is fired when the media element’s paused property changes from true to false , either as a result of calling the play method on the media element or setting the autoplay attribute to the element.

For example, we can create an autoplay video element and then log the play event when it’s fired. First, we make the HTML code by adding a videon element:

<video controls autoplay src='https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_30mb.mp4'></video>

Then in the JavaScript code, we define our own event handler function for the play event and set it to the onplay property of our video element DOM object:

const video = document.querySelector('video');video.onplay = (event) => {  
  console.log('video plays');  
};

When the video starts playing as the page loads, we should see the ‘video plays’ message logged in the console.log statement.

It should also log when we call the play method on the video element. If we have instead:

const video = document.querySelector('video');
video.play();
video.onplay = (event) => {  
  console.log('video plays');  
};

we should have the same message logged in the console. This is also the case if we play the video manually.

The onwheel property of a DOM object lets us assign an event handler function to it to handle the wheel event. The event is fired when the mouse wheel is rotated. It’s not the same as onscroll since scrolling doesn’t always involve using the mouse wheel. We can get the deltaY to get the magnitude and direction the mouse wheel is rotating at.

The pause event is fired when media playback has been paused. To handle this event, we can assign an event handler function to the onpause property a DOM element.

The pause event is sent when a request to pause an activity is handled and the activity has entered a paused state. This is most common when we pause audio or video by manually pausing media playback or calling the pause() method to do the same thing. The event is fired once the pause() method returns and after the media element’s paused property has been changed to true .

The onplay property of a DOM media element like audio or video lets us assign and event handler function to these objects. It handles the play event which is fired when the media element’s paused property changes from true to false , either as a result of calling the play method on the media element or setting the autoplay attribute to the element.

Categories
JavaScript Vue

Add Drag and Drop into a Vuejs App

We can add basic drag and drop features into a Vue app.

The vuedraggable library makes adding drag and drop easy.

To use it, first we install it by running:

npm i -S vuedraggable

Then we can use it as follows:

App.vue

<template>
  <div id="app">
    <draggable group="words" :list="arr" @change="log">
      <div v-for="element in arr" :key="element">{{element}}</div>
    </draggable>
  </div>
</template>

<script>
import draggable from "vuedraggable";

export default {
  name: "App",
  components: {
    draggable
  },
  data() {
    return {
      arr: ['item1', 'item2', 'item3']
    };
  },
  methods: {
    log(e) {
      console.log(e);
    }
  }
};
</script>

We add the draggable component to the App component and we can display a list where we can drag them items around the way we wish to.

As we drag and drop the items, we log the changed with the log method, which has the element that’s been moved and the original and new index of the item.

We can also add headers or footers by using the slots as follows:

App.vue

<template>
  <div id="app">
    <draggable group="words" :list="arr" @change="log">
      <div v-for="element in arr" :key="element">{{element}}</div>
      <button slot="footer" @click="addItem">Add</button>
    </draggable>
  </div>
</template>

<script>
import draggable from "vuedraggable";

export default {
  name: "App",
  components: {
    draggable
  },
  data() {
    return {
      arr: ["item1", "item2", "item3"]
    };
  },
  methods: {
    log(e) {
      console.log(e);
    },
    addItem() {
      this.arr = [...this.arr, `item${this.arr.length + 1}`];
    }
  }
};
</script>

We added a button by writing:

<button slot="footer" @click="addItem">Add</button>

As long as the slot’s value is footer, it’ll be displayed below the list.

If we change the slot’s value to header, then it’ll displayed on top of the list:

<template>
  <div id="app">
    <draggable group="words" :list="arr" @change="log">
      <button slot="header" @click="addItem">Add</button>
      <div v-for="element in arr" :key="element">{{element}}</div>
    </draggable>
  </div>
</template>

<script>
import draggable from "vuedraggable";

export default {
  name: "App",
  components: {
    draggable
  },
  data() {
    return {
      arr: ["item1", "item2", "item3"]
    };
  },
  methods: {
    log(e) {
      console.log(e);
    },
    addItem() {
      this.arr = [...this.arr, `item${this.arr.length + 1}`];
    }
  }
};
</script>

vuedraggable is very useful for creating drag and drop lists with ease.