内容简介:之前恶搞了一张朋友的表情包,直接在百度上找了一个在线表情包制作器,突然灵光一闪,要是支持摄像头该多好,方便又快捷 (重点是省手机内存,不用拍照 :) ),二话不说,开始搬砖使用的第三方库
之前恶搞了一张朋友的表情包,直接在百度上找了一个在线表情包制作器,突然灵光一闪,要是支持摄像头该多好,方便又快捷 (重点是省手机内存,不用拍照 :) ),二话不说,开始搬砖
2. 预想的功能点
图片支持直接粘贴 和 拖拽 图片和文字缩放,支持鼠标滚轮 支持图片翻转 支持捕捉摄像头画面当素材
3. 撸页面
使用的第三方库
antd react-color react-draggle dom-to-image
页面 使用 React + Antd 方便快捷,三下五除二就搞定了
//每一行基本就是这样子
const operationRow = ({ icon = "edit", label, component }) => (
<Row className={`${prefix}-item`}>
<Col span={labelSpan} className={`${prefix}-item-label`}>
<Button type="dashed" icon={icon}>
{label}
</Button>
</Col>
<Col
span={valueSpan}
offset={offsetSpan}
className={`${prefix}-item-input`}
>
{component}
</Col>
</Row>
);
复制代码
支持图片拖拽
dragArea.addEventListener(
"dragleave",
e => {
this.stopAll(e);
this.removeDragAreaStyle();
},
false
);
//移动
dragArea.addEventListener(
"dragover",
e => {
this.stopAll(e);
this.addDragAreaStyle();
},
false
);
dragArea.addEventListener(
"drop",
e => {
this.stopAll(e);
this.removeDragAreaStyle();
const files = e.dataTransfer.files;
this.renderImage(Array.from(files)[0]);
},
false
);
复制代码
支持 图片 粘贴,这个也很简单 绑定粘贴事件 拿到 event 里面的 data 渲染出来就行了
pasteHandler = e => {
const { items, types } = e.clipboardData;
if (!items) return;
const item = items[0]; //只要一张图片
const { kind, type } = item; //kind 种类 ,type 类型
if (kind.toLocaleLowerCase() != "file") {
return message.error("错误的文件类型!");
}
const file = item.getAsFile();
this.renderImage(file);
};
//粘贴图片
bindPasteListener = area => {
area.addEventListener("paste", this.pasteHandler);
};
复制代码
渲染图片
renderImage = file => {
if (file && Object.is(typeof file, "object")) {
let { type, name, size } = file;
if (!isImage(type)) {
return message.error("无效的图片格式");
}
this.setState({ loading: true });
const url = window.URL.createObjectURL(file);
this.setState({
currentImg: {
src: url,
size: `${~~(size / 1024)}KB`,
type
},
scale: defaultScale,
loading: false,
loadingImgReady: true
});
}
};
复制代码
其他就没啥好说的了,常规的页面布局
4. 生成图片
生成图片 本质上就是 利用 canvas 的 ctx.drawImage() ,
绘制文字
const canvas = document.createElement('cavans')
const ctx = canvas.getContext('2d')
canvas.width = "预览区域的宽"
canvas.height = "预览区域的高"
//图片
ctx.drawImage("URL",...attr)
//文字
ctx.fillText(TEXT,...attr)
//旋转图片
ctx.rotate(Math.PI/180 * 好多度)
//缩放 也是 调用 drawImage, 改变 sy,sx 绘制的其实就实现缩放了
ctx.drawImage(URL,0,0,sx /scale,sy/scale,0,0,x,y)
//转成图片
canvas.toDataURL('image/png',如果要压缩这里就填第二个参数)
复制代码
懂原理了 其实没必要一行一行这样写了 找到个 现成的 dom-to-image 的库,肥肠的不错,也是开源和组件化得魅力啊,利人利己
调用 api domToimage.toPng() 轻松搞定
drawMeme = () => {
const { width, height, loadingImgReady,isCompress } = this.state;
if (!loadingImgReady) return message.error("请选择图片!");
this.setState({ drawLoading: true });
const imageArea = document.querySelector(".preview-content");
const options = {
width,
height,
}
if(isCompress){
options.quality = defaultQuality
}
domToImage
.toPng(imageArea, options)
.then(dataUrl => {
this.setState({ drawLoading: false });
Modal.confirm({
title: "生成成功",
content: <img src={dataUrl} style={{ maxWidth: "100%" }} />,
onOk: () => {
message.success("下载成功!");
const filename = Date.now()
const ext = isCompress ? 'jpeg' : 'png'
var link = document.createElement("a");
link.download = `${filename}.${ext}`;
link.href = dataUrl;
link.click();
},
okText: "立即下载",
cancelText: "再改一改"
});
})
.catch(err => {
message.error(err);
this.setState({ drawLoading: false });
});
};
复制代码
- MediaStream 实现 摄像头捕捉
要想拿到 MediaStream , 调用 navigatar.mediaDevices() 即可, 如果想研究 webRTC ,这些 API 也是基础, 个人不是很感兴趣,就没研究,暂时只用到这个借口
navigator.mediaDevices
.getUserMedia({
video: true,
audio: true
})
.then(stream => {
const cameraUrl = window.URL.createObjectURL(stream);
const hide = message.loading('盛世美颜即将出现...')
//其他代码
this.setState(
{
cameraUrl,
cameraVisible: true
},
() => {
setTimeout(()=>{
try {
this.video.play();
} catch (err) {
console.log(err);
Modal.error({
title: "摄像头失败",
content: err.message
});
} finally{
hide()
}
},1000)
}
);
})
.catch((err)=>{
console.log(err)
Modal.error({
title: "调用摄像头失败",
content: err.toString()
});
this.setState({ cameraVisible: false });
});
})
复制代码
这时页面左上角 会弹出一个提示 问你是不是允许 使用摄像头,同意后 拿到 stream ,否则进入 cath
使用 URL.createObjectURL() 拿到一个临时的 url 链接
然后将 链接 设置成 <video src={临时 URL}/> 调用 video.play()
//jsx
<video
style={{
display:"block",
margin:"0 auto"
}}
ref={video => (this.video = video)}
src={cameraUrl}
width={previewContentStyle.width}
height={previewContentStyle.height}
/>
复制代码
这时就会看见一个 帅气的脸庞 出现在了屏幕上 !
这时来到了最后一步,截取画面,也很简单 把 video 节点画在 canvas 上, 然后 toDataURL() 蹬蹬,搞定
screenShotCamera = () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const { width, height } = previewContentStyle;
canvas.width = width;
canvas.height = height;
ctx.drawImage(this.video, 0, 0, width, height);
const data = canvas.toDataURL("image/png");
message.success('截取摄像头画面成功!')
this.setState({
currentImg: {
src: data
},
cameraVisible:false,
scale: defaultScale,
loading: false,
loadingImgReady: true
});
};
复制代码
5. 下载图片
下载图片 基于 HTML5 的 download 属性很好实现
const filename = Date.now()
const ext = isCompress ? 'jpeg' : 'png'
const link = document.createElement("a");
link.download = `${filename}.${ext}`;
link.href = dataUrl;
link.click();
复制代码
然后默认触发一次点击事件 搞定
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- iOS 上的相机捕捉
- 8千个城市2千万摄像头暴露:2018摄像头安全报告
- 为什么不建议在 for 循环里捕捉异常?
- 谷歌ARCore 1.6改善环境照明 抛光屏幕捕捉和记录
- 如何构建一个简单的摄像头组件
- [译] 充分利用多摄像头 API
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
jQuery实战(第2版)
[美]Bear Bibeault、[美]Yehuda Katz / 三生石上 / 人民邮电出版社 / 2012-3 / 69.00元
jQuery 是目前最受欢迎的JavaScript/Ajax 库之一,能用最少的代码实现最多的功能。本书全面介绍jQuery 知识,展示如何遍历HTML 文档、处理事件、执行动画、给网页添加Ajax 以及jQuery UI 。书中紧紧地围绕“用实际的示例来解释每一个新概念”这一宗旨,生动描述了jQuery 如何与其他工具和框架交互以及如何生成jQuery 插件。 本书适合各层次Web 开发人......一起来看看 《jQuery实战(第2版)》 这本书的介绍吧!