Evet gençler bu atölye çalışmasında sizlerle daha önce yapmış olduğumuz lineer-doğrusal çizim uygulamasını bir adım daha öte götürerek, serbest el ile çizim, çember çizimi, çizim renginin kullanıcı tarafından seçilmesi ve hatta çizgi kalınlığının da kullanıcının kontrolüne verilmesini sağlayan bir uygulama haline getireceğiz. Elbette bu uygulamada da yine < div /> nesnelerinden faydalanacağız. Aslında bu uygulama ile şunu da kavramış olmanız gerekiyor < div /> nesnesini legolara benzetebilirsiniz hayal gücünüzü kullanarak tarayıcıya daha onlarca değişik iş yaptırabilirsiniz bu tamamen size kalmış. Bu uygulamamızda diğerinden farklı olarak çember çizeceğimizden bahsettim ki öncesinde hepimizin temelde şekil olarak bildiği çember nedir? Çember belirli bir noktadan eşit uzaklıktaki noktalar kümesidir dersek bu tanıma göre çemberin merkezini başlangıç noktası alırsak yarıçap olarak tanımladığımız uzunluk kadar mesafedeki tüm noktaların kümesi çemberimizi oluşturacaktır. Çemberi de aynen doğrusal çizim uygulmasında olduğu gibi noktaları (div'leri) kullanarak oluşturacağız. Bu durumda şayet merkeze göre bir noktanın konumunu belirleyebilirsek diğer noktaları hesaplarken merkeze göre dönme açısını değiştirerek hesaplayabiliriz. Şimdi bu kadar kolay bir olay için bu kadar çok satır yazdığım için üzgünüm ama yazılmak zorunda...Çember çiziminde hesaplama yaparken sol üst köşede verdiğim şekildeki hesaplamaları kullandım. Bu arada tüm trigonometrik hesaplar radyan türünden açısal hesaplamalara dayanır bu nedenle hesaplamalarınızda doğrudan derece türünden değerler kullanamazsınız. Uygulamayı tamamladığınızda aşağıda verdiğim gibi bir ekran görüntüsü elde edeceksiniz.

Burada renk düğmelerinden çizgi kalınlığını belirlediğiniz kaydırma çubuğuna, işlem seçim düğmelerinden, yaptığınız işlemlerler hakkında bilgi verilen durum çubuğuna hatta çizim yaptınız alana kadar sadece ve sadece < div /> kullandım ki aslında bu çok ilkel bir çözüm ama olsun sizlerin sadece < div / > ile neler başarabileceğinizi göstermek adına güzel bir uygulama oldu.  Kısaca bunu da hatırlattıktan sonra şimdi sizlere çalışamamızın HTML kodlarını vereyim.

< body onload="temizle()" >
< div id="kontroller" onmouseup="surukleBirak(false)" style="width:100%;height:10%; border:2px solid #333; background-color:#eee; padding:2px 2px" >
< div id="ustPanel" >
< div id="btnColorRed" class="colorButtons" onclick="setPenColor('Red')" onmouseOver="butonlariCanlandir('btnColorRed',1)" onmouseOut="butonlariCanlandir('btnColorRed',0)" style="background-color:red" >< / div >
< div id="btnColorGold" class="colorButtons" onclick="setPenColor('Gold')" onmouseOver="butonlariCanlandir('btnColorGold',1)" onmouseOut="butonlariCanlandir('btnColorGold',0)" style="background-color:gold" >< / div >
< div id="btnColorBlack" class="colorButtons" onclick="setPenColor('Black')" onmouseOver="butonlariCanlandir('btnColorBlack',1)" onmouseOut="butonlariCanlandir('btnColorBlack',0)" style="background-color:black" >< / div >
< div id="btnColorBlue" class="colorButtons" onclick="setPenColor('Blue')" onmouseOver="butonlariCanlandir('btnColorBlue',1)" onmouseOut="butonlariCanlandir('btnColorBlue',0)" style="background-color:blue" >< / div >
< div id="btnColorGreen" class="colorButtons" onclick="setPenColor('Green')" onmouseOver="butonlariCanlandir('btnColorGreen',1)" onmouseOut="butonlariCanlandir('btnColorGreen',0)" style="background-color:green" >< / div >
< div id="btnTemizle" class="dugme" onclick="temizle()" onmouseOver="butonlariCanlandir('btnTemizle',1)" onmouseOut="butonlariCanlandir('btnTemizle',0)" >Temizle< / div >
 
< div id="cubuk"  onmousemove="surukle()" onmouseup="surukleBirak(false)" >
	< div id="cizgi" >< / div >
	< div id="btn1" onmousedown="surukleBirak(true)" onmouseup="surukleBirak(false)" >< / div >
< / div >

< div id="btnCizgi" class="dugme" onclick="islemSec(1)" onmouseOver="butonlariCanlandir('btnCizgi',1)" onmouseOut="butonlariCanlandir('btnCizgi',0)" >Düz çizgi< / div >
< div id="btnDaire" class="dugme" onclick="islemSec(3)" onmouseOver="butonlariCanlandir('btnDaire',1)" onmouseOut="butonlariCanlandir('btnDaire',0)" >Çember çiz< / div >
< div id="btnSerbest" class="dugmeEtkin" onclick="islemSec(0)" onmouseOver="butonlariCanlandir('btnSerbest',1)" onmouseOut="butonlariCanlandir('btnSerbest',0)" >Serbest< / div >
< div id="btnXY" class="dugmeEtkin" onclick="islemSec(2)" onmouseOver="butonlariCanlandir('btnXY',1)" onmouseOut="butonlariCanlandir('btnXY',0)" >[X:Y]Aktif< / div >
< / div >
< div id="durumCubugu" >< / div >
< / div >
< div style="width:100%; height:88%; border:2px solid crimson; border-top:none; " id="govde" onMouseDown="durumDegistir(true)" onmouseup="durumDegistir(false)" >
< div id="eksenX" >< / div >
< div id="eksenY" >< / div >
< div id="gosterge" >< / div >
< / div >
< / body >

Şimdi ise gelelim çalışmamızın etkin bir biçimde işleyebilmesi için gerekli JavaScript kodlarına, bu kodların önemli bir bölümü doğrusal çizim uygulamasında yazdığım kodlardan oluşuyor elbette yeni işlemler için de kod yazdım ama temelde fikir doğrusal çizim uygulamasını geliştirmek idi. Tüm kodların dökümü aşağıdaki gibidir kodlardan önce yeteri kadar açıklama yaptığıma inanıyorum bu nedenle burada fazladan birkaç tuşa basmaya gerek duymuyorum.Bu uygulamayı yeterince inceledikten sonra kendisini geliştirmek isteyen arkadşlar, sizlere ise bir soru sormak istiyorum:

  1. Öncelikle web sayfanızı istediğiniz ölçülerde  (yükseklik ve genişlikte) ızgaralar ile dilimleyin (< div  /> ile)
  2. Sonra kullanıcın bu ızgaraların kesim noktaları üzerinde dört defa tıklama yapmasına izin verin ve her tıklamayı farklı renklerle işaretleyin ( tabi ki < div / > ile)
  3. Son olarak kullanıcıya bu noktalar arasındaki en kısa seyahat olasılığını renklendirerek gösterin (elbette < div /> ile ve elbette tüm noktalara uğramak şartı ile
  4. Seyahat ızgara çizgileri üzerinden yapılacaktır.

Sayfada yazdığım tüm javascript kodların dökümü aşağıdaki gibidir.

<script language="javascript">
var ciziliyorMu=false, surukleniyorMu=false;
var cizgiKalinligi=5;
var kalemRengi="Black";
//baslangicta serbest cizim etkin
var islemID=0, xyPanel=true;
var bitX=0,bitY=0,basX=0,basY=0;
//tarayici penceresindeki fare hareketlerini dinliyoruz
window.addEventListener("mousemove",nesneEkle);

function durumDegistir(islem){
////////////////////////////////////////////////////////////////
// Kodlama			: Bilal SERT
// Tarih-Saat		: .../..../2019 | 11:47
// Amaç				: sol tusun durumunu belirlemek kullanici
//					  tusa basiyor mu? Basmiyor mu?
// G/Ç				: yok
// Çağrıldığı yer	: body.onmousedown()
////////////////////////////////////////////////////////////////			
ciziliyorMu=islem;
if(islem==true){
basX=window.event.clientX;
basY=window.event.clientY;
}else{
bitX=window.event.clientX;
bitY=window.event.clientY;
durumCubugu.innerHTML="[" + basX + ":" + basY + "] ile [" + bitX + ":" + bitY + "] arasinda cizim yapilacak";			
//duz cizgi dugmesine basilmis ise
if(islemID==1)cizgiCiz();
if(islemID==3){
  daireCiz();
  bitY=basY+2;
  bitX=basX+2;
  daireCiz();
}
}
if(ciziliyorMu==true)govde.style.cursor="pointer";else govde.style.cursor="default";
}//end of durumDegistir

function surukleBirak(islem){
////////////////////////////////////////////////////////////////
// Kodlama			: Bilal SERT
// Tarih-Saat		: .../..../2019 | 21:06
// Amaç				: kullanicinin dugmeyi suruklemesine izin
//					  vermek
// G/Ç				: yok
// Çağrıldığı yer	: btn1.onmousedown ve btn1.onmouseup
////////////////////////////////////////////////////////////////			
surukleniyorMu=islem;
if(surukleniyorMu==true)btn1.style.cursor="pointer";else btn1.style.cursor="default";

}//end of surukleBirak	

function surukle(){
////////////////////////////////////////////////////////////////
// Kodlama			: Bilal SERT
// Tarih-Saat		: .../..../2019 | 21:06
// Amaç				: kullanicinin dugmeyi suruklemesini saglamak
//					  
// G/Ç				: yok
// Çağrıldığı yer	: cubuk.onmousemove()
////////////////////////////////////////////////////////////////			
if(surukleniyorMu==true){
if(window.event.clientX > 315 && window.event.clientX < 440){
	btn1.style.left=window.event.clientX;
	cizgiKalinligi=Math.floor((window.event.clientX - 315)/10 + 2);
	durumCubugu.innerHTML="cizgi kalınlığı " + cizgiKalinligi + " piksel olarak ayarlandi";	
}
}
}//end of surukle	

function daireCiz(){
////////////////////////////////////////////////////////////////////////
// Kodlama			: Bilal SERT
// Tarih-Saat		: .../..../2019| 16:00
// Amaç				: Farenin sol tusunun ilk basildigi nokta (merkez)
// ile sol tusun birakildigi iki nokta arasinda (yaricap) cember cizmek
// G/Ç				: yok
// Çağrıldığı yer	: govde.onmouseup()
////////////////////////////////////////////////////////////////////////				
var lenX=Math.abs(bitX-basX);
var lenY=Math.abs(bitY-basY);
//aciyi her zaman pozitif aliyoruz
var radAci=0;
var yCap=Math.floor(Math.sqrt((lenX*lenX)+(lenY*lenY)));
var sayac=0;
var kod="";
kod="";
for(sayac=0;sayac<360;sayac++){
let sol=basX+(yCap*Math.cos(sayac*Math.PI/180));
let ust=basY+(yCap* Math.sin(sayac*Math.PI/180));
if(ust>=80 && ust <=screen.height-130){
if(sol>=10 && sol <=screen.width-20){
kod + = "< div";
kod + = " style='width:" + cizgiKalinligi;
kod + = "px; height:" + cizgiKalinligi;
kod + = "px; background-color:" + kalemRengi;
kod + = "; position:absolute; left:" + sol; 
kod + = "; top:" + ust + "'>< \/ div >";	
}
}		
}//for
document.getElementById("govde").innerHTML + = kod;				
}//end of daireCiz		

function cizgiCiz(){
////////////////////////////////////////////////////////////////
// Kodlama			: Bilal SERT
// Tarih-Saat		: .../..../2019| 15:53
// Amaç				: Farenin sol tusunun ilk basildigi nokta ile
// sol tusun birakildigi iki nokta arasinda duz bir cizgi cizmek
// G/Ç				: yok
// Çağrıldığı yer	: govde.onmouseup()
////////////////////////////////////////////////////////////////
var lenX=Math.abs(bitX-basX);
var lenY=Math.abs(bitY-basY);
var sayac=0;
var code="";
//aciyi her zaman pozitif aliyoruz
var radAci=Math.abs(Math.atan((bitY-basY)/(bitX-basX)));
var uzunluk=Math.floor(Math.sqrt((lenX*lenX)+(lenY*lenY)));

for(sayac=0;sayac<uzunluk;sayac + = cizgiKalinligi){
code + = "< div";
if(bitX>basX){
	code + = " style='position:absolute; left:" + (basX+(sayac*Math.cos(radAci))); 
}else{
	code + = " style='position:absolute; left:" + (basX-(sayac*Math.cos(radAci))); 
}
code + = "; background-color:" + kalemRengi ;
code + = "; width:" + cizgiKalinligi ;
code + = "; height:" + cizgiKalinligi ;
if(bitY>basY){
	code + = "; top:" + (basY+(sayac* Math.sin(radAci))) + "'>< \/ div >";
}else{
	code + = "; top:" + (basY-(sayac* Math.sin(radAci))) + "'>< \/ div >";
}			

}//for
document.getElementById("govde").innerHTML + = code;
}//end of cizgiCiz

function nesneEkle(){
////////////////////////////////////////////////////////////////
// Kodlama			: Bilal SERT
// Tarih-Saat		: .../..../2019| 12:36
// Amaç				: Rasgele bicimlendirilmis < div> eklemek
// G/Ç				: yok
// Çağrıldığı yer	: body.onmousemove()
////////////////////////////////////////////////////////////////
var sol=window.event.clientX;
var yukari=window.event.clientY;
var gen=cizgiKalinligi;//Math.floor(Math.random()*100+30);
var yuk=cizgiKalinligi;//Math.floor(Math.random()*100+30);
var kod;

if(ciziliyorMu && islemID==0){
kod="";
//sayet sol tus basili tutularak surukleme yapiliyorsa nesneleri ekle
kod + = "< div style= \ "position:absolute;left:" + sol + ";";
kod + = "top:" + yukari + ";";
kod + = "width:" + gen + ";";
kod + = "height:" + yuk + ";";
//sabit bir renk icin
kod + = "background-color:" + kalemRengi + "; \ ">"
kod + = "< / div>";		
govde.innerHTML + = kod;
}//if

//eksenleri hareket ettirirken kontrol panel sinirlarini ihlal etmnesine izin vermiyoruz
eksenY.style.left=window.event.clientX;
if(window.event.clientY>100 && window.event.clientY<900)eksenX.style.top=window.event.clientY;
//gostergeyi hareket ettirirken kontrol panel sinirlarini ihlal etmnesine izin vermiyoruz
if(window.event.clientY>135 && window.event.clientY<900)gosterge.style.top=window.event.clientY-32;
gosterge.style.left=window.event.clientX-92;
gosterge.innerHTML="x:" + window.event.clientX + " y:" + window.event.clientY;
}//end of nesne ekle

function butonlariCanlandir(nesAdi,id){
////////////////////////////////////////////////////////////////
// Kodlama			: Bilal SERT
// Tarih-Saat		: .../..../2019| 11:59
// Amaç				: div nesnelerini buton gibi hareketlendirmek
// G/Ç				: yok
// Çağrıldığı yer	: tum dugmelerin onmouseover ve onmousedown
//					  olaylarinda
////////////////////////////////////////////////////////////////	
var dugme=eval(nesAdi);
if(id==1){
//efekt ver
dugme.style.boxShadow="3px 3px 5px gray";
dugme.style.borderBottom="1px solid white";
dugme.style.borderRight="1px solid white";
dugme.style.cursor="pointer";
}else{
//normal haline dondur
dugme.style.boxShadow="none";
dugme.style.borderBottom="1px solid #333";
dugme.style.borderRight="1px solid #333";
dugme.style.cursor="default";			
}//if

}//end of butonlariCanlandir
function setPenColor(renkAdi){
////////////////////////////////////////////////////////////////
// Kodlama			: Bilal SERT
// Tarih-Saat		: .../..../2019| 12:07
// Amaç				: cizimde kullanilacak kalem rengini yani
//					  div zemin rengini belirlemek
// G/Ç				: yok
// Çağrıldığı yer	: renk dugmelerinin oclick olaylarinda
////////////////////////////////////////////////////////////////	
kalemRengi=renkAdi;
durumCubugu.innerHTML="Kalem rengi " + kalemRengi + " olarak ayarlandi !";
}//end of setPenColor

function temizle(){
////////////////////////////////////////////////////////////////
// Kodlama			: Bilal SERT
// Tarih-Saat		: .../..../2019| 12:31
// Amaç				: cizimde kullanilan div nesnesinin icerigini
//					  silmek yani resmi temizlemek
// G/Ç				: yok
// Çağrıldığı yer	: btnTemizle.onclick()
////////////////////////////////////////////////////////////////		
govde.innerHTML="< div id= \ "eksenX \ ">< / div>";
govde.innerHTML + = "< div id= \ "eksenY \ ">< / div>";
govde.innerHTML + = "< div id= \ "gosterge \ ">< / div>";
durumCubugu.innerHTML="";
//gosterge etkin hale getiriliyor
islemSec(2);

}//end of temizle
function islemSec(id){
////////////////////////////////////////////////////////////////
// Kodlama			: Bilal SERT
// Tarih-Saat		: 18.11.2019 | 14:44
// Amaç				: islem türüne karar vermek, serbest, düz vb.
// G/Ç				: id integer veri
// Çağrıldığı yer	: btnCizgi.onclick(), btnSerbest.onclick()
////////////////////////////////////////////////////////////////
if(id!=2){
btnSerbest.className="dugme";
btnCizgi.className="dugme";
btnDaire.className="dugme";
}
switch(id){
case 0:
islemID=id;
btnSerbest.className="dugmeEtkin";
break;
case 1:
islemID=id;
btnCizgi.className="dugmeEtkin";
break;
case 2:
if(xyPanel){
btnXY.className="dugme";
xyPanel=false;
gosterge.style.visibility="hidden";
btnXY.innerText="[X:Y]Pasif";
}else{
btnXY.className="dugmeEtkin";
xyPanel=true;
gosterge.style.visibility="visible";
btnXY.innerText="[X:Y]Aktif";
}
break;	
case 3:
islemID=id;
btnDaire.className="dugmeEtkin";
break;
}//switch
//durumCubugu.innerHTML="islemID=" + islemID;
}//end of islemSec
</script>

Görsel olarak aynı sonucu alabilmeniz aşağıda verdiğim css kodlarını da kullanmanız gerekecek. Tüm işlemleri tamamladığınızda buna benzer bir web sayfanız olacaktır. Şimdiden sizlere iyi çalışmalar dilerim.

<style type="text/css">
.colorButtons{
width:30px;
height:30px;
border:1px solid #333;
#box-shadow:3px 3px 5px gray;
float:left;
margin-left:3px;
margin-top:3px;
}
.dugme{
background-color:#d92626;
border:1px solid #333;
color:white;
tex-align:center;
font-family:arial;
font-size:14px;
width:100px;
height:25px;
float:left;
margin-left:3px;
margin-top:3px;
padding-left:10px;
padding-top:5px;	
display:block;
}
.dugmeEtkin{
background-color:#ff0080;
border:1px solid #333;
color:white;
tex-align:center;
font-family:arial;
font-size:14px;
width:100px;
height:25px;
float:left;
margin-left:3px;
margin-top:3px;
padding-left:10px;
padding-top:5px;
display:block;
}
#eksenX{
width:100%;
height:2px;
background-color:#eee;
position:absolute;
left:0px;
top:50%;

}
#eksenY{
width:2px;
height:88%;
background-color:#eee;
position:absolute;
left:50%;
top:12%;

}
#gosterge{
background-color:rgba(240,240,240,0.4);
color:#gray;
width:90px;
height:24px;
position:absolute;
left:50%;
top:50%;
font-family:arial;
font-size:11px;
padding-top:6px;
text-align:center;
z-index:5000;

}		
#cubuk{
background-color:gray;
border:1px solid #333;
color:white;
width:130px;
height:30px;
float:left;
margin-left:3px;
margin-top:3px;
padding-left:10px;
padding-right:10px;

}	
#btn1{
background-color:gold;
border:1px solid #333;
color:white;
width:13px;
height:20px;
position:absolute;
left:329px;
top:17px;
box-shadow:1px 1px 3px yellow;
}	
#cizgi{
background-color:gold;
border:1px solid #333;
color:white;
width:100%;
height:2px;
position:relative;
left:0px;
top:10px;
}			
#ustPanel{
width:100%;
height:60%;
}
#durumCubugu{
width:100%;
height:40%;
background-color:silver;
color:white;
}
style>