Pārlūkot izejas kodu

когда-нибудь я это доделаю, но это не точно

Varvara Huza 3 gadi atpakaļ
vecāks
revīzija
00aa5deb07
2 mainītis faili ar 419 papildinājumiem un 0 dzēšanām
  1. 57 0
      Homework_19 (canvas)/index.html
  2. 362 0
      Homework_19 (canvas)/index.js

+ 57 - 0
Homework_19 (canvas)/index.html

@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width">
+        <title>геометрия блять</title>
+        <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
+        <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.1.3/papaparse.min.js"></script>
+        <script src="http://gitlab.a-level.com.ua/gitgod/nanobind/raw/master/static/nb.js"></script>
+        <style>
+            * {
+                box-sizing: border-box;   
+                margin: 0;
+                padding: 0;
+            }
+
+            body {
+                margin: 0;
+                padding: 0;
+            }
+
+            button{
+                width: 100%;
+                font-size: 2em;
+            }
+            input, button, select{
+                width: 100%;
+                font-size: 2em;
+            }
+
+            table {
+                border: 1px;
+                border-collapse: collapse;
+            }
+
+            td,th {
+                border: 1px solid black;
+            }
+        </style>
+    </head>
+    <body>
+        <canvas id='canvas' width=1500 height=400></canvas> 
+        <button id='undo'>UNDO</button>
+        <input type='color' id='color'>
+        <select id='tool'>
+            <option value='graffity'>Graffity</option>
+            <option value='circle' selected>Circle</option>
+            <option value='ellipse' >Ellipse</option>
+            <option value='line'>Line</option>
+            <option value='rect'>Rectangle</option>
+            <option value='select'>Select</option>
+        </select>
+        <input type='number' id='size' value=10>
+        <button id='delete'>Delete...</button>
+        <script src="index.js"></script>
+    </body>
+</html>

+ 362 - 0
Homework_19 (canvas)/index.js

@@ -0,0 +1,362 @@
+const canvas = document.getElementById('canvas')
+const ctx    = canvas.getContext('2d')
+
+const width  = canvas.width;
+const height = canvas.height;
+
+let current
+let selection = []
+let xxx
+let yyy
+let selectWidth
+let selectHeight
+let cyka
+let blyat
+
+const tools = {
+    graffity: {
+        mousemove(e){ //e.buttons 0b00000x11 & 0b00000100 == x
+            (e.buttons & 1) && new Circle(e.clientX, e.clientY, +size.value, color.value)
+        }
+    },
+    circle: {
+        mousedown(e){
+            current = new Circle(e.clientX,e.clientY, 1, color.value)
+        },
+        mousemove(e){
+            if (!current) return;
+
+            current.radius = current.distanceTo(e.clientX, e.clientY)
+            Drawable.drawAll()
+        },
+
+        mouseup(e){
+            current = null
+        }
+    },
+    ellipse: {
+        mousedown(e) {
+            current = new Ellipse(e.clientX, e.clientY, 5, 5, Math.PI / 2, 0, 2 * Math.PI, color.value);
+        },
+        mousemove(e) {
+            if (!current) return;
+
+            current.radiusX = Math.abs(e.clientY - current.y)
+            current.radiusY = Math.abs(e.clientX - current.x)
+
+            Drawable.drawAll();
+        },
+
+        mouseup(e) {
+            current = null;
+        },
+    },
+    line: {
+        mousedown(e){
+            current = new Line(e.clientX, e.clientY, 0, 0, color.value, +size.value)
+        },
+        mousemove(e){
+            if (!current) return;
+
+            current.width = e.clientX - current.x
+            current.height = e.clientY - current.y
+
+            Drawable.drawAll()
+        },
+
+        mouseup(e){
+            current = null
+        }
+    },
+    rect: {
+        mousedown(e) {
+            current = new Rectangle(e.clientX, e.clientY, 0, 0, color.value);
+        },
+        mousemove(e) {
+            if (!current) return;
+
+            current.width = e.clientX - current.x;
+            current.height = e.clientY - current.y;
+
+            Drawable.drawAll();
+        },
+
+        mouseup(e) {
+            if (current.width < 0) {
+                current.x = current.x + current.width 
+                current.width = Math.abs(current.width)
+            }
+            if (current.height < 0) {
+                current.y = current.y + current.height
+                current.height = Math.abs(current.height)
+            }
+            current = null;
+        },
+    },
+    select: {
+		click(e) {
+			if (!blyat) {
+				let found = Drawable.instances.filter(c => c.in && c.in(e.clientX, e.clientY))
+				if (found.length) {
+					if (e.ctrlKey) {
+						selection.push(found.pop())
+					}
+					else {
+						selection = [found.pop()]
+					}
+				}
+				else {
+					if (!e.ctrlKey) selection = []
+				}
+
+				Drawable.drawAll(selection)
+			}
+			cyka = false
+            blyat = false
+		},
+		mousedown(e) {
+			xxx = e.clientX,
+	        yyy = e.clientY
+			cyka = true
+            current = new RectangleForSelect(xxx, yyy, selectWidth, selectHeight)
+		},
+		mousemove(e) {
+			if (cyka && current) {
+				blyat = true
+
+                current.width = e.clientX - current.x;
+                current.height = e.clientY - current.y;
+
+                selectWidth = current.width
+                selectHeight = current.height
+                
+                Drawable.drawAll(selection)
+			}
+		},
+
+		mouseup(e) {
+            if (current.width < 0) {
+                xxx += current.width
+                selectWidth = Math.abs(current.width)
+            }
+            if (current.height < 0) {
+                yyy += current.height
+                selectHeight = Math.abs(current.height)
+            }
+            Drawable.instances.pop()
+            current = null
+
+			let found = Drawable.instances.filter(c => c.inBounds && c.inBounds(xxx, yyy, selectWidth, selectHeight))
+			if (found.length) {
+				selection.push(...found)
+			} else {
+				selection = [...selection]
+			}
+			Drawable.drawAll(selection)
+		},
+    }
+}
+
+function superHandler(evt){
+    let t = tools[tool.value]
+    if (typeof t[evt.type] === 'function')
+        t[evt.type].call(this, evt)
+}
+
+canvas.onmousemove = superHandler
+canvas.onmouseup   = superHandler
+canvas.onmousedown = superHandler
+canvas.onclick = superHandler
+
+function Drawable(){
+   Drawable.addInstance(this);   
+}
+
+const distance = (x1,y1, x2, y2) => ((x1-x2)**2 + (y1-y2)**2)**0.5
+
+Drawable.prototype.draw = function(){};
+Drawable.prototype.distanceTo = function(x,y){
+    if (typeof this.x !== 'number' ||
+        typeof this.y !== 'number'){
+        return NaN
+    }
+    return distance(this.x, this.y, x, y)
+};
+Drawable.instances = [];
+Drawable.addInstance = function(item){
+    Drawable.instances.push(item);
+}
+
+Drawable.drawAll = function(selection=[]){
+    ctx.clearRect(0,0,width,height);
+    Drawable.forAll(item => item.draw())
+    selection.forEach(item  => item.draw(true))
+}
+
+Drawable.forAll = function(callback){
+    for(var i = 0; i<Drawable.instances.length;i++){
+        callback(Drawable.instances[i])
+    }
+}
+
+class Circle extends Drawable {
+    constructor(x,y,radius, color){
+        super()
+        this.x      = x;
+        this.y      = y;
+        this.radius = radius;
+        this.color  = color;
+
+        this.draw(); 
+    }
+
+    draw(selected){
+        ctx.beginPath();
+        ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
+        ctx.closePath();
+        ctx.fillStyle = this.color;
+        if (selected){
+            ctx.lineWidth = 5
+            ctx.strokeStyle = 'yellow'
+            ctx.stroke();
+        }
+        ctx.fill();
+    }
+
+    in(x,y){
+        return this.distanceTo(x,y) < this.radius
+    }
+
+    inBounds(x,y,w,h){ // x = 100, this.x = 102, w = 5
+        return this.x >= x && this.x <= x + w &&
+               this.y >= y && this.y <= y + h 
+    }
+}
+
+class Line extends Drawable {
+    constructor(x, y, width, height, color, lineWidth){
+        super()
+        this.x      = x;
+        this.y      = y;
+        this.width  = width;
+        this.height = height;
+        this.color  = color;
+        this.lineWidth  = lineWidth;
+
+
+        this.draw(); 
+    }
+    
+    draw(){
+        ctx.beginPath();
+        ctx.moveTo(this.x, this.y);
+        ctx.lineTo(this.x + this.width, this.y + this.height);
+        ctx.closePath();
+        ctx.strokeStyle = this.color;
+        ctx.lineWidth   = this.lineWidth
+        ctx.stroke();
+    }
+    
+}
+
+class Rectangle extends Drawable {
+    constructor(x, y, width, height, color) {
+        super()
+        this.x      = x;
+        this.y      = y;
+        this.width  = width;
+        this.height = height;
+        this.color  = color;;
+    }
+
+    draw(selected) {
+        ctx.beginPath();
+        ctx.rect(this.x, this.y, this.width, this.height);
+        ctx.closePath();
+        ctx.fillStyle = this.color;
+        if (selected) {
+            ctx.lineWidth = 5
+            ctx.strokeStyle = 'yellow'
+            ctx.stroke();
+        }
+        ctx.fill(); 
+    }
+
+    in(x,y){
+        return x > this.x && y > this.y && x < this.x + this.width && y < this.y + this.height
+    }
+
+    inBounds(x,y,w,h){ // x = 100, this.x = 102, w = 5
+        return this.x >= x && this.x + this.width <= x + w &&
+               this.y >= y && this.y + this.height <= y + h 
+    }
+}
+
+class RectangleForSelect extends Rectangle {
+    constructor(x, y, width, height) {
+        super(x, y, width, height)
+    }
+
+    draw() {
+        ctx.beginPath();
+        ctx.rect(this.x, this.y, this.width, this.height);
+        ctx.closePath();
+        ctx.strokeStyle = 'black'
+        ctx.lineWidth = '2'
+        ctx.stroke(); 
+    }
+}
+
+class Ellipse extends Drawable {
+    constructor(x, y, radiusX, radiusY, rotation, startAngle, endAngle, color){
+        super()
+        this.x      = x;
+        this.y      = y;
+        this.radiusX = radiusX
+        this.radiusY = radiusY
+        this.rotation = rotation;
+        this.startAngle = startAngle
+        this.endAngle = endAngle
+        this.color  = color;
+
+        this.draw(); 
+    }
+
+    draw(selected){
+        ctx.beginPath();
+        ctx.ellipse(this.x, this.y, this.radiusX, this.radiusY, this.rotation, this.startAngle, this.endAngle);
+        ctx.closePath();
+        ctx.fillStyle = this.color;
+        if (selected){
+            ctx.lineWidth = 5
+            ctx.strokeStyle = 'yellow'
+            ctx.stroke();
+        }
+        ctx.fill();
+    }
+
+    in(x,y){
+        return (Math.abs(y - this.y) < this.radiusX && Math.abs(x - this.x) < this.radiusY)
+    }
+
+    inBounds(x,y,w,h){ // x = 100, this.x = 102, w = 5
+        return this.x >= x && this.x <= x + w &&
+               this.y >= y && this.y <= y + h 
+    }
+}
+
+color.onchange = () => {
+    selection.forEach(c => c.color = color.value)
+    Drawable.drawAll(selection)
+}
+
+document.getElementById('delete').onclick = () =>{
+    Drawable.instances = Drawable.instances.filter(item => !selection.includes(item))
+    selection = []
+    Drawable.drawAll()
+}
+
+undo.onclick = function(){
+    Drawable.instances.pop()
+    Drawable.drawAll()
+}