diff --git a/Readme.txt b/Readme.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b99291f5a5049743d5607f4605faba088d3887cd
--- /dev/null
+++ b/Readme.txt
@@ -0,0 +1,3 @@
+Hernowo Ari Sutanto - 1906400274	= Pembuatan HTML, .JS, dengan fitur triangle, rectangle, Polygon
+Andrew Nehemia Hutapea - 1906400311	= Editor HTML, .JS, membantu dalam pembuatan rectangle, triangle
+Muhammad Farhan Ramadhan - 1906306155	= Editor HTML, .JS, fitur Line, clear canvas, membantu dalam pembuatan rectangle, triangle
\ No newline at end of file
diff --git a/worksheet1.html b/worksheet1.html
index 69e999132831ad318b3618600fdabc5100f24060..1f15951280247465a6bd6d3c98750e2e26d7677e 100644
--- a/worksheet1.html
+++ b/worksheet1.html
@@ -45,6 +45,8 @@
                         <button class="button-shape" id ="rectangle" type="button">Rectangle</button>
                     </div>
                     <button id ="end-polygon">End Polygon</button>
+                    <button id ="clear">Clear</button>
+                    <button id ="rotate">Rotate</button>
                 </div>
             </div>
             
@@ -56,16 +58,23 @@
 </body>
 <script id="vertex-shader" type="x-shader/x-vertex">
     #version 300 es
+
     in vec4 aPosition;
     in vec4 aColor;
-    
+    uniform float uTheta;
     out vec4 vColor;
     
     
     void
     main()
     {
-        gl_Position = aPosition;
+        float s = sin(uTheta);
+        float c = cos(uTheta);
+
+        gl_Position.x = -s*aPosition.y + c*aPosition.x;
+        gl_Position.y =  s*aPosition.x + c*aPosition.y;
+        gl_Position.z = 0.0;
+        gl_Position.w = 1.0;
         vColor = aColor;
     }
 </script>
diff --git a/worksheet1.js b/worksheet1.js
index 31997194239fb659c554f4a289dccdab274cba0e..c91b6788aae15cbde1bb45d161591e123ef6afc7 100644
--- a/worksheet1.js
+++ b/worksheet1.js
@@ -17,6 +17,10 @@ var ObjShape = "";
 var drawArraysConfig = {};
 var SHAPES = []; // list dari gambar yang dibuat
 var speed = 100;
+var spin = false;
+var glob_theta = 0.0;
+var thetaLoc;
+var speed = 10;
 
 init();
 
@@ -49,7 +53,10 @@ function init() {
     var colorLoc = gl.getAttribLocation(program, "aColor");
     gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
     gl.enableVertexAttribArray(colorLoc);
+    
+    thetaLoc = gl.getUniformLocation(program, "uTheta");
 
+    // variabel untuk warna dengan input sesuai user
     const red = document.getElementById("red");
     const green = document.getElementById("green");
     const blue = document.getElementById("blue");
@@ -71,6 +78,10 @@ function init() {
     document.getElementById('triangle').addEventListener('click', function() {
         ObjShape = 'triangle';
     });
+    document.getElementById('line').addEventListener('click', function() {
+        ObjShape = 'line';
+    });
+    
 
 
     var a = document.getElementById("end-polygon")
@@ -92,9 +103,28 @@ function init() {
         }
     });
     
+    // button untuk menghapus gambar
+    var clearButton = document.getElementById("clear")
+    clearButton.addEventListener("click", function() {
+        index = 0;
+        SHAPES = [];
+    })
 
+    // button untuk animasi rotasi
+    var animateButton = document.getElementById("rotate")
+    animateButton.addEventListener("click", function() {
+        if (!spin) {
+            spin = true
+        } else {
+            spin = false;
+            glob_theta = 0.0;
+            gl.uniform1f(thetaLoc, glob_theta)
+        }
+    })
 
     canvas.addEventListener("mousedown", function(event){
+
+        //Bentuk Polygon
         if(ObjShape == "polygon"){
             t = getCanvasCoordinate(event, canvas);
             gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
@@ -108,6 +138,8 @@ function init() {
             numPositions[numPolygons]++
             index++
         }
+
+        //Bentuk persegi/rectangle
         else if(ObjShape == "rectangle"){
             drawArraysConfig = {
                 "nama": ObjShape,
@@ -138,6 +170,8 @@ function init() {
                 SHAPES.push(drawArraysConfig);
             }
         }
+
+        //Bentuk segitiga/triangle
         else if(ObjShape == "triangle") {
             drawArraysConfig = {
                 "nama": ObjShape,
@@ -172,18 +206,52 @@ function init() {
                 }
             }
         }
+
+        //bentuk garis/line
+        else if(ObjShape == "line") {
+            drawArraysConfig = {
+                "nama": ObjShape,
+                "mode": gl.LINES,
+                "index": index,
+                "step": 2
+            }
+            console.log(ObjShape)
+            gl.bindBuffer( gl.ARRAY_BUFFER, bufferId);
+            if(first) {  
+                first = false;
+                t[0] = getCanvasCoordinate(event, canvas)
+            }
+    
+            else {
+                first = true
+                t[1] = getCanvasCoordinate(event, canvas)
+                
+                for(var i=0; i<2; i++) gl.bufferSubData(gl.ARRAY_BUFFER, 8*(index+i), flatten(t[i]));
+                index += 2;
+    
+                gl.bindBuffer(gl.ARRAY_BUFFER, cBufferId);
+                var tt = vec4(red.value/255.0 ,green.value/255.0 , blue.value/255.0 , 1.0);
+                for(var i=0; i<2; i++) gl.bufferSubData(gl.ARRAY_BUFFER, 16*(index-2+i), flatten(tt))
+    
+                // reset vertices & add line to SHAPES
+                t = [];
+                SHAPES.push(drawArraysConfig)
+            }
+        }
     });
     if(ObjShape != "polygon") {
         render();
     }   
 }
 
+// fungsi render gambar
 function render() {
     gl.clear( gl.COLOR_BUFFER_BIT );
 
-    // for(var i=0; i<numPolygons; i++) {
-    //     gl.drawArrays( gl.TRIANGLE_FAN, start[i], numPositions[i] );
-    // }
+    if(spin) {
+        glob_theta += 0.1;
+        gl.uniform1f(thetaLoc, glob_theta)
+    }
     for(var i = 0; i<SHAPES.length; i++){
         var obj = SHAPES[i];
         gl.drawArrays( obj["mode"], obj["index"], obj["step"] );