CLIP MAKER USING HTML CSS AND JS

AYUSH KUSHWAHA
0
Clip Ui

Make a attractive clip maker (polygon maker) using html, css and js

Open Your Code editor and make a folder Then make a file with name index.html and paste the given below code.


   

<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <meta http-equiv="X-UA-Compatible" content="ie=edge">

  <link rel="stylesheet" href="style.css">

  <title>Clip me Ui</title>

</head>

<body>

  <div class="wrapper">

  <div class="title">CLIP<span>ME</span></div>

  <div class="clip-area">

    <div style="--x:0;--y:0;" draggable></div>

    <div style="--x:1;--y:0;" draggable></div>

    <div style="--x:1;--y:1;" draggable></div>

    <div style="--x:0;--y:1;" draggable></div>

  </div>

  <code class="clip-path"></code>

  <div class="action">

    <button onclick="copy()">Copy CSS</button>

    <button onclick="remove()">Remove</button>

  </div>

  <div class="info">

    Drag the Points to Shape the Clip-Path<br>

    Double Click any Point to Create a New Point

  </div>

</div>

<script>

const doc = document ;

const qs  = q => doc.querySelector(q);

const qsa = q => doc.querySelectorAll(q);

const ce  = q => doc.createElement(q);

function addEventHooks(o){

  o.on = (...p) => o.addEventListener(...p);

  o.off = (...p) => o.removeEventListener(...p);

}

</script>

<!-- Copy To Clipboard -->

<script>

function copyToClipboard(str) { 

    const el = ce('textarea');

    el.value = str; 

    qs("body").appendChild(el); 

    el.select(); 

    doc.execCommand('copy'); 

    el.remove();

};

</script>

<script src="script.js"></script>

</html>

</body>

   

 

Now make a style.css file and pase the give below code


  

  @import url('https://fonts.googleapis.com/css2?family=Nunito:wght@700;900&display=swap');

* {

    box-sizing: border-box ;

    margin : 0 ;

    padding: 0 ;

}

html {

    font-family: "Nunito" , sans-serif ;

}

.wrapper {

    position:absolute;

    inset:0px;

    color:#fff;

    background-color:hsl(220,20%,15%);

    overflow:hidden;

    display:flex;

    align-items:center;

    justify-content:center;

    flex-direction:column;

}

.clip-area {

    --cp:polygon(40% 40%,60% 40%,60% 60%,40% 60%);

    position:relative;

    width :80vmin;

    height:80vmin;

    background-color:hsl(220,20%,10%);

    border-radius:8px;

}

.clip-area::before {

    position:absolute;

    content:"";

    inset:0;

    background:linear-gradient(

        -135deg,

        hsl(10,80%,60%),

        hsl(335,80%,60%)

    );

    clip-path:var(--cp);

}

.clip-area[data-animate="true"]::before {

    transition:all 200ms ease-out;

}

[draggable] {

    --x:0;

    --y:0;

    position:absolute;

    z-index:1;

    width :1rem;

    height:1rem;

    border-radius:50%;

    box-shadow:0 0 0 0 white;

    background-color:white;

    transition:

        box-shadow 200ms ease-out,

        background 200ms ease-out;

    transform: translate(

        calc((var(--x) * var(--w)) - 50%),

        calc((var(--y) * var(--h)) - 50%)

    );

}

[data-active="true"]{

    box-shadow: 0 0 0 4px white;

    background-color:hsl(335,80%,60%);

}

.clip-path {

    color:hsl(220,20%,80%);

    margin-top:2rem;

    text-align:center;

    width:80vmin;

    padding:1rem;

    white-space:nowrap;

    background-color:hsl(220,20%,10%);

    border-radius:8px;

    overflow-x:auto;

    font-size:1.1rem;

    font-weight:700;

    user-select:all;

}

.clip-path::before {

    content:"clip-path : ";

    color:hsl(355,80%,60%);

}

.clip-path::after {

    content:" ;";

    color:hsl(220,20%,40%);

}

.title {

    font-size:2rem;

    font-weight:900;

    margin-bottom:2rem;

}

.title span {

    color:hsl(355,80%,60%);

    }

::selection {

    color:#fff;

    background-color:hsl(355,80%,60%);

}

.action {

    width:80vmin;

    margin-top:1rem;

    display:flex;

}

.action > * + * {

    margin-left:1rem;

}

button {

    padding:1rem ;

    background-color:hsl(355,80%,60%);

    background:linear-gradient(

        -135deg,

        hsl(10,80%,60%),

        hsl(335,80%,60%)

    );

    color:#fff;

    width:100%;

    font-weight:900;

    text-transform:uppercase;

    border-radius:8px;

    border:none;

    font-family:"Nunito",sans-serif;

}

.info {

    margin-top:2rem;

    color:hsl(220,20%,50%);

    max-width:40ch;

    text-align:center;

}

.toast {

    position:fixed;

    bottom:2rem;

    left:50%;

    padding:1rem 1.5rem;

    border-radius:8px;

    background-color:hsl(220,20%,10%);

    white-space:nowrap;

    color:#fff;

    transform:translate(-50%,0);

    animation: 

        pop-up 200ms ease-out,

        pop-down 200ms 2s forwards ease-out;

}

@keyframes pop-up {

    from {transform:translate(-50%,10rem);}

}

@keyframes pop-down {

    to {transform:translate(-50%,10rem);}

}

  

Now make a script.js file and paste the given below code.


  

window.onload = () => {

  window.onresize();

  initDraggable();

  update();

  setTimeout(()=>{

      toast("Like and Comment ❤");

  },500);

}

window.onresize = () => {

  let p = qs(".clip-area");

  let cb = p.getBoundingClientRect();

  p.style.setProperty("--w",cb.width+"px");

  p.style.setProperty("--h",cb.height+"px");

}

function update(){

  let ca = qs(".clip-area");

  let points = [...qsa("[draggable]")];

  let path = "polygon(";

  points.forEach((t,i) => {

    const p  = t.parentElement ;

    const cb = t.getBoundingClientRect();

    let {x,y} = getXYOffset(t,p);

    

    path += (i==0?"":",");

    path += `${Math.round(x)}% ${Math.round(y)}%`;

  });

  path+=")";

  //console.log(path)

  ca.style.setProperty("--cp",path);

  qs(".clip-path").innerText = path;

}

function initDraggable(){

  let de = [...qsa("[draggable]")];

  de.forEach(makeDraggable);

}

function makeDraggable(e){

    addEventHooks(e)

    e.setAttribute("tabindex","1");

    e.ps = ps.bind(e);

    e.pm = pm.bind(e);

    e.pe = pe.bind(e);

    e.on("touchstart",e.ps);

    e.on("mousedown",e.ps);

    e.on("dblclick",clone);

}

function clamp(v,min,max){

    return Math.max(min,Math.min(v,max));

}

function getXYOffset(t,p){

    let tcb = t.getBoundingClientRect();

    let pcb = p.getBoundingClientRect();

    x = ((tcb.x - pcb.x + tcb.width/2)/pcb.width);

    y = ((tcb.y - pcb.y + tcb.height/2)/pcb.height);

    x = clamp(x,0,1)*100;

    y = clamp(y,0,1)*100;

    return { x , y };

}

function getOffset(e,p){

  let cb = p.getBoundingClientRect();

  let x = e.pageX || e.touches[0].pageX;

  let y = e.pageY || e.touches[0].pageY;

  x = ((x-cb.x)/cb.width);

  y = ((y-cb.y)/cb.height);

  x = clamp(x,0,1);

  y = clamp(y,0,1);

  return { x , y };

}

function clone(e){

  let t = e.target;

  let np = ce("div");

  let p = t.parentElement;

  let x = t.style.getPropertyValue("--x");

  let y = t.style.getPropertyValue("--y");

  np.setAttribute("draggable","true");

  np.style.setProperty("--x",x)

  np.style.setProperty("--y",y)

  makeDraggable(np);

  p.insertBefore(np,t);

  vibrate(50);

}

function vibrate(t){

    try{

        navigator.vibrate(t);

    } catch(err){

        // do nothing

    }

}

function ps(e){

  const t = e.target;

  const p = t.parentElement;

  addEventHooks(p)

  p.on("touchmove",t.pm);

  p.on("mousemove",t.pm);

  p.on("touchend",t.pe);

  p.on("mouseup",t.pe);

  p.on("touchleave",t.pe);

  p.on("mouseleave",t.pe);

  [...qsa('[data-active="true"]')].forEach(a=>{

      a.dataset.active = "false";

  })

  t.dataset.active = "true";

}

function pm(e){

  const t = e.target;

  const p = t.parentElement ;

  const cb = p.getBoundingClientRect();

  let {x,y} = getOffset(e,p);

  t.style.setProperty("--x",x);

  t.style.setProperty("--y",y);

  update();

}

function pe(e){

  const t = e.target;

  const p = t.parentElement;

  p.off("touchmove",t.pm);

  p.off("mousemove",t.pm);

  p.off("touchend",t.pe);

  p.off("mouseup",t.pe);

  p.off("touchleave",t.pe);

  p.off("mouseleave",t.pe);

}

function copy(e){

    let path = "clip-path: " + qs(".clip-path").innerText + " ;";

    copyToClipboard(path);

    toast("Copied to Clioboard");

    vibrate(50);

}

function toast(msg){

  let t = ce("div");

  t.classList.add("toast");

  t.innerText = msg;

  qs("body").append(t);

  setTimeout(()=>{t.remove()},5000);

}

function remove(){

  if(qsa("[draggable]").length < 4) return;

  let a = qs("[data-active='true']");

  if(a){

    let ns = a.nextElementSibling;

    if(!ns) ns = qs("[draggable]");

    let x = ns.style.getPropertyValue("--x");

    let y = ns.style.getPropertyValue("--y");

    qs(".clip-area").dataset.animate="true";

    ns.dataset.active = "true";

    a.style.setProperty("--x",x)

    a.style.setProperty("--y",y)

    update();

    setTimeout(()=>{

        a.remove();

        qs(".clip-area").dataset.animate="false";

        update();

    },200);

    vibrate(60);

  }

}



output

output

Post a Comment

0Comments

Post a Comment (0)