效果图
template
下方的image图片自行寻找替换!
<template>
<view>
<camera
v-if="!tempImagePath && cameraHeight !== 0"
:resolution="'high'"
:frame-size="'large'"
:device-position="device"
:flash="flash"
:style="{
position: 'fixed',
top: '0',
width: cameraWidth + 'px',
height: cameraHeight + 'px',
}"
></camera>
<image
v-else
:src="tempImagePath"
mode="widthFix"
style="width: 100%"
></image>
<view class="watermark" v-if="cameraHeight !== 0">
<view class="time">
<text class="times-r">
{{ time }}
</text>
<text class="times-date">
<text class="year-date">
{{ date }}
</text>
<text class="weeks-date">
{{ week }}
</text>
</text>
</view>
<view class="location_box">
<view class="location">{{ address }}</view>
</view>
</view>
<canvas
type="2d"
id="canvas"
:style="{
position: 'fixed',
top: '-10000px',
left: '-10000px',
width: canvasWidth + 'px',
height: canvasHeight + 'px',
}"
></canvas>
<view class="handle" id="myContainer">
<button class="handle_card" @click="chooseLocation">
<image
class="handle_card_icon"
:src="require('./image/wz.png')"
mode="widthFix"
></image>
<view class="handle_card_name">定位</view>
</button>
<button class="handle_card" @click="setDevice">
<image
class="handle_card_icon"
:src="require('./image/qh.png')"
mode="widthFix"
></image>
<view class="handle_card_name">切换</view>
</button>
<button class="handle_ps" @click="takePhoto">
<image
class="handle_ps_image"
:src="require('./image/ps.png')"
mode="widthFix"
></image>
<view class="handle_ps_name">拍摄</view>
</button>
<button class="handle_card" @click="setFlash">
<image
class="handle_card_icon"
:src="require('./image/sd.png')"
mode="widthFix"
></image>
<view class="handle_card_name">闪光</view>
</button>
<button class="handle_card" open-type="share">
<image
class="handle_card_icon"
:src="require('./image/fx.png')"
mode="widthFix"
></image>
<view class="handle_card_name">分享</view>
</button>
</view>
</view>
</template>
js
开发者秘钥key自行填写,用于定位位置功能!
showToast和showLoading为自行封装的弹窗
如果没有直接用官网的uni.showToast
<script>
const mapSDK = new QQMapWX({
key: "", //申请的开发者秘钥key
});
import { showToast, showLoading } from "@/js/common.js";
export default {
data() {
return {
device: "back",
flash: "",
date: "",
time: "",
week: "",
address: "",
addressName: "",
cameraWidth: 0,
cameraHeight: 0,
canvasWidth: 0,
canvasHeight: 0,
tempImagePath: "",
timer: null,
};
},
created() {
const systemInfo = wx.getSystemInfoSync();
const screenWidth = systemInfo.screenWidth;
const screenHeight = systemInfo.screenHeight;
const statusBarHeight = systemInfo.statusBarHeight;
const menuButtonInfo = wx.getMenuButtonBoundingClientRect();
const cameraWidth = screenWidth;
uni
.createSelectorQuery()
.select("#myContainer")
.boundingClientRect((rect) => {
const cameraHeight =
screenHeight -
statusBarHeight -
menuButtonInfo.height -
(menuButtonInfo.top - systemInfo.statusBarHeight) * 2 -
rect.height;
this.cameraWidth = cameraWidth;
this.cameraHeight = cameraHeight;
this.getTime();
this.getLocation();
})
.exec();
},
methods: {
// 获取并更新时间的方法
getTime() {
this.timer = setInterval(() => {
const timeData = this.formatTime();
this.date = timeData.date;
this.time = timeData.time;
this.week = timeData.week;
}, 1000);
},
// 获取并更新位置信息的方法
getLocation() {
uni.getLocation({
success: (Locares) => {
mapSDK.reverseGeocoder({
location: {
latitude: Locares.latitude,
longitude: Locares.longitude,
},
get_poi: 1,
success:(res)=> {
this.address = res.address;
}
})
})
}
})
},
// 拍摄事件
takePhoto() {
const ctx = uni.createCameraContext();
ctx.takePhoto({
quality: "high",
success: (res) => {
this.canvasWidth = res.width;
this.canvasHeight = res.height;
this.tempImagePath = res.tempImagePath;
this.addWatermark(this.tempImagePath)
.then((addWatermark) => {
uni.saveImageToPhotosAlbum({
filePath: addWatermark,
success: () => {
showToast("保存成功");
this.tempImagePath = "";
},
});
})
.catch((e) => {
showToast(e);
})
}
})
},
/**
* 给图片添加水印
*/
addWatermark(imageUrl) {
return new Promise((resolve, reject) => {
showLoading("图片生成中...");
const query = uni.createSelectorQuery();
query
.select("#canvas")
.fields({
node: true,
})
.exec((res) => {
const canvas = res[0].node;
const ctx = canvas.getContext("2d");
const { canvasWidth, canvasHeight } = this;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
// 绘制背景图片
const image = canvas.createImage();
image.src = imageUrl;
image.onload = () => {
const sizeX = this.canvasWidth / 375;
ctx.drawImage(image, 0, 0);
ctx.font = `${35 * sizeX}px 黑体`;
ctx.fillStyle = "#ffffff";
ctx.textBaseline = "bottom";
// 绘制时间
ctx.fillText(this.time, 10 * sizeX, canvasHeight - 30 * sizeX);
const timeWidth = ctx.measureText(this.time).width;
// 绘制边框线条
ctx.beginPath();
ctx.lineCap = "round";
ctx.moveTo(timeWidth + 16 * sizeX, canvasHeight - 59 * sizeX);
ctx.lineTo(timeWidth + 16 * sizeX, canvasHeight - 36 * sizeX);
ctx.lineWidth = 3 * sizeX;
ctx.strokeStyle = "#7FCAF4";
ctx.stroke();
// 绘制年月日
ctx.font = `${12 * sizeX}px 黑体`;
ctx.fillText(
this.date,
timeWidth + 22 * sizeX,
canvasHeight - 49 * sizeX
);
// 绘制周几
ctx.fillText(
this.week,
timeWidth + 22 * sizeX,
canvasHeight - 34 * sizeX
);
// 绘制地址
ctx.font = `${14 * sizeX}px 黑体`;
ctx.fillText(this.address, 10 * sizeX, canvasHeight - 10 * sizeX);
uni.canvasToTempFilePath({
canvas,
success: (res) => {
uni.hideLoading();
console.log(canvas, res.tempFilePath, 199);
resolve(res.tempFilePath);
},
fail: (e) => {
uni.hideLoading();
reject(new Error(JSON.stringify(e)));
},
});
};
});
});
},
/**
* 切换摄像头
*/
setDevice() {
this.device = this.device === "back" ? "front" : "back";
const text = this.device === "back" ? "后置" : "前置";
showToast(`摄像头${text}`)
},
/**
* 闪光灯开关
*/
setFlash() {
this.flash = this.flash === "torch" ? "off" : "torch";
},
/**
* 选择位置信息
*/
chooseLocation() {
uni.chooseLocation({
success: (res) => {
this.address = res.address;
},
fail(err) {
console.log(err);
},
});
},
formatTime() {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const weekDay = ["日", "一", "二", "三", "四", "五", "六"][date.getDay()];
const hour = date.getHours();
const minute = date.getMinutes();
// const second = date.getSeconds(); 如果需要秒显示,自行修改
const formatNumber = (n) => {
const s = n.toString();
return s[1] ? s : "0" + s;
};
return {
date: [year, month, day].map(formatNumber).join("-"),
time: [hour, minute].map(formatNumber).join(":"),
week: "星期" + weekDay,
};
},
},
};
</script>
sass样式
<style lang="scss">
.handle {
position: fixed;
bottom: 0;
width: 100%;
height: 15%;
display: flex;
justify-content: space-around;
align-items: center;
font-size: 28rpx;
background: rgb(255, 255, 255);
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
.handle_ps,
.handle_card {
display: flex;
flex-direction: column;
text-align: center;
height: 75px;
line-height: 25px;
background: #ffffff;
padding: 0;
font-size: 25rpx;
}
.handle_ps {
&::after {
border: none;
}
}
.handle_card::after {
border: none;
}
.handle_ps_image {
width: 50px;
height: 50px;
}
.handle_card_name {
font-size: 25rpx;
}
.handle_card_icon {
width: 40px;
height: 40px;
margin: 5px;
}
.watermark {
position: fixed;
bottom: 16%;
left: 10px;
color: #fff;
}
.location_box {
display: flex;
line-height: 25px;
height: 25px;
}
.time {
display: flex;
.times-r {
position: relative;
font-size: 75rpx;
padding-right: 25rpx;
&::before {
content: "";
position: absolute;
width: 6rpx;
height: 53%;
border-radius: 10rpx;
background: #7fcaf4;
right: 8rpx;
top: 50%;
transform: translateY(-50%);
}
}
.times-date {
padding-left: 5rpx;
display: flex;
flex-direction: column;
justify-content: center;
font-size: 24rpx;
.year-date,
.weeks-date {
display: block;
}
}
}
.time,
.location {
color: #fff;
}
</style>
感谢你的阅读,如对你有帮助请收藏+关注!
只分享干货实战和精品,从不啰嗦!!!
如某处不对请留言评论,欢迎指正~
博主可收徒、常玩QQ飞车,可一起来玩玩鸭~