Kamis, 15 September 2022

Widget Kalender

Github:
https://github.com/forkHub/cemcem/tree/main/calendar


Widget kalender adalah pustaka fungsi untuk membantu membuat tampilan kalender pada website. Ada tiga fungsi utama untuk membuat tampilan kalender, salah satunya adalah fungsi untuk membuat tampilan kalender standard yang terdiri dari bulan, tahun, dan daftar tanggal.

Cara pakainya cukup mudah:

import * as kalender from "./Kalender.js"; 
document.body.appendChild(kalender.widget(8, 2022));

Bila dijalankan akan menampilkan sebuah tampilan standard kalender.
Anda bisa memilih untuk menaruh kalender di body, atau di bagian lain pada halaman.


Fungsi widget menerima dua parameter yaitu bulan dan tahun. Fungsi ini akan menghasilkan sebuah html element yang bisa di tambahkan sebagai child dari element yang sudah ada.

Tampilan ini adalah tampilan dasar, kita bisa mengkustom dengan cara mengedit class css tiap element. Tiap element diberi class yang lumayan banyak dan akan terus ditambahi untuk meningkatkan kustomisasi.

Anda bisa mendowload source code pada link github di atas.








Jumat, 18 Maret 2022

Algorithma Mengubah warna pada gambar menjadi 64 warna

Demo bisa dilihat disini : code (forkhub.github.io)


Pada tulisan ini Saya akan membahas algorithma untuk mengurangi jumlah warna pada gambar sehingga jumlahnya menjadi 64 warna saja. Kita sering melihat efek ini pada aplikasi pengedit gambar seperti Gimp. 

Dengan mengurangi jumlah warna pada gambar, maka kualitas gambar akan turun, seperti di bawah ini.


Setiap gambar dalam komputer terdiri dari kumpulan piksel, Tiap piksel memiliki 3 komponen warna, yaitu: merah, hijau dan biru. Tiap komponent warna memiliki intensitas mulai dari 0-255. Komputer bisa menampilkan sebanyak (256 x 256 x 256) warna atau sekitar 16 juta warna (16,777,216).

Tidak semua warna ditampilkan secara bersamaan, Saya belum menemukan sebuah gambar komputer yang memiliki warna sebanyak itu. 

Untuk mengubah jumlah warna sebuah gambar menjadi 64 warna saja, kita akan mengubah intensitas dari tiap komponen warna, yang awalnya memiliki 256 level menjadi hanya 4 saja.
 
Intensitas baru yang kita pakai akan terdiri dari 0, 85, 170, dan 255 saja. Angka ini adalah angka bebas. Saya memilih angka tersebut supaya persebarannya rata. Anda bisa mengubah-ubah angkanya untuk mendapatkan berbagai macam effect yang berbeda.

Bila setiap warna hanya memiliki level intensitas sebanyak 4 macam saja, maka jumlah warna yang bisa dihasilkan masimum adalah sebanyak 4 x 4 x 4 atau sama dengan 64 warna.

Dengan penyederhanaan ini maka setiap intensitas dari komponen warna yang ada akan dibulatkan ke intensitas baru yang terdekat. Kita bisa memilih metode pembulatannya: apakah pembulatan ke bawah, ke atas, atau pembulatan ke angka terdekat, atau kita bisa buat selang-seling antara pembulatan ke atas atau kebawah sesuai posisi dari pixelnya. 

Pembulatan selang-seling ini akan memberikan efek dithering, dan ini yang akan Saya pakai disini.

Kode sumbernya adalah sebagai berikut:

window.onload = () => {
    let canvas: HTMLCanvasElement = document.createElement('canvas');

    let ctx: CanvasRenderingContext2D = canvas.getContext('2d');

    let img: HTMLImageElement = document.getElementById('gbr') as HTMLImageElement;

    canvas.style.width = img.naturalWidth + 'px';

    canvas.style.height = img.naturalHeight + 'px';

    canvas.width = img.naturalWidth;

    canvas.height = img.naturalHeight;

    document.body.appendChild(canvas);

    ctx.drawImage(img, 0, 0);

    ubahWarnaGambar(canvas, [0, 85, 170, 255]);
}

function ubahWarnaKomponen(warna: number, level: number[], atas: boolean): number {

    for (let i: number = level.length - 2; i >= 0; i--) {

        if (warna > level[i]) {

            if (atas) {

                return level[i + 1];
            }

            else {

                return level[i];

            }

        }

        else if (warna == level[i]) {

            return warna;

        }

    }

    throw Error('warna tidak ada dalam level');

}

function checkBulatAtas(x: number, y: number): boolean {
    let modx: number = x % 2;
    let mody: number = y % 2;

    return modx == mody;
}

function ubahWarnaGambar(canvas: HTMLCanvasElement, level: number[]): void {

    let ctx: CanvasRenderingContext2D;

    let data: ImageData;

    ctx = canvas.getContext('2d');

    for (let i: number = 0; i < canvas.width; i++) {

        for (let j: number = 0; j < canvas.height; j++) {

            data = ctx.getImageData(i, j, 1, 1);

            data.data[0] = ubahWarnaKomponen(data.data[0], level, checkBulatAtas(i, j));

            data.data[1] = ubahWarnaKomponen(data.data[1], level, checkBulatAtas(i, j));

            data.data[2] = ubahWarnaKomponen(data.data[2], level, checkBulatAtas(i, j));

            ctx.putImageData(data, i, j);
        }

    }

}

Bagian awal dari kode diatas berfungsi untuk menggambar sebuah gambar pada kanvas. Manipulasi gambar akan dilakukan pada kanvas.

Fungsi ubahWarnaGambar() adalah fungsi untuk mengubah warna gambar. Fungsi ini menerima parameter berupa kanvas. Gambar yang akan kita ubah warnanya kita gambar dulu ke dalam kanvas. Kemudian kita akan menggunakan perintah kanvas getImageData() untuk mendapatkan informasi warna dari tiap pikselnya. 

getImageData() akan menghasilkan sebuah object. Dari object ini kita bisa mengakses property data yang berisi berisi informasi tentang intensitas warna merah, hijau, biru, dan juga transparansi dari tiap piksel. 

Selanjutnya kita akan mengubah intensitas dari warna merah, biru dan hijau ini dengan memanggil fungsi ubahWarnaKomponen(). Tiap komponen warna akan dicheck intensitasnya dan dibulatkan ke intensitas yang baru. Pembulatan bisa bersifat ke atas ataupun ke bawah, sesuai dengan nilai yang dibelikan oleh parameter  atas.

Parameter atas didapatkan dari Fungsi checkBulatAtas(). Fungsi ini mengecek apakah kita akan melakukan pembulatan ke atas atau ke bawah. Pembulatan ke atas kita lakukan bila posisi x dan y keduanya sama-sama ganjil atau sama-sama genap. Posisi ini adalah posisi yang letaknya selang-seling seperti posisi kotak pada papan catur.

Hasilnya bisa dilihat pada gambar di atas. Kita bisa meningkatkan kualitas gambar dengan memainkan angka-angka pada intensitas sesuai dengan gambarnya. 

Saat ini nilai intensitas yang baru berlaku pada semua komponen warna, kita bisa menerapkan nilai intensitas yang berbeda untuk setiap komponen warna, dan hasilnya mungkin bisa lebih baik lagi.

Kita akan bahas itu di tulisan selanjutnya. Terima kasih sudah membaca tulisan ini. Bila ada pertanyaan, silahkan langsung tulis di komentar. 
 

Kredit:




    















Jumat, 04 Februari 2022

Blijs: JavaScript Library untuk kanvas

BLIJS adalah kumpulan library untuk menangani kanvas dan input. 

Syntax dari library ini menggunakan syntax dari BlitzBasic. BlitzBasic adalah sebuah bahasa engigne yang pernah populer di tahun 2000 dan sekarang sudah menjadi open source (tautan).

Saya menyukai BlitzBasic karena kemudahan dalam struktur bahasanya, dan kemampuannya yang sangat bagus saat itu untuk membuat berbagai macam aplikasi berbasis flash sebelum adanya flash. 

Saat ini sudah ada dokumentasi dalam format google.doc dan playground untuk mengetest beberapa demo.