问题描述
再次与我,一滴。我正在努力调整我的canvas元素的大小,使其像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,}
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 那么breakpoints可以帮助您根据屏幕设置动态高度宽度
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>
,
我找到了一个仅使用CSS的修复程序,方法是将宽度设置为100%,将高度设置为自动
#canvas {
width: 100%;
height: auto;
position: relative;
z-index: 0;
}