Javascript 画布的宽度和高度属性在Vue JS中返回0
我正在使用Vue JS,我的组件中有2个画布(我正在尝试重新创建) 组件的模板部分:Javascript 画布的宽度和高度属性在Vue JS中返回0,javascript,html,css,vue.js,Javascript,Html,Css,Vue.js,我正在使用Vue JS,我的组件中有2个画布(我正在尝试重新创建) 组件的模板部分: <template> <div class="d-flex flex-column"> <div class="d-flex flex-column" style="height: 300px;"> <canvas ref="overlay" id="overlay" style="position: absolute;
<template>
<div class="d-flex flex-column">
<div class="d-flex flex-column" style="height: 300px;">
<canvas ref="overlay" id="overlay" style="position: absolute; pointer-events: none"></canvas>
<canvas ref="canvas" :id="canvasId"></canvas>
</div>
<vue-slider @drag-end="selectRange" class="w-100 mb-3 mx-3 p-0 pr-3" ref="slider" v-model="sliderValue" v-bind="sliderOptions"></vue-slider>
</div>
</template>
<script>
import chartjs from "chart.js";
import vueSlider from "vue-slider-component";
import {Line} from "vue-chartjs";
const props = {
dataset: {
type: Array,
required: true
},
index: {
type: Number,
required: true
},
sliderShow: {
type: Boolean,
required: true
}
};
export default {
components: { vueSlider },
extends: Line,
name: "rhythmogram",
props,
data() {
return {
canvasId: "",
sliderValue: [],
sliderOptions: {
tooltip: "hover",
"tooltip-dir": "bottom",
overlapFormatter: "{value1} - {value2}",
tooltipStyle: {
"borderRadius": "0px"
},
useKeyboard: true,
data: []
},
chartData: [],
xLabels: []
};
},
mounted() {
this.canvasId = `areachart${this.index}`;
this.$nextTick(() => {
// ...
// filling this.chartData and this.xLabels
// ...
this.renderChart({
labels: this.xLabels,
datasets: [{
label: this.name,
data: this.chartData
}]
}, {
maintainAspectRatio: false,
elements: {
line: {
tension: 0.2,
borderWidth: 1,
borderColor: "rgba(24, 81, 154, .95)",
backgroundColor: "rgba(24, 81, 154, .5)"
},
point: {
pointStyle: "circle",
radius: 0
}
},
tooltips: {
enabled: false
},
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
min: minValueToDisplay,
max: maxValueToDisplay
}
}],
xAxes: [{
ticks: {
stepSize: 10
}
}]
}
});
// Overlay
var canvas = this.$refs.canvas;
var overlay = this.$refs.overlay;
var chart = this._data._chart;
var startIndex = 0;
var endIndex = 0;
overlay.width = canvas.width;
overlay.height = canvas.height;
console.log(canvas); //this returns the correct element with width and height > 0
console.log("Width:\t" + canvas.width); //this returns 0
console.log("Height:\t" + canvas.height); // this returns 0
var selectionContext = overlay.getContext('2d');
var selectionRect = {
w: 0,
startX: 0,
startY: 0
};
var drag = false;
canvas.addEventListener('pointerdown', evt => {
const points = chart.getElementsAtEventForMode(evt, 'index', {
intersect: false
});
startIndex = points[0]._index;
const rect = canvas.getBoundingClientRect();
selectionRect.startX = evt.clientX - rect.left;
selectionRect.startY = chart.chartArea.top;
drag = true;
});
canvas.addEventListener('pointermove', evt => {
const rect = canvas.getBoundingClientRect();
if (drag) {
const rect = canvas.getBoundingClientRect();
selectionRect.w = (evt.clientX - rect.left) - selectionRect.startX;
selectionContext.globalAlpha = 0.5;
selectionContext.clearRect(0, 0, canvas.width, canvas.height);
selectionContext.fillRect(selectionRect.startX, selectionRect.startY, selectionRect.w, chart.chartArea.bottom -
chart.chartArea.top);
} else {
selectionContext.clearRect(0, 0, canvas.widht, canvas.height);
var x = evt.clientX - rect.left;
if (x > chart.chartArea.left) {
selectionContext.fillRect(x, chart.chartArea.top, 1, chart.chartArea.bottom - chart.chartArea.top);
}
}
});
canvas.addEventListener('pointerup', evt => {
const points = chart.getElementsAtEventForMode(evt, 'index', {
intersect: false
});
drag = false;
console.log('selected: ' + this.sliderOptions.data[startIndex] + ', ' + this.sliderOptions.data[points[0]._index]);
});
});
},
methods: {
selectRange() {
// stuff
}
},
watch: {
sliderShow(val) {
// stuff
}
}
};
</script>
组件的脚本部分:
<template>
<div class="d-flex flex-column">
<div class="d-flex flex-column" style="height: 300px;">
<canvas ref="overlay" id="overlay" style="position: absolute; pointer-events: none"></canvas>
<canvas ref="canvas" :id="canvasId"></canvas>
</div>
<vue-slider @drag-end="selectRange" class="w-100 mb-3 mx-3 p-0 pr-3" ref="slider" v-model="sliderValue" v-bind="sliderOptions"></vue-slider>
</div>
</template>
<script>
import chartjs from "chart.js";
import vueSlider from "vue-slider-component";
import {Line} from "vue-chartjs";
const props = {
dataset: {
type: Array,
required: true
},
index: {
type: Number,
required: true
},
sliderShow: {
type: Boolean,
required: true
}
};
export default {
components: { vueSlider },
extends: Line,
name: "rhythmogram",
props,
data() {
return {
canvasId: "",
sliderValue: [],
sliderOptions: {
tooltip: "hover",
"tooltip-dir": "bottom",
overlapFormatter: "{value1} - {value2}",
tooltipStyle: {
"borderRadius": "0px"
},
useKeyboard: true,
data: []
},
chartData: [],
xLabels: []
};
},
mounted() {
this.canvasId = `areachart${this.index}`;
this.$nextTick(() => {
// ...
// filling this.chartData and this.xLabels
// ...
this.renderChart({
labels: this.xLabels,
datasets: [{
label: this.name,
data: this.chartData
}]
}, {
maintainAspectRatio: false,
elements: {
line: {
tension: 0.2,
borderWidth: 1,
borderColor: "rgba(24, 81, 154, .95)",
backgroundColor: "rgba(24, 81, 154, .5)"
},
point: {
pointStyle: "circle",
radius: 0
}
},
tooltips: {
enabled: false
},
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
min: minValueToDisplay,
max: maxValueToDisplay
}
}],
xAxes: [{
ticks: {
stepSize: 10
}
}]
}
});
// Overlay
var canvas = this.$refs.canvas;
var overlay = this.$refs.overlay;
var chart = this._data._chart;
var startIndex = 0;
var endIndex = 0;
overlay.width = canvas.width;
overlay.height = canvas.height;
console.log(canvas); //this returns the correct element with width and height > 0
console.log("Width:\t" + canvas.width); //this returns 0
console.log("Height:\t" + canvas.height); // this returns 0
var selectionContext = overlay.getContext('2d');
var selectionRect = {
w: 0,
startX: 0,
startY: 0
};
var drag = false;
canvas.addEventListener('pointerdown', evt => {
const points = chart.getElementsAtEventForMode(evt, 'index', {
intersect: false
});
startIndex = points[0]._index;
const rect = canvas.getBoundingClientRect();
selectionRect.startX = evt.clientX - rect.left;
selectionRect.startY = chart.chartArea.top;
drag = true;
});
canvas.addEventListener('pointermove', evt => {
const rect = canvas.getBoundingClientRect();
if (drag) {
const rect = canvas.getBoundingClientRect();
selectionRect.w = (evt.clientX - rect.left) - selectionRect.startX;
selectionContext.globalAlpha = 0.5;
selectionContext.clearRect(0, 0, canvas.width, canvas.height);
selectionContext.fillRect(selectionRect.startX, selectionRect.startY, selectionRect.w, chart.chartArea.bottom -
chart.chartArea.top);
} else {
selectionContext.clearRect(0, 0, canvas.widht, canvas.height);
var x = evt.clientX - rect.left;
if (x > chart.chartArea.left) {
selectionContext.fillRect(x, chart.chartArea.top, 1, chart.chartArea.bottom - chart.chartArea.top);
}
}
});
canvas.addEventListener('pointerup', evt => {
const points = chart.getElementsAtEventForMode(evt, 'index', {
intersect: false
});
drag = false;
console.log('selected: ' + this.sliderOptions.data[startIndex] + ', ' + this.sliderOptions.data[points[0]._index]);
});
});
},
methods: {
selectRange() {
// stuff
}
},
watch: {
sliderShow(val) {
// stuff
}
}
};
</script>
从“chart.js”导入chartjs;
从“vue滑块组件”导入vueSlider;
从“vue chartjs”导入{Line};
常量道具={
数据集:{
类型:数组,
必填项:true
},
索引:{
类型:数字,
必填项:true
},
幻灯片放映:{
类型:布尔型,
必填项:true
}
};
导出默认值{
组件:{vueSlider},
扩展:行,
名称:“节律图”,
道具,
数据(){
返回{
画布:“,
sliderValue:[],
幻灯片选项:{
工具提示:“悬停”,
“工具提示目录”:“底部”,
重叠格式化程序:“{value1}-{value2}”,
工具提示样式:{
“边界半径”:“0px”
},
是的,
数据:[]
},
图表数据:[],
xLabels:[]
};
},
安装的(){
this.canvasId=`areachart${this.index}`;
这个.$nextTick(()=>{
// ...
//填充this.chartData和this.xLabels
// ...
这是我的艺术({
标签:this.xLabels,
数据集:[{
标签:this.name,
data:this.chartData
}]
}, {
MaintaintAspectRatio:false,
要素:{
行:{
张力:0.2,
边框宽度:1,
边框颜色:“rgba(24,81,154,95)”,
背景色:“rgba(24,81,154,5)”
},
要点:{
点样式:“圆”,
半径:0
}
},
工具提示:{
已启用:false
},
图例:{
显示:假
},
比例:{
雅克斯:[{
滴答声:{
贝吉纳泽罗:是的,
min:minValueToDisplay,
max:maxValueToDisplay
}
}],
xAxes:[{
滴答声:{
步长:10
}
}]
}
});
//覆盖层
var canvas=此。$refs.canvas;
var overlay=此。$refs.overlay;
var图表=此。_数据。_图表;
var startIndex=0;
var-endIndex=0;
overlay.width=canvas.width;
overlay.height=canvas.height;
console.log(canvas);//返回宽度和高度大于0的正确元素
console.log(“宽度:\t”+canvas.Width);//返回0
console.log(“Height:\t”+canvas.Height);//返回0
var selectionContext=overlay.getContext('2d');
变量selectionRect={
w:0,
startX:0,
startY:0
};
var-drag=false;
canvas.addEventListener('pointerdown',evt=>{
常量点=chart.getElementsAtEventForMode(evt,'索引'{
交集:错
});
startIndex=点[0]。\u指数;
const rect=canvas.getBoundingClientRect();
selectionRect.startX=evt.clientX-rect.left;
selectionRect.startY=chart.chartArea.top;
阻力=真;
});
canvas.addEventListener('pointermove',evt=>{
const rect=canvas.getBoundingClientRect();
如果(拖动){
const rect=canvas.getBoundingClientRect();
selectionRect.w=(evt.clientX-rect.left)-selectionRect.startX;
selectionContext.globalAlpha=0.5;
selectionContext.clearRect(0,0,canvas.width,canvas.height);
selectionContext.fillRect(selectionRect.startX、selectionRect.startY、selectionRect.w、chart.chartArea.bottom-
chart.chartArea.top);
}否则{
selectionContext.clearRect(0,0,canvas.widt,canvas.height);
var x=evt.clientX-rect.left;
如果(x>chart.chartArea.left){
selectionContext.fillRect(x,chart.chartArea.top,1,chart.chartArea.bottom-chart.chartArea.top);
}
}
});
canvas.addEventListener('pointerup',evt=>{
常量点=chart.getElementsAtEventForMode(evt,'索引'{
交集:错
});
阻力=假;
console.log('所选:'+this.slideoptions.data[startIndex]+','+this.slideoptions.data[points[0].\u index]);
});
});
},
方法:{
selectRange(){