vue.js - 在 VueJS 中调整画布大小
问题描述
又是我,和blob。我正在努力让我的画布元素像 VueJS 中的其他布局一样调整大小并具有移动响应能力。我正在使用 NuxtJS。
下面是我的 VueJS 文件(我在触发窗口大小调整的方法中调用了 resize() 方法):
<template id="breath">
<div id="page__home">
<v-row dense>
<v-col cols="12" align="center" justify="center">
<h1 class="card__header">
<v-icon large color="black">
mdi-comment-question-outline
</v-icon>
Mindful Breathing
</h1>
<canvas id="canvas" width="450" height="450"></canvas>
<h1 class="instructions">{{ breathText[0] }}</h1>
<v-container fluid class="container">
<v-row align="center" justify="center">
<v-spacer></v-spacer>
<v-btn fab medium color="secondary">
<v-icon color="black">
mdi-volume-high
</v-icon>
</v-btn>
<v-spacer></v-spacer>
<v-btn fab x-large color="primary" @click="start">
<v-icon large color="white">
mdi-play
</v-icon>
</v-btn>
<v-spacer></v-spacer>
<v-btn fab medium color="secondary">
<v-icon color="black">
mdi-tune-vertical
</v-icon>
</v-btn>
<v-spacer></v-spacer>
</v-row>
</v-container>
</v-col>
</v-row>
</div>
</template>
<script>
import Blob from "../assets/content/Blob_Point"
import { Point } from "../assets/content/Blob_Point"
let oldMousePoint = { x: 0, y: 0 }
let blob = new Blob()
let hover = false
export default {
data() {
return {
canvas: null,
x: 0,
y: 0,
isDrawing: false,
rectWidth: 200,
dir: 0.25,
radius: 200,
ticker: undefined,
timer: undefined,
timerState: "stopped",
displaySec: 10,
breathText: ["Inhale", "Hold", "Exhale", "Hold"],
}
},
mounted() {
let canvas = document.getElementById("canvas")
this.canvas = canvas.getContext("2d")
canvas.setAttribute("touch-action", "none")
blob = new Blob(this.color, this.canvas)
blob.color = "#8CE5EA"
blob.canvas = canvas
blob.init()
blob.render()
blob.f_varySize()
},
created() {
window.addEventListener("pointermove", this.mouseMove)
window.addEventListener("mousemove", this.mouseMove)
},
methods: {
start() {
if (this.timerState !== "running") {
this.tick()
this.timerState = "running"
} else {
window.clearInterval(this.timer)
this.timerState = "stopped"
}
},
// ------ Text Change methods + Timer ---------//
tick() {
this.timer = window.setInterval(() => {
this.textChange()
}, 500)
},
textChange() {
const first = this.breathText.shift()
this.breathText = this.breathText.concat(first)
},
// ------------------------------------------//
// ------ Window Resize (Not functioning)---//
resize() {
document.getElementById("canvas").width = window.innerWidth
document.getElementById("canvas").height = window.innerHeight
},
//-------//
// -------- spring/wave animation on mouseOver of blob ----//
mouseMove(e) {
let pos = blob.center
let diff = { x: e.clientX - pos.x, y: e.clientY - pos.y }
let dist = Math.sqrt(diff.x * diff.x + diff.y * diff.y)
let angle = null
blob.mousePos = {
x: pos.x - e.clientX,
y: pos.y - e.clientY,
}
if (dist < blob.radius && hover === false) {
let vector = {
x: e.clientX - pos.x,
y: e.clientY - pos.y,
}
angle = Math.atan2(vector.y, vector.x)
hover = true
// blob.color = '#77FF00';
} else if (dist > blob.radius && hover === true) {
let vector = {
x: e.clientX - pos.x,
y: e.clientY - pos.y,
}
angle = Math.atan2(vector.y, vector.x)
hover = false
blob.color = null
}
if (typeof angle == "number") {
let nearestPoint = null
let distanceFromPoint = 100
blob.points.forEach((point) => {
if (Math.abs(angle - point.azimuth) < distanceFromPoint) {
// console.log(point.azimuth, angle, distanceFromPoint);
nearestPoint = point
distanceFromPoint = Math.abs(angle - point.azimuth)
}
})
if (nearestPoint) {
let strength = {
x: oldMousePoint.x - e.clientX,
y: oldMousePoint.y - e.clientY,
}
strength =
Math.sqrt(strength.x * strength.x + strength.y * strength.y) * 1
if (strength > 100) strength = 100
nearestPoint.acceleration = (strength / 100) * (hover ? -1 : 1)
}
}
oldMousePoint.x = e.clientX
oldMousePoint.y = e.clientY
},
// ----- //
// ------ Blob initialisation ------//
init() {
for (let i = 0; i < this.numPoints; i++) {
let point = new Point(this.divisional * (i + 1), this)
point.acceleration = -1 + Math.random() * 2
this.push(point)
}
},
//---------//
// ------ changing blob radius (Not working) ----//
f_varySize() {
console.log("testing")
this.ticker = setInterval(() => {
/*if (this.radius > 200) {
this.dir = -0.25
//console.log(g_radius);
}
if (this.radius < 200) {
this.dir = 0.25
//console.log(g_radius);
} */
this.radius += this.dir
}, 20)
},
},
}
</script>
<style scoped>
#canvas {
border: 1px solid grey;
z-index: -1;
}
.instructions {
color: #fff;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 100;
}
</style>
我应该在脚本标签之外执行此操作吗?VueJS 中是否有另一种我没有用来实现这一目标的方法?我试过设置
document.getElementById("canvas").width = window.innerWidth
document.getElementById("canvas").height = window.innerHeight
至
document.getElementById("canvas").width = this.window.innerWidth
document.getElementById("canvas").height = this.window.innerHeight
但它似乎没有任何效果。
这是桌面视图和移动视图的屏幕截图
感谢到目前为止一直在回答我的问题的每个人,您给了我很大的帮助!我是开发新手,所以这是一条崎岖的道路:D
解决方案
如果您使用的是 vuetify,那么断点可以帮助您根据屏幕设置动态高度宽度
new Vue({
el: '#app',
vuetify: new Vuetify(),
computed :{
getWidth() {
if(this.$vuetify.breakpoint.mobile){
return 200
} else {
return 300
}
},
getHeight() {
if(this.$vuetify.breakpoint.mobile){
return 200
} else {
return 300
}
}
}
})
canvas{
border : 1px solid
}
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<div id="app">
<v-app>
<v-main>
<v-container>
<canvas id="canvas" :width="getWidth" :height="getHeight"></canvas>
</v-container>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
</body>
</html>
推荐阅读
- django - 让 django 为 html 选择标签选择正确的选项
- snowflake-cloud-data-platform - 雪花 - 如何引用名称中带有特殊字符的指定表的内部阶段?
- c# - 如何在 Xamarin 中显示带有三个点的工具栏?
- swagger - OpenApi:从多个文件中生成 java/kotlin DTO
- reactjs - 类型断言对象字面量打字稿
- android - 从 Mac 到 Android 的 ADB 连接被拒绝
- perl - 我有两个使用 Perl 转换数据的问题?
- c++ - .eof() 使用数组时替换
- java - 付款时的子值计数器 Firebase Android
- sql - sql中每组的分层抽样