feat 大头贴
@ -0,0 +1,60 @@
|
||||
@charset "utf-8";
|
||||
|
||||
:root {
|
||||
font-size: 1vw;
|
||||
--c-d-1: #000;
|
||||
--c-l-1: #FFF;
|
||||
}
|
||||
|
||||
body,html {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
background-color: var(--c-d-1);
|
||||
color: var(--c-l-1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.p-root {
|
||||
width: 100vw;
|
||||
height: 100vw;
|
||||
position: relative;
|
||||
}
|
||||
.p-root>*{
|
||||
border: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position:absolute;
|
||||
top:0;
|
||||
left: 0;
|
||||
}
|
||||
.p-root>div{
|
||||
line-height: 100vw;
|
||||
text-align: center;
|
||||
color: rgba(255,255,255,.3);
|
||||
text-shadow: 0 0 1vw rgba(0,0,0,.5);
|
||||
font-size: 15vw;
|
||||
font-weight: 900;
|
||||
}
|
||||
.p-root>div>div {
|
||||
float: left;
|
||||
width: 50vw;
|
||||
}
|
||||
.p-imgs {
|
||||
width: 100vw;
|
||||
height: calc(50vh - 50vw);
|
||||
display: flex;
|
||||
overflow: visible;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.p-imgs>img {
|
||||
width: calc(50vh - 52vw);
|
||||
height: calc(50vh - 52vw);
|
||||
margin: 1vw;
|
||||
background-color: var(--c-l-1);
|
||||
display: block;
|
||||
|
||||
}
|
||||
|
After Width: | Height: | Size: 538 KiB |
|
After Width: | Height: | Size: 362 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 188 KiB |
|
After Width: | Height: | Size: 147 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 99 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 167 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 164 KiB |
@ -0,0 +1 @@
|
||||
image.png
|
||||
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>大头贴</title>
|
||||
<link rel="stylesheet" href="css/index.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="p-root">
|
||||
<video muted autoplay width="1200" height="1200"></video>
|
||||
<canvas width="1200" height="1200"></canvas>
|
||||
<img src="imgs/01.png">
|
||||
<div>拍照</div>
|
||||
<div>
|
||||
<div>确定</div>
|
||||
<div>取消</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--下面放图片模板-->
|
||||
<div class="p-imgs">
|
||||
</div>
|
||||
<!--下面放拍好的照片-->
|
||||
<div class="p-imgs">
|
||||
</div>
|
||||
<script type="module" src="js/index.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -0,0 +1,134 @@
|
||||
let root = document.querySelector(".p-root");
|
||||
let imgs = document.querySelectorAll(".p-imgs");
|
||||
let video = root.children[0];
|
||||
let canvas = root.children[1];
|
||||
let img = root.children[2];
|
||||
let btnTack = root.children[3];
|
||||
let btns = root.children[4];
|
||||
let btnConfirm = btns.children[0];
|
||||
let btnCancel = btns.children[1];
|
||||
|
||||
/**
|
||||
* 处理点击选择模板图片
|
||||
*/
|
||||
imgs[0].addEventListener("click", (e) => {
|
||||
if (e.target instanceof HTMLImageElement) {
|
||||
img.src = e.target.src;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 生成模板图片
|
||||
*/
|
||||
for (let i = 1; i <= 24; i++) {
|
||||
let img = new Image();
|
||||
img.onerror = () => {
|
||||
img.src = "imgs/01.png";
|
||||
}
|
||||
img.src = "imgs/" + i.toString().padStart(2, "0") + ".png";
|
||||
imgs[0].appendChild(img);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理图片的左右移动
|
||||
*/
|
||||
imgs.forEach(item => {
|
||||
let x = 0;
|
||||
let x1 = -1;
|
||||
console.info(item.scrollWidth, item.clientWidth);
|
||||
item.addEventListener("touchmove", (e) => {//绑定触摸移动事件
|
||||
if (x1 > -1) {
|
||||
x += e.changedTouches[0].screenX - x1;
|
||||
}
|
||||
x1 = e.changedTouches[0].screenX;
|
||||
item.style.left = x + "px";
|
||||
});
|
||||
item.addEventListener("touchend", (e) => {//绑定触摸移动事件结束
|
||||
x1 = -1;
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取视频流
|
||||
*/
|
||||
btns.hidden = true;//确定,取消不可见
|
||||
navigator.mediaDevices.getUserMedia({
|
||||
audio: false,
|
||||
video: {
|
||||
facingMode: "environment",//前置:user,后置:environment
|
||||
width: { min: 800, ideal: 1080, max: 2000 },
|
||||
height: { min: 800, ideal: 1080, max: 2000 }
|
||||
}
|
||||
// width:800,
|
||||
// height:800
|
||||
|
||||
|
||||
// }).catch(e=>{
|
||||
// console.error(e);
|
||||
// return navigator.mediaDevices.getUserMedia({
|
||||
// audio:false,
|
||||
// video:{
|
||||
// facingMode: "environment",//前置:user,后置:environment
|
||||
// // width: {min:100,ideal: 200,max:2000},
|
||||
// // height: {min:100,ideal: 200,max:2000 }
|
||||
|
||||
// }
|
||||
// });
|
||||
}).then((stream) => {
|
||||
console.info(stream);
|
||||
console.info(stream.getTracks()[0]);
|
||||
console.info(stream.getTracks()[0].getConstraints());
|
||||
console.info(stream.getTracks()[0].getSettings());
|
||||
console.info(stream.getTracks()[0].getCapabilities());
|
||||
console.info(stream.getTracks()[0].applyConstraints());
|
||||
console.info(stream.getVideoTracks());
|
||||
// video.onloadedmetadata = function (e) {
|
||||
// console.info(e);
|
||||
// };
|
||||
video.srcObject = stream;
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
alert("摄像设备不可用");
|
||||
});
|
||||
|
||||
/**
|
||||
* 处理拍照
|
||||
*/
|
||||
btnTack.addEventListener("click", () => {
|
||||
canvas.getContext('2d').drawImage(video, 0, 0, 1200, 1200);
|
||||
btnTack.hidden = true;
|
||||
btns.hidden = false;
|
||||
});
|
||||
|
||||
/**
|
||||
* 处理取消
|
||||
*/
|
||||
btnCancel.addEventListener("click", () => {
|
||||
canvas.getContext('2d').clearRect(0, 0, 1200, 1200);
|
||||
btnTack.hidden = false;
|
||||
btns.hidden = true;
|
||||
});
|
||||
/**
|
||||
* 处理确定
|
||||
*/
|
||||
btnConfirm.addEventListener("click", () => {
|
||||
canvas.getContext('2d').drawImage(img, 0, 0, 1200, 1200);
|
||||
let item = new Image();
|
||||
item.src = canvas.toDataURL("image/png");
|
||||
imgs[1].appendChild(item);
|
||||
canvas.getContext('2d').clearRect(0, 0, 1200, 1200);
|
||||
btnTack.hidden = false;
|
||||
btns.hidden = true;
|
||||
});
|
||||
|
||||
/**
|
||||
* 处理点击照片事件
|
||||
*/
|
||||
imgs[1].addEventListener("click", (e) => {
|
||||
if (e.target instanceof HTMLImageElement) {
|
||||
let a = document.createElement("a");
|
||||
a.href = e.target.src;
|
||||
a.download = "大头贴-" + new Date().getTime() + ".png";
|
||||
a.click();
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,93 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>实验01.抓取摄像头图片到画布</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="temp">
|
||||
<div title="摄像头">
|
||||
<video class="p-camera" muted autoplay></video>
|
||||
<button class="p-button">拍照</button>
|
||||
</div>
|
||||
<div title="画布">
|
||||
<canvas class="p-canvas"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
:root {
|
||||
font-size: 1vw;
|
||||
--c-d-1: #000;
|
||||
--c-l-1: #FFF;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 1rem;
|
||||
background-color: var(--c-l-1);
|
||||
}
|
||||
|
||||
.temp {
|
||||
display: grid;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.temp>* {
|
||||
border: var(--c-d-1) .1rem solid;
|
||||
min-height: 10rem;
|
||||
position: relative;
|
||||
padding: .7rem;
|
||||
}
|
||||
|
||||
.temp>*[title]::before {
|
||||
content: attr(title);
|
||||
position: absolute;
|
||||
font-size: 1rem;
|
||||
line-height: 1;
|
||||
background-color: var(--c-l-1);
|
||||
top: -.7rem;
|
||||
left: 1rem;
|
||||
}
|
||||
.p-camera,.p-canvas {
|
||||
background-color: var(--c-d-1);
|
||||
width: 100%;
|
||||
height: 40vh;
|
||||
}
|
||||
</style>
|
||||
<script type="module">
|
||||
let root = document.body;
|
||||
let camera = root.querySelector(".p-camera");
|
||||
let button = root.querySelector(".p-button");
|
||||
let canvas = root.querySelector(".p-canvas");
|
||||
console.debug(camera,button,canvas);
|
||||
console.debug(camera.clientWidth,camera.clientHeight);
|
||||
canvas.setAttribute("width",camera.clientWidth);
|
||||
canvas.setAttribute("height",camera.clientHeight);
|
||||
camera.setAttribute("width",camera.clientWidth);
|
||||
camera.setAttribute("height",camera.clientHeight);
|
||||
|
||||
navigator.mediaDevices.getUserMedia({
|
||||
audio:false,
|
||||
video:{
|
||||
facingMode: "environment",//前置:user,后置:environment
|
||||
width: {ideal: camera.clientWidth},
|
||||
height: {ideal: camera.clientHeight }
|
||||
|
||||
}
|
||||
}).then((stream)=>{
|
||||
camera.srcObject=stream;
|
||||
}).catch(e=>{
|
||||
console.debug(e.message);
|
||||
console.error(e);
|
||||
});
|
||||
button.addEventListener("click",()=>{
|
||||
canvas.getContext('2d').drawImage(camera, 0, 0, camera.clientWidth,camera.clientHeight);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>实验02.使用画布合成多张图片</title>
|
||||
</head>
|
||||
<body>
|
||||
<canvas></canvas>
|
||||
<canvas></canvas>
|
||||
<canvas></canvas>
|
||||
<button>保存画布图片</button>
|
||||
<style>
|
||||
canvas {
|
||||
border: 3px solid #FFF;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 0 2px #666;
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
}
|
||||
</style>
|
||||
<script type="module">
|
||||
let cs = document.querySelectorAll("canvas");
|
||||
for(let c of cs){
|
||||
c.width=2000;
|
||||
c.height=2000;
|
||||
}
|
||||
console.debug(cs);
|
||||
let c0 = cs[0].getContext("2d");
|
||||
let c1 = cs[1].getContext("2d");
|
||||
let c2 = cs[2].getContext("2d");
|
||||
console.debug(c1);
|
||||
let loadImage = function(src){
|
||||
return new Promise((resolve,reject)=>{
|
||||
let img = new Image();
|
||||
img.onload=()=>{
|
||||
resolve(img);
|
||||
};
|
||||
img.onerror=reject;
|
||||
img.style.display="none";
|
||||
img.src=src;
|
||||
document.body.appendChild(img);
|
||||
});
|
||||
}
|
||||
loadImage("imgs/01.png").then((img)=>{
|
||||
c0.drawImage(img,0,0,2000,2000);
|
||||
c2.drawImage(img,0,0,2000,2000);
|
||||
return loadImage("imgs/02.png");
|
||||
}).then((img)=>{
|
||||
c1.drawImage(img,0,0,2000,2000);
|
||||
c2.drawImage(img,0,0,2000,2000);
|
||||
});
|
||||
document.querySelector("button").onclick=()=>{
|
||||
let a = document.createElement("a");
|
||||
a.href = cs[2].toDataURL("image/png");
|
||||
a.download="大头贴-"+new Date().getTime()+".png";
|
||||
a.click();
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||