Vue.js ile HTML5 Canvas Kontrolü ve Grafik Çizimi
Bu rehberde Vue.js bileşen yapısını HTML5 Canvas API ile birlikte kullanmayı öğreneceksiniz.
Amaç, DOM’a yük bindirmeden reaktif ve akıcı grafikler çizmektir.
Örnek olarak Rabisu Bulut sunucularındaki yükü temsil eden canlı bir bar chart geliştireceğiz.
Bu yöntem; izleme panelleri, grafikler ve oyunlar için idealdir.
🧠 Teknik Özet
Bu rehber Vue.js ile HTML5 Canvas entegrasyonunu anlatır.
Problem: Canvas çizimlerinin Vue reaktivitesiyle senkron yönetilmesi.
Çözüm: provide / inject yapısı ile çizim context’ini bileşenlere aktarmak.
Ön Gereksinimler
- Bilgisayarınızda Node.js kurulu olmalı
- Temel seviyede Vue.js bilgisi yeterlidir
1️⃣ Projeyi Oluşturma
Vue CLI ile yeni bir proje başlatın.
npx @vue/cli create rabisu-grafik-panel
- Bu komut varsayılan ayarlarla Vue projesi oluşturur.
cd rabisu-grafik-panel
- Bu komut proje dizinine geçiş yapar.
2️⃣ Canvas Kapsayıcısını Hazırlama (Provider)
- Canvas alanını yöneten ana bileşeni oluşturuyoruz. Bu bileşen çizim yetkisini alt bileşenlere dağıtır.
src/components/MyCanvas.vue
<template>
<div class="canvas-wrapper">
<canvas ref="my-canvas"></canvas>
<slot></slot>
</div>
</template>
<script>
export default {
data() {
return {
provider: {
context: null,
},
};
},
provide() {
return {
provider: this.provider,
};
},
mounted() {
const canvas = this.$refs['my-canvas'];
this.provider.context = canvas.getContext('2d');
canvas.width = canvas.parentElement.clientWidth;
canvas.height = canvas.parentElement.clientHeight;
},
};
</script>
- Bu kod Canvas context’ini reaktif şekilde alt bileşenlere aktarır.
3️⃣ Renderless Çizim Bileşeni Oluşturma
- Bu bileşen DOM’a HTML basmaz. Canvas üzerine doğrudan çizim yapar.
src/components/MyBox.vue
<script>
const pxX = (p, ctx) => Math.floor((ctx.canvas.width / 100) * p);
const pxY = (p, ctx) => Math.floor((ctx.canvas.height / 100) * p);
export default {
inject: ['provider'],
props: {
x1: Number,
y1: Number,
x2: Number,
y2: Number,
deger: Number,
renk: String,
},
data() {
return {
oncekiKutu: { x: 0, y: 0, w: 0, h: 0 },
};
},
computed: {
hesaplananKutu() {
const ctx = this.provider.context;
if (!ctx) return null;
const kutu = {
x: pxX(this.x1, ctx),
y: pxY(this.y1, ctx),
w: pxX(this.x2 - this.x1, ctx),
h: pxY(this.y2 - this.y1, ctx),
};
this.oncekiKutu = kutu;
return kutu;
},
},
render() {
if (!this.provider.context) return;
const ctx = this.provider.context;
const k = this.hesaplananKutu;
ctx.clearRect(this.oncekiKutu.x, this.oncekiKutu.y, this.oncekiKutu.w, this.oncekiKutu.h);
ctx.fillStyle = this.renk;
ctx.fillRect(k.x, k.y, k.w, k.h);
ctx.fillStyle = '#000';
ctx.font = '20px Arial';
ctx.textAlign = 'center';
ctx.fillText(`${Math.floor(this.deger)}%`, k.x + k.w / 2, k.y - 10);
},
};
</script>
- Bu yapı Vue reaktivitesi değiştiğinde Canvas’ı otomatik günceller.
4️⃣ Uygulamayı Birleştirme
- Sunucu yüklerini simüle eden ana bileşeni oluşturalım.
src/App.vue
<template>
<div id="app">
<h2>Rabisu Bulut - Sunucu Yük İzleme</h2>
<my-canvas style="width:100%; height:500px; border:1px solid #ccc">
<my-box
v-for="(sunucu, index) in sunucuMetrikleri"
:key="index"
:x1="(index / sunucuMetrikleri.length) * 100"
:x2="(index / sunucuMetrikleri.length) * 100 + 100 / sunucuMetrikleri.length"
:y1="100"
:y2="100 - sunucu.yuk"
:renk="sunucu.renk"
:deger="sunucu.yuk"
/>
</my-canvas>
</div>
</template>
<script>
import MyCanvas from './components/MyCanvas.vue';
import MyBox from './components/MyBox.vue';
export default {
components: { MyCanvas, MyBox },
data() {
return {
sunucuMetrikleri: [
{ yuk: 45, renk: '#ff6b6b' },
{ yuk: 20, renk: '#4ecdc4' },
{ yuk: 78, renk: '#ffe66d' },
{ yuk: 12, renk: '#1a535c' },
],
};
},
mounted() {
setInterval(() => {
const i = Math.floor(Math.random() * this.sunucuMetrikleri.length);
let v = this.sunucuMetrikleri[i].yuk + (Math.random() - 0.5) * 10;
this.sunucuMetrikleri[i].yuk = Math.max(0, Math.min(100, v));
}, 100);
},
};
</script>
- Bu yapı canlı veri akışını simüle eder.
❓ Sıkça Sorulan Sorular
1. Canvas neden tercih edilir? Yüksek performans ve düşük DOM maliyeti sağlar.
2. Template yerine render kullanmam şart mı? Canvas çizimi için evet.
3. Mobil uyumlu mu? Evet, tüm modern tarayıcılar destekler.
4. Vue 3’te çalışır mı? Mantık aynıdır, API uyarlaması gerekir.
🎯 Sonuç
Vue.js reaktivitesini kaybetmeden HTML5 Canvas üzerinde çizim yaptınız. Bu yöntemle izleme panelleri, grafikler ve oyunlar geliştirebilirsiniz.
Projelerinizi Rabisu Bulut altyapısında barındırarak hemen yayına alabilirsiniz. 🚀