欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS實現(xiàn)一個可以當鏡子照的?Button

 更新時間:2023年03月05日 09:24:26   作者:zxg_神說要有光  
這篇文章主要介紹了JS實現(xiàn)一個可以當鏡子照的?Button的方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

正文

最近寫了一個好玩的 Button,它除了是一個 Button 外,還可以當鏡子照。

那這個好玩的 Button 是怎么實現(xiàn)的呢?

很容易想到是用到了攝像頭。

沒錯,這里要使用瀏覽器的獲取媒體設(shè)備的 api 來拿到攝像頭的視頻流,設(shè)置到 video 上,然后對 video 做下鏡像反轉(zhuǎn),加點模糊就好了。

button 的部分倒是很容易,主要是陰影稍微麻煩點。

把 video 作為 button 的子元素,加個 overflow:hidden 就完成了上面的效果。

思路很容易,那我們就來實現(xiàn)下吧。

獲取攝像頭用的是 navigator.mediaDevices.getUserMedia 的 api。

mediaDevices 的介紹

在 MDN 中可以看到 mediaDevices 的介紹:

可以用來獲取攝像頭、麥克風、屏幕等。

它有這些 api:

getDisplayMedia 可以用來錄制屏幕,截圖。

getUserMedia 可以獲取攝像頭、麥克風的輸入。

我們這里用到getUserMedia 的 api

它要指定音頻和視頻的參數(shù),開啟、關(guān)閉、分辨率、前后攝像頭啥的:

這里我們把 video 開啟,把 audio 關(guān)閉。

也就是這樣:

navigator.mediaDevices.getUserMedia({
    video: true,
    audio: false,
})
.then((stream) => {
    //...
}).catch(e => {
    console.log(e)
})

把獲取到的 stream 用一個 video 來展示

navigator.mediaDevices.getUserMedia({
    video: true,
    audio: false,
})
.then((stream) => {
  const video = document.getElementById('video');
  video.srcObject = stream;
  video.onloadedmetadata = () => {
    video.play();
  };
})
.catch((e) => console.log(e));

就是這樣的:

通過 css 的 filter 來加點感覺:

比如加點 blur:

video {
  filter: blur(10px);
}

加點飽和度:

video {
  filter: saturate(5)
}

或者加點亮度:

video: {
  filter: brightness(3);
}

filter 可以組合,調(diào)整調(diào)整達到這樣的效果就可以了:

video {
  filter: blur(2px) saturate(0.6) brightness(1.1);
}

然后調(diào)整下大?。?/p>

video {
  width: 300px;
  height: 100px;
  filter: blur(2px) saturate(0.6) brightness(1.1);
}

你會發(fā)現(xiàn)視頻的畫面沒有達到設(shè)置的寬高。

這時候通過 object-fit 的樣式來設(shè)置:

video {
  width: 300px;
  height: 100px;
  object-fit: cover;
  filter: blur(2px) saturate(0.6) brightness(1.1);
}

cover 是充滿容器,也就是這樣:

但畫面顯示的位置不大對,看不到臉。我想顯示往下一點的畫面怎么辦呢?

可以通過 object-position 來設(shè)置:

video {
  width: 300px;
  height: 100px;
  object-fit: cover;
  filter: blur(2px) saturate(0.6) brightness(1.1);
  object-position: 0 -100px;
}

y 向下移動 100 px ,也就是這樣的:

現(xiàn)在畫面顯示的位置就對了。

其實現(xiàn)在還有一個特別隱蔽的問題,不知道大家發(fā)現(xiàn)沒,就是方向是錯的。照鏡子的時候應該左右翻轉(zhuǎn)才對。

所以加一個 scaleX(-1),這樣就可以繞 x 周反轉(zhuǎn)了。

video {
  width: 300px;
  height: 100px;
  object-fit: cover;
  filter: blur(2px) saturate(0.6) brightness(1.1);
  object-position: 0 -100px;
  transform: scaleX(-1);
}

這樣就是鏡面反射的感覺了。

然后再就是 button 部分,這個我們倒是經(jīng)常寫:

function Button({ children }) {
  const [buttonPressed, setButtonPressed] = useState(false);

  return (
    <div
      className={`button-wrap ${buttonPressed ? "pressed" : null}`}
    >
      <div
        className={`button ${buttonPressed ? "pressed" : null}`}
        onPointerDown={() => setButtonPressed(true)}
        onPointerUp={() => setButtonPressed(false)}
      >
         <video/>
      </div>
      <div className="text">{children}</div>
    </div>
  );
}

這里我用 jsx 寫的,點擊的時候修改 pressed 狀態(tài),設(shè)置不同的 class。

樣式部分

:root {
  --transition: 0.1s;
  --border-radius: 56px;
}

.button-wrap {
  width: 300px;
  height: 100px;
  position: relative;
  transition: transform var(--transition), box-shadow var(--transition);
}

.button-wrap.pressed {
  transform: translateZ(0) scale(0.95);
}

.button {
  width: 100%;
  height: 100%;
  border: 1px solid #fff;
  overflow: hidden;
  border-radius: var(--border-radius);
  box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.25), 0px 8px 16px rgba(0, 0, 0, 0.15),
    0px 16px 32px rgba(0, 0, 0, 0.125);
  transform: translateZ(0);
  cursor: pointer;
}

.button.pressed {
  box-shadow: 0px -1px 1px rgba(0, 0, 0, 0.5), 0px 1px 1px rgba(0, 0, 0, 0.5);
}

.text {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  color: rgba(0, 0, 0, 0.7);
  font-size: 48px;
  font-weight: 500;
  text-shadow:0px -1px 0px rgba(255, 255, 255, 0.5),0px 1px 0px rgba(255, 255, 255, 0.5);
}

這種 button 大家寫的很多了,也就不用過多解釋。

要注意的是 text 和 video 都是絕對定位來做的居中。

陰影的設(shè)置

陰影的 4 個值是 x、y、擴散半徑、顏色。

我設(shè)置了個多重陰影:

然后再改成不同透明度的黑就可以了:

再就是按下時的陰影,設(shè)置了上下位置的 1px 黑色陰影:

.button.pressed {
  box-shadow: 0px -1px 1px rgba(0, 0, 0, 0.5), 0px 1px 1px rgba(0, 0, 0, 0.5);
}

同時,按下時還有個 scale 的設(shè)置:

再就是文字的陰影,也是上下都設(shè)置了 1px 陰影,達到環(huán)繞的效果:

text-shadow:0px -1px 0px rgba(255, 255, 255, 0.5),0px 1px 0px rgba(255, 255, 255, 0.5);

最后,把這個 video 嵌進去就行了。

完整代碼

import React, { useState, useEffect, useRef } from "react";
import "./button.css";

function Button({ children }) {
  const reflectionRef = useRef(null);
  const [buttonPressed, setButtonPressed] = useState(false);

  useEffect(() => {
    if (!reflectionRef.current) return;
    navigator.mediaDevices.getUserMedia({
        video: true,
        audio: false,
    })
    .then((stream) => {
        const video = reflectionRef.current;
        video.srcObject = stream;
        video.onloadedmetadata = () => {
        video.play();
        };
    })
    .catch((e) => console.log(e));
  }, [reflectionRef]);

  return (
    <div
      className={`button-wrap ${buttonPressed ? "pressed" : null}`}
    >
      <div
        className={`button ${buttonPressed ? "pressed" : null}`}
        onPointerDown={() => setButtonPressed(true)}
        onPointerUp={() => setButtonPressed(false)}
      >
        <video
          className="button-reflection"
          ref={reflectionRef}
        />
      </div>
      <div className="text">{children}</div>
    </div>
  );
}

export default Button;
body {
  padding: 200px;
}
:root {
  --transition: 0.1s;
  --border-radius: 56px;
}

.button-wrap {
  width: 300px;
  height: 100px;
  position: relative;
  transition: transform var(--transition), box-shadow var(--transition);
}

.button-wrap.pressed {
  transform: translateZ(0) scale(0.95);
}

.button {
  width: 100%;
  height: 100%;
  border: 1px solid #fff;
  overflow: hidden;
  border-radius: var(--border-radius);
  box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.25), 0px 8px 16px rgba(0, 0, 0, 0.15),
    0px 16px 32px rgba(0, 0, 0, 0.125);
  transform: translateZ(0);
  cursor: pointer;
}

.button.pressed {
  box-shadow: 0px -1px 1px rgba(0, 0, 0, 0.5), 0px 1px 1px rgba(0, 0, 0, 0.5);
}

.text {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  color: rgba(0, 0, 0, 0.7);
  font-size: 48px;
  font-weight: 500;
  text-shadow:0px -1px 0px rgba(255, 255, 255, 0.5),0px 1px 0px rgba(255, 255, 255, 0.5);
}

.text::selection {
  background-color: transparent;
}

.button .button-reflection {
  width: 100%;
  height: 100%;
  transform: scaleX(-1);
  object-fit: cover;
  opacity: 0.7;
  filter: blur(2px) saturate(0.6) brightness(1.1);
  object-position: 0 -100px;
}

總結(jié)

瀏覽器提供了 media devices 的 api,可以獲取攝像頭、屏幕、麥克風等的輸入。

除了常規(guī)的用途外,還可以用來做一些好玩的事情,比如今天這個的可以照鏡子的 button。

它看起來就像我上廁所時看到的這個東西一樣??:

以上就是JS實現(xiàn)一個可以當鏡子照的 Button的詳細內(nèi)容,更多關(guān)于JS鏡子Button的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論