Liveteract-JS-Library / pub / js / live_interact.js
live_interact.js
Raw
"use strict";

(function(global, document){

    var actionhold = false

    function drag(e){
        // console.log("ben simdi bunun ise yaradigini nerden bilicem")
        // if()
        // console.log(e.target.tagName)
        e.stopPropagation()

        if(e.target.tagName !== "SELECT" && e.target.tagName !== "A"){
            e.preventDefault()
        }
        const element = e.target
        // console.log(element)
        if(!element){
                // console.log("dokunma sikerim")
                return
            }
        if(element.className.includes('draggable')){// && element.tagName !== "BUTTON" ){
                
            // console.log(e.css)
            // console.log(window.getComputedStyle(element)["transform"])
            const t_matrix = window.getComputedStyle(element)["transform"]
            let X = 0
            let Y = 0
            
            if(t_matrix !== "none"){
                // const regex = /[A-Z]/g;
                const t_matrix_vals = t_matrix.match(/[0-9]+.+[0-9]+/)[0].split(", ")

                // console.log(t_matrix_vals)
                X = parseInt(t_matrix_vals[4], 10)
                Y = parseInt(t_matrix_vals[5], 10)
                // console.log(X + ' ' + Y)
                // console.log(window.getComputedStyle(element)["transform"])
            }
            
            window.onmousemove = mousemove
            window.onmouseup = mouseup
            window.onmouseleave = mouseup
            function mousemove(e){
                actionhold = true
                // console.log("amm")
                // e.clientX += 200
                // e.x += e.movementX
                X += e.movementX
                Y += e.movementY
                // console.log(X + " " + Y)
                // e.movementX
                // initialY += e.movementY
                if(element.className.includes('_snapping')){
                    // console.log(element.className)
                    const snapping = element.className.match(/snapping [0-9]*/)[0]

                    const stepSize = parseInt(snapping.match(/[0-9]*$/)[0], 10)

                    if(stepSize){
                        const quotientY = parseInt(Y/stepSize, 10)
                        const quotientX = parseInt(X/stepSize, 10)
                        element.style.transform = `translate(${quotientX*stepSize}px, ${quotientY*stepSize}px)`    
                    
                    }
                }
                else{

                    element.style.transform = `translate(${X}px, ${Y}px)`
                }
                // element.style.transform = `translate(100%, 100%)`
                // console.log("ise niye yaramiyo la")
            }
            
            function mouseup(e){
                setTimeout(function(){
                    actionhold = false
                }, 5)
                window.onmousemove = null
                window.onmouseup = null
                window.onmouseleave = null        
            }
        }

    }


    function resize(e){
        e.stopPropagation()
        e.preventDefault()

        const element = e.target
        // console.log(element)
        // console.log("dokunma sikerim")
        if(!element){
                // console.log("dokunma sikerim")
                return
            }
        const parent = element.parentNode
        // if(element.className.includes('resizable')){// && element.tagName !== "BUTTON" ){
        if(parent.className.includes('resizable')){// && element.tagName !== "BUTTON" ){
            
            
            let h = parent.clientHeight
            let w = parent.clientWidth
            const t_matrix = window.getComputedStyle(parent)["transform"]
            let X = 0
            let Y = 0
            
            if(t_matrix !== "none"){
                // const regex = /[A-Z]/g;
                const t_matrix_vals = t_matrix.match(/[0-9]+.+[0-9]+/)[0].split(", ")

                // console.log(t_matrix_vals)
                X = parseInt(t_matrix_vals[4], 10)
                Y = parseInt(t_matrix_vals[5], 10)
                // console.log(X + ' ' + Y)
                // console.log(window.getComputedStyle(element)["transform"])
            }

            window.onmousemove = mousemove
            window.onmouseup = mouseup
            window.onmouseleave = mouseup
            function mousemove(e){
                // console.log(element.className)
                if(element.className.match(/\s{1}n$/)){
                    // console.log(1)
                    h -= e.movementY
                    Y += e.movementY
                    parent.style.height = `${h}px`
                    parent.style.transform = `translate(${X}px, ${Y}px)`
                }
                else if(element.className.match(/\s{1}s$/)){
                    // console.log(2)
                    h += e.movementY
                    parent.style.height = `${h}px`
                }
                else if(element.className.match(/\s{1}e$/)){
                    // console.log(3)
                    w += e.movementX
                    parent.style.width = `${w}px`
                }
                else if(element.className.match(/\s{1}w$/)){
                    // console.log(4)
                    w -= e.movementX
                    X += e.movementX
                    parent.style.width = `${w}px`
                    parent.style.transform = `translate(${X}px, ${Y}px)`                
                }
                else if(element.className.match(/\s{1}ne$/)){
                    // console.log(5)
                    h -= e.movementY
                    Y += e.movementY
                    w += e.movementX
                    parent.style.width = `${w}px`
                    parent.style.height = `${h}px`
                    parent.style.transform = `translate(${X}px, ${Y}px)`                
                }
                else if(element.className.match(/\s{1}nw$/)){
                    // console.log(6)
                    h -= e.movementY
                    w -= e.movementX
                    Y += e.movementY
                    X += e.movementX
                    parent.style.width = `${w}px`
                    parent.style.height = `${h}px`
                    parent.style.transform = `translate(${X}px, ${Y}px)`

                }
                else if(element.className.match(/\s{1}se$/)){
                    // console.log(7)
                    h += e.movementY
                    w += e.movementX
                    parent.style.height = `${h}px`
                    parent.style.width = `${w}px`
                }
                else if(element.className.match(/\s{1}sw$/)){
                    // console.log(parent.class)
                    h += e.movementY
                    w -= e.movementX
                    X += e.movementX
                    parent.style.height = `${h}px`
                    parent.style.width = `${w}px`
                    parent.style.transform = `translate(${X}px, ${Y}px)` 
                                
                }

            }
            function mouseup(e){
                // console.log("bruaya gelmiyon mu aq")
                window.onmousemove = null
                window.onmouseup = null
                window.onmouseleave = null
            }
        }

    }

    function align(e){
        e.preventDefault()
        e.stopPropagation()
        const dropDownMenu = e.target.parentNode.querySelector("#_selectMenu")
        const parent = e.target.parentNode.parentNode
        const alignFactor = dropDownMenu.value
        // console.log(parent)
        const selectedElements = document.querySelectorAll("._selected")
        // console.log(selectedElements)
        // console.log(parent.offsetLeft)
        const translateCoords = parent.style.transform.match(/-?[0-9]*px/g)
        // console.log(translateCoords)

        // var sourceX = parent.offsetLeft
        // var sourceY = parent.offsetTop
        var sourceX = parent.offsetLeft
        var sourceY = parent.offsetTop
        var sourceH = parent.offsetHeight
        var sourceW = parent.offsetWidth
        // console.log("initial offsets are " + sourceX + " and " + sourceY)
        if(translateCoords){
            sourceX += parseInt(translateCoords[0],10)
            sourceY += parseInt(translateCoords[1],10)
        }
        for(let i = 0 ; i < selectedElements.length ; i++){
            if(selectedElements[i] === parent){
                continue
            }
            var selected = selectedElements[i]
            // console.log(selected)
            var selectedX = selected.offsetLeft
            var selectedY = selected.offsetTop
            var selectedW = selected.offsetWidth
            var selectedH = selected.offsetHeight
            var oldTranslateX = 0
            var oldTranslateY = 0
            // console.log("selecteds cords are " + selectedX + " and " + selectedY )
            if(selected.style.transform.match(/-?[0-9]*px/g)){
                oldTranslateX = parseInt(selected.style.transform.match(/-?[0-9]*px/g)[0], 10)
                oldTranslateY = parseInt(selected.style.transform.match(/-?[0-9]*px/g)[1], 10)
                selectedX += parseInt(selected.style.transform.match(/-?[0-9]*px/g)[0], 10)
                selectedY += parseInt(selected.style.transform.match(/-?[0-9]*px/g)[1], 10)
            }
            switch(alignFactor){
                case "top":
                    selected.style.transform = `translate(${oldTranslateX}px, ${sourceY - selectedY + oldTranslateY}px)`
                    break
                case "bottom":
                    selected.style.transform = `translate(${oldTranslateX}px, ${sourceH - selectedH + sourceY - selectedY + oldTranslateY}px)`
                    break
                case "left":
                    selected.style.transform = `translate(${sourceX - selectedX + oldTranslateX}px, ${oldTranslateY}px)`
                    break
                case "right":
                    selected.style.transform = `translate(${sourceW - selectedW + sourceX - selectedX + oldTranslateX}px, ${oldTranslateY}px)`
                    break
                case "horizontally":
                    selected.style.transform = `translate(${oldTranslateX}px, ${parseInt(sourceH/2 - selectedH/2 + sourceY - selectedY + oldTranslateY,10)}px)`
                    break
                case "vertically":
                    selected.style.transform = `translate(${parseInt(sourceW/2 - selectedW/2 + sourceX - selectedX + oldTranslateX, 10)}px, ${oldTranslateY}px)`
                    break
            }
        }

    }


    function toggleSnapping(e, snapSize){
        e.stopPropagation()
        e.preventDefault()
        // const snapSize = 25
        // e.target.classList.toggle("green")
        e.target.parentNode.parentNode.classList.toggle(`_snapping`)
        e.target.parentNode.parentNode.classList.toggle(`${snapSize}`)
        if(e.target.parentNode.parentNode.classList.contains("_snapping")){
            e.target.style.cssText += "background-color: lightgreen;"
        }
        else{
            e.target.style.backgroundColor = ""
        }

    }

    function toggleDraggable(e){
        // console.log("burda miyim amk")
        e.stopPropagation()
        e.preventDefault()

        // const but = e.target
        // e.target.classList.toggle("green")
        // e.target.classList.toggle("draggable")
        e.target.parentNode.parentNode.classList.toggle("_draggable")
        const selectedObject = e.target.parentNode.parentNode
        const dragStyles = 'position: absolute; cursor: move;'
        // console.log(selectedObject.style.cssText)
        if(selectedObject.classList.contains("_draggable")){
            e.target.style.cssText += "background-color: lightgreen;"
            // console.log("demek ki varmis")
            // console.log(selectedObject.style.cssText.indexOf(dragStyles))
            selectedObject.style.cssText += dragStyles
        }
        else{
            e.target.style.backgroundColor = ""
            selectedObject.style.cssText = selectedObject.style.cssText.replace(dragStyles, '')
            // console.log("demek ki yokmis")
        }
        
        //toggle draggable class properties here
    }
    function toggleResizable(e){
        e.stopPropagation()
        e.preventDefault()

        // const but = e.target
        // e.target.classList.toggle("green")
        // e.target.classList.toggle("draggable")
        const selectedObject = e.target.parentNode.parentNode
        selectedObject.classList.toggle("resizable")
        const borders = selectedObject.querySelectorAll(".border")
        // console.log(borders)
        if(selectedObject.classList.contains("resizable")){
            e.target.style.cssText += "background-color: lightgreen;"
            
            for(let i = 0 ; i < borders.length ; i++){
                // console.log(borders[i])
                // borders[i].style.cssText+="visibility: visible"
                borders[i].style.cssText+="display: inline-block"
            }
        }
        else{
            e.target.style.backgroundColor = ""
            for(let i = 0 ; i < borders.length ; i++){
                borders[i].style.cssText+="display: none"
                // borders[i].style.cssText+="visibility: hidden"
            }
        }
    }


    function remove(e){
        e.stopPropagation()
        e.preventDefault()
        
        const bttn = e.target
        const selectedObject = bttn.parentNode.parentNode
        selectedObject.parentNode.removeChild(selectedObject)
        // if(selectedObject.className.includes('draggable')){
        // }
    }

    function togglePopup(e){
        if(!actionhold){
            e.stopPropagation()
            if(e.target.tagName !== "A"){
                e.preventDefault()
            }

            const element = e.target
            const popupMenu = element.querySelector('.popup')
            if(popupMenu){
                // popupMenu.classList.toggle("visible")
                if(popupMenu.style.display === "block"){
                    popupMenu.style.display = "none"
                }
                else{
                    // console.log(document.querySelector(".chosen"))
                    popupMenu.style.display = "block"
                }
                // element.classList.toggle("selected")
                if(document.querySelector(".chosen")){
                    document.querySelector(".chosen").style.zIndex = 0
                    document.querySelector(".chosen").classList.remove("chosen")
                }
                element.classList.toggle("chosen")
                // console.log(element.style)
                element.style.zIndex = 100
            }
        }
    }


    function toggleSelect(e){
        e.stopPropagation()
        e.preventDefault()
        const selectedObject = e.target.parentNode.parentNode
        selectedObject.classList.toggle("_selected")
        
        if(selectedObject.classList.contains("_selected")){
            const actions = ["Align Top", "Align Bottom", "Align Left", "Align Right", "Align Horizontally", "Align Vertically"]
            const dropList = document.createElement("select")
            // dropList.name = "actions"
            // dropList.style.transform = "translate(200px, 0)"

            for(let i = 0 ; i < actions.length ; i++){
                var optionElem = document.createElement("option")
                optionElem.value = actions[i].toLowerCase().match(" [a-z]*")[0].slice(1)
                optionElem.text = actions[i]
                dropList.appendChild(optionElem)
                // console.log(optionElem)
            }


            const activateButton = document.createElement("button")
            activateButton.appendChild(document.createTextNode("align"))
            activateButton.id = "activatorButton"
            activateButton.addEventListener("click", align)
            e.target.parentNode.appendChild(dropList)
            e.target.parentNode.appendChild(activateButton)
            dropList.id = "_selectMenu"
            e.target.innerHTML = "selected"
            e.target.style.cssText += "background-color: lightgreen;"
        }
        else{
            const remDropList = document.getElementById("_selectMenu")
            const activateButton = document.getElementById("activatorButton")
            e.target.parentNode.removeChild(remDropList)
            e.target.parentNode.removeChild(activateButton)
            e.target.innerHTML = "select"
            e.target.style.backgroundColor = ""
        }
        
    }



    class Resizer{
        constructor(elementID){
            this.element = document.getElementById(elementID)

        }
        buildBorders(){
            const children = this.element.childNodes
            // console.log(this.element.childNodes)
            this.element.style.cssText += "display: flex;"
            for(let i = 0 ; i < children.length ; i++){
                if(children[i].style){
                    children[i].style.cssText += "position: absolute;"
                }
            }

            const borders = ['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw']
            for(let border of borders){
                var newElement = document.createElement('div')
                newElement.className = `border ${border}`
                newElement.style.cssText += "background-image:radial-gradient(aqua, #FF00CC);width: 10px;height: 10px;position: absolute;display: none;"
                if(border.match(/^(n|s)$/)){// || border.match(/\s{1}s$/)){
                    newElement.style.cssText += "width: 100%;cursor: ns-resize;"
                }
                else if(border.match(/^(e|w)$/)){// || border.match(/\s{1}w$/)){
                    newElement.style.cssText += "height: 100%;cursor: ew-resize;"
                }
                else if(border.includes("ne") || border.includes("sw")){
                    newElement.style.cssText += "cursor: nesw-resize;"
                }
                else if(border.includes("nw") || border.includes("se")){
                    newElement.style.cssText += "cursor: nwse-resize;"
                }

                if(border.includes("n")){
                    newElement.style.cssText += "bottom: 100%;"
                }
                else if(border.includes("s")){
                    newElement.style.cssText += "top: 100%;"
                }
                if(border.includes("e")){
                    newElement.style.cssText += "left: 100%;"
                }
                else if(border.includes("w")){
                    newElement.style.cssText += "right: 100%;"
                }
                this.element.appendChild(newElement)
                newElement.addEventListener("mousedown", resize)
            }
        }
        removeBorders(){
            const borders = this.element.querySelector(".border")
            for(let border in borders){
                this.element.removeChild(border)
            }
        }
    }



    class PopupMenu{
        constructor(elementID){
            
            this.element = document.getElementById(elementID)
            this.buttons = []
            const newMenu = document.createElement('div')
            newMenu.className = "popup"
            newMenu.style.cssText += "height: auto; position: absolute;display:none;bottom: 100%;z-index: 10;"
            // newMenu.style = "background-color: yellow; width: 30px; height: 30px; position: relative; transform: translate(0, -100%)"
            this.menu = newMenu
            // this.menu = null
        }

        bindPopup(){
            if(this.menu){
                this.element.appendChild(this.menu)
            }
        }
        addButton(button){
            button.style.cssText += "display: inline-block;margin-inline-end: 20px;border: none;cursor: pointer;"
            this.buttons.push(button)
            this.menu.appendChild(button)
            
        }
        addButtons(buttonList){

            
            for(let i = 0 ; i < buttonList.length ; i++){
                let isValButton = 0
                let button = document.createElement("button")
                button.style.cssText += "display: inline-block;margin-inline-end: 20px;border: none;cursor: pointer;"
                if(buttonList[i].match(/drag/)){
                    button.appendChild(document.createTextNode("draggable"))
                    button.addEventListener("click", toggleDraggable)
                    isValButton = 1                
                }
                else if(buttonList[i].match(/resiz/)){
                    // const button = document.createElement("button")
                    button.appendChild(document.createTextNode("resizable"))
                    button.addEventListener("click", toggleResizable)
                    isValButton = 1
                }
                else if(buttonList[i].match(/snap/)){
                    var snapSize = buttonList[i].match(/[0-9]+/)
                    // console.log(snapSize)
                    if(!snapSize){
                        snapSize = 1
                    }
                    // const snap_button = document.createElement("button")
                    button.appendChild(document.createTextNode("snapping"))
                    button.addEventListener("click", (e)=>{toggleSnapping(e, snapSize)})
                    isValButton = 1
                }
                else if(buttonList[i].match(/select/)){
                    // const select_button = document.createElement("button")
                    button.appendChild(document.createTextNode("select"))
                    button.addEventListener("click", toggleSelect)
                    isValButton = 1
                }
                else if(buttonList[i].match(/remove/)){
                    button.appendChild(document.createTextNode("remove"))
                    button.addEventListener("click", remove)
                    isValButton = 1
                }
                if(isValButton === 1){
                    this.buttons.push(button)
                    this.menu.appendChild(button)
                }
            }
            
        }
    }

    var isSaving = false
    // console.log("global value is " + saving)

    if(sessionStorage.getItem("saving") === "true"){
        isSaving = true
        const currElement = document.getElementById(sessionStorage.getItem("elementID"))
        // console.log("buraya geliyo yine de")
        const savedElement = sessionStorage.getItem("obj")
        currElement.innerHTML = savedElement
    }

    function toggleSaver(e, id){
        isSaving = !isSaving
        sessionStorage.setItem("saving", isSaving)
        const obj = document.getElementById(id)
        // console.log(sessionStorage.getItem("saving"))
        var area = obj.innerHTML
        sessionStorage.setItem("elementID", id)
        sessionStorage.setItem("obj", area)
        // console.log(saving)
        // location.reload()
    }


    function Generator(selector){
        this.parent = document.querySelector(selector)
    }

    Generator.prototype = {
        makeCircle: function(){
            const circle = document.createElement('div')
            circle.style = 'width: 100px; height: 100px; border-radius: 50%; margin: 10px; background-color: Aqua;'
            circle.className = 'draggable'
            // const body = document.querySelector('body')
            this.parent.appendChild(circle)
            return circle
        },

        makeRect: function(){
            const rectangle = document.createElement('div')
            rectangle.style = 'width: 100px; height: 60px; margin: 10px; background-color: Red;'
            const body = document.querySelector('body')
            rectangle.className = 'draggable'
            this.parent.appendChild(rectangle)
            return rectangle
        },

        makeCustom: function(tag){
            const shape = document.createElement(tag)
            const body = document.querySelector('body')
            shape.className = "draggable"
            shape.style = "width: 200px; height: 200px; border: 4px dashed black;" //default styles to make it visible on the view
            this.parent.appendChild(shape)
            return shape
        },

    }

    function ActionList(elementID){
        this.block = document.getElementById(elementID)
        
    }

    ActionList.prototype = {

        addButton: function(text, classname){

            const new_button = document.createElement("button")
            new_button.className = classname
            new_button.appendChild(document.createTextNode(text))
            this.block.appendChild(new_button)
            return new_button
        },

        remButton: function(button){
            this.block.removeChild(button)

        }

    }

    global.Generator = global.Generator || Generator
    global.ActionList = global.ActionList || ActionList
    global.PopupMenu = global.PopupMenu || PopupMenu
    global.Resizer = global.Resizer || Resizer
    global.togglePopup = global.togglePopup || togglePopup
    global.toggleSelect = global.toggleSelect || toggleSelect
    global.toggleDraggable = global.toggleDraggable || toggleDraggable
    global.toggleResizable = global.toggleResizable || toggleResizable
    global.toggleSnapping = global.toggleSnapping || toggleSnapping
    global.toggleSnapping = global.toggleSaver || toggleSaver
    global.remove = global.remove || remove
    global.drag = global.drag || drag
    global.resize = global.resize || resize
    global.align = global.align || align
})(window, window.document)