在VueJS中调整画布大小

问题描述

再次与我,一滴。我正在努力调整我的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

但这似乎没有任何作用。

这是桌面视图和移动视图的屏幕截图

Desktop View

Mobile View

到目前为止,感谢所有回答我的问题的人,您的帮助很大!我是开发新手,所以路途艰难: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;
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...