{"id":64,"date":"2025-10-15T16:24:50","date_gmt":"2025-10-15T16:24:50","guid":{"rendered":"https:\/\/stickermonkey.nl\/?page_id=64"},"modified":"2025-10-16T12:18:35","modified_gmt":"2025-10-16T12:18:35","slug":"editor","status":"publish","type":"page","link":"https:\/\/stickermonkey.nl\/?page_id=64","title":{"rendered":"Editor"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"64\" class=\"elementor elementor-64\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c23b3aa e-flex e-con-boxed e-con e-parent\" data-id=\"c23b3aa\" data-element_type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5a88ddb elementor-widget elementor-widget-html\" data-id=\"5a88ddb\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<style>\n:root{--bg:#f7f7f7;--card:#fff;--muted:#666;--accent:#111;}\n*{box-sizing:border-box;}\n.editor-wrap{display:flex;gap:16px;flex-wrap:wrap;justify-content:center;align-items:flex-start;font-family:\"Poppins\",system-ui;}\n.card{background:var(--card);padding:14px;border-radius:12px;box-shadow:0 6px 18px rgba(0,0,0,0.06);}\n.panel{width:280px;min-width:260px;}\n.canvas-holder{flex:1 1 680px;display:flex;justify-content:center;align-items:center;min-width:520px;}\n#main-canvas{border-radius:8px;border:1px solid #dcdcdc;background:#fff;display:block;max-width:100%;}\n.tool-btn{background:#f4f4f4;border:1px solid #e3e3e3;padding:8px 10px;border-radius:8px;cursor:pointer;}\n.tool-btn.active{background:#e0e0e0;}\n.input{width:100%;padding:8px;border-radius:8px;border:1px solid #ddd;margin-top:6px;}\nlabel.small{font-size:.85rem;color:var(--muted);display:block;margin-top:8px;}\n.row{display:flex;gap:8px;margin-top:8px;flex-wrap:wrap;}\n.small{font-size:.85rem;color:var(--muted);margin-top:8px;}\n#status{color:#333;font-size:.9rem;margin-top:6px;}\n.selbox{position:absolute;border:2px dashed rgba(106,160,255,.9);pointer-events:none;transform-origin:0 0;display:none;}\n<\/style>\n\n<div class=\"editor-wrap\">\n  <div class=\"panel card\">\n    <h3>Tools<\/h3>\n    <div class=\"row\">\n      <button id=\"tool-select\" class=\"tool-btn active\">Select<\/button>\n      <button id=\"tool-draw\" class=\"tool-btn\">Brush<\/button>\n      <button id=\"tool-erase\" class=\"tool-btn\">Eraser<\/button>\n    <\/div>\n\n    <h4>Image<\/h4>\n    <input id=\"file-image\" type=\"file\" accept=\"image\/*\" class=\"input\" \/>\n    <div class=\"row\">\n      <button id=\"btn-add-image\" class=\"tool-btn\">Add Image<\/button>\n      <button id=\"btn-remove-bg\" class=\"tool-btn\">Remove BG<\/button>\n    <\/div>\n    <label class=\"small\">BG Color<\/label><input id=\"bg-remove-color\" type=\"color\" value=\"#ffffff\" class=\"input\"\/>\n    <label class=\"small\">Tolerance<\/label><input id=\"bg-remove-tol\" type=\"range\" min=\"0\" max=\"200\" value=\"40\" class=\"input\"\/>\n\n    <h4>Background<\/h4>\n    <label class=\"small\">Color<\/label><input id=\"bg-color\" type=\"color\" value=\"#ffffff\" class=\"input\"\/>\n    <label class=\"small\">Image<\/label><input id=\"bg-image-file\" type=\"file\" accept=\"image\/*\" class=\"input\"\/>\n    <div class=\"row\">\n      <button id=\"btn-set-bg\" class=\"tool-btn\">Set BG<\/button>\n      <button id=\"btn-clear-bg\" class=\"tool-btn\">Clear BG<\/button>\n    <\/div>\n\n    <h4>Text<\/h4>\n    <input id=\"text-input\" class=\"input\" placeholder=\"Type text then Add\"\/>\n    <div class=\"row\">\n      <button id=\"btn-add-text\" class=\"tool-btn\">Add<\/button>\n      <button id=\"btn-edit-text\" class=\"tool-btn\">Edit<\/button>\n    <\/div>\n\n    <h4>Brush<\/h4>\n    <label class=\"small\">Size<\/label><input id=\"brush-size\" type=\"range\" min=\"1\" max=\"80\" value=\"6\" class=\"input\"\/>\n    <label class=\"small\">Color<\/label><input id=\"brush-color\" type=\"color\" value=\"#000000\" class=\"input\"\/>\n\n    <h4>Actions<\/h4>\n    <div class=\"row\">\n      <button id=\"btn-undo\" class=\"tool-btn\">Undo<\/button>\n      <button id=\"btn-clear\" class=\"tool-btn\">Clear<\/button>\n      <button id=\"btn-download\" class=\"tool-btn\">Download<\/button>\n    <\/div>\n    <div id=\"status\" class=\"small\"><\/div>\n  <\/div>\n\n  <div class=\"canvas-holder card\" style=\"position:relative;\">\n    <canvas id=\"main-canvas\" width=\"1000\" height=\"700\"><\/canvas>\n    <div id=\"sel-box\" class=\"selbox\"><\/div>\n  <\/div>\n\n  <div class=\"panel card\">\n    <h3>Properties<\/h3>\n    <div class=\"small\">Selected: <span id=\"sel-info\">None<\/span><\/div>\n    <label class=\"small\">Opacity<\/label><input id=\"prop-opacity\" type=\"range\" min=\"0\" max=\"1\" step=\"0.01\" value=\"1\" class=\"input\"\/>\n    <label class=\"small\">Font Size<\/label><input id=\"prop-fontsize\" type=\"number\" value=\"28\" class=\"input\"\/>\n    <label class=\"small\">Font Color<\/label><input id=\"prop-fontcolor\" type=\"color\" value=\"#000000\" class=\"input\"\/>\n    <div class=\"row\">\n      <button id=\"btn-bring\" class=\"tool-btn\">Bring<\/button>\n      <button id=\"btn-send\" class=\"tool-btn\">Send<\/button>\n      <button id=\"btn-delete\" class=\"tool-btn\">Delete<\/button>\n    <\/div>\n    <label class=\"small\">Canvas Size<\/label>\n    <input id=\"canvas-w\" type=\"number\" value=\"1000\" class=\"input\"\/>\n    <input id=\"canvas-h\" type=\"number\" value=\"700\" class=\"input\"\/>\n    <button id=\"btn-resize-canvas\" class=\"tool-btn\">Resize<\/button>\n  <\/div>\n<\/div>\n\n<script>\n(()=>{ \/\/ Canvas Editor (compact)\nconst c=document.getElementById(\"main-canvas\"),x=c.getContext(\"2d\"),sb=document.getElementById(\"sel-box\");\nlet objs=[],bg={color:\"#fff\",image:null},mode=\"select\",sel=null,down=false,last={x:0,y:0},off={x:0,y:0},draw=null,undo=[];\nconst st=t=>{const s=document.getElementById(\"status\");s.textContent=t;setTimeout(()=>{if(s.textContent===t)s.textContent=\"\"},2e3)};\nconst u=()=>undo.push(JSON.stringify({objs,bg})),p=()=>{if(!undo.length)return;const a=JSON.parse(undo.pop());objs=a.objs;bg=a.bg;sel=null;r()};\nfunction r(){x.clearRect(0,0,c.width,c.height);x.fillStyle=bg.color;x.fillRect(0,0,c.width,c.height);\nif(bg.image)x.drawImage(bg.image,0,0,c.width,c.height);\nfor(const o of objs.slice().sort((a,b)=>(a.z||0)-(b.z||0))){x.save();x.globalAlpha=o.opacity??1;\nif(o.type===\"image\")x.translate(o.x,o.y),x.rotate(o.a||0),x.drawImage(o._, -o.w\/2,-o.h\/2,o.w,o.h);\nelse if(o.type===\"text\"){x.translate(o.x,o.y);x.rotate(o.a||0);x.font=`${o.fs||28}px Arial`;x.fillStyle=o.fill||\"#000\";x.textAlign=\"center\";x.textBaseline=\"middle\";x.fillText(o.t||\"\",0,0);}\nelse if(o.type===\"draw\"){x.beginPath();x.lineJoin=x.lineCap=\"round\";x.lineWidth=o.sz;x.strokeStyle=o.col;for(let i=1;i<o.p.length;i++)x.moveTo(o.p[i-1].x,o.p[i-1].y),x.lineTo(o.p[i].x,o.p[i].y);x.stroke();}\nx.restore()}dSel();}\nfunction dSel(){if(!sel){sb.style.display=\"none\";return;}const o=objs.find(v=>v.id===sel);if(!o){sb.style.display=\"none\";return;}\nlet minX=Infinity,minY=Infinity,maxX=-Infinity,maxY=-Infinity;\nif(o.type===\"image\"||o.type===\"text\"){const pts=[[-o.w\/2,-o.h\/2],[o.w\/2,-o.h\/2],[o.w\/2,o.h\/2],[-o.w\/2,o.h\/2]],c2=Math.cos(o.a||0),s2=Math.sin(o.a||0);\nfor(const [px,py] of pts){const xx=o.x+px*c2-py*s2,yy=o.y+px*s2+py*c2;minX=Math.min(minX,xx);minY=Math.min(minY,yy);maxX=Math.max(maxX,xx);maxY=Math.max(maxY,yy);}\n}else if(o.type===\"draw\"){for(const p of o.p)minX=Math.min(minX,p.x),minY=Math.min(minY,p.y),maxX=Math.max(maxX,p.x),maxY=Math.max(maxY,p.y);}\nsb.style.cssText=`display:block;left:${c.offsetLeft+minX}px;top:${c.offsetTop+minY}px;width:${maxX-minX}px;height:${maxY-minY}px;`}\nfunction hit(xp,yp){for(const o of objs.slice().sort((a,b)=>(b.z||0)-(a.z||0))){if(o.type===\"image\"||o.type===\"text\"){const a=o.a||0,cs=Math.cos(-a),sn=Math.sin(-a),lx=cs*(xp-o.x)-sn*(yp-o.y),ly=sn*(xp-o.x)+cs*(yp-o.y);\nif(Math.abs(lx)<=o.w\/2&&Math.abs(ly)<=o.h\/2)return o;}else if(o.type===\"draw\"){for(const p of o.p)if(Math.hypot(p.x-xp,p.y-yp)<=o.sz)return o;}}return null;}\nfunction hex2rgb(h){h=h.replace(\"#\",\"\");if(h.length==3)h=h.split(\"\").map(v=>v+v).join(\"\");const n=parseInt(h,16);return{r:(n>>16)&255,g:(n>>8)&255,b:n&255}}\nfunction cDist(r1,g1,b1,r2,g2,b2){return Math.sqrt((r1-r2)**2+(g1-g2)**2+(b1-b2)**2)}\nc.addEventListener(\"pointerdown\",e=>{const r=c.getBoundingClientRect(),x1=e.clientX-r.left,y1=e.clientY-r.top;down=true;last={x:x1,y:y1};\nif(mode===\"draw\"||mode===\"erase\"){draw={id:Date.now(),p:[{x:x1,y:y1}],sz:+document.getElementById(\"brush-size\").value,col:mode===\"erase\"?bg.color:document.getElementById(\"brush-color\").value,type:\"draw\"};return;}\nconst h=hit(x1,y1);if(h){sel=h.id;off.x=x1-h.x;off.y=y1-h.y;}else sel=null;r();});\nc.addEventListener(\"pointermove\",e=>{if(!down)return;const r=c.getBoundingClientRect(),x1=e.clientX-r.left,y1=e.clientY-r.top;\nif(mode===\"draw\"||mode===\"erase\"){draw.p.push({x:x1,y:y1});r();x.beginPath();x.lineJoin=x.lineCap=\"round\";x.strokeStyle=draw.col;x.lineWidth=draw.sz;\nx.moveTo(draw.p.at(-2).x,draw.p.at(-2).y);x.lineTo(x1,y1);x.stroke();return;}\nconst o=objs.find(v=>v.id===sel);if(o){if(o.type===\"draw\"){const dx=x1-last.x,dy=y1-last.y;o.p=o.p.map(p=>({x:p.x+dx,y:p.y+dy}));}\nelse o.x=x1-off.x,o.y=y1-off.y;r();}last={x:x1,y:y1};});\nc.addEventListener(\"pointerup\",()=>{down=false;if(draw){u();objs.push({...draw,z:objs.length+1});draw=null;r();}else u();});\ndocument.getElementById(\"tool-select\").onclick=()=>{mode=\"select\";};\ndocument.getElementById(\"tool-draw\").onclick=()=>{mode=\"draw\";};\ndocument.getElementById(\"tool-erase\").onclick=()=>{mode=\"erase\";};\ndocument.getElementById(\"btn-add-image\").onclick=()=>{const f=fileImage.files[0];if(!f)return alert(\"choose image\");const r2=new FileReader();r2.onload=e=>{const i=new Image();i.onload=()=>{u();objs.push({id:Date.now(),type:\"image\",x:c.width\/2,y:c.height\/2,w:i.width>400?400:i.width,h:i.height*(i.width>400?400\/i.width:1),a:0,opacity:1,z:objs.length+1,_:i});sel=objs.at(-1).id;r();};i.src=e.target.result;};r2.readAsDataURL(f);};\ndocument.getElementById(\"btn-remove-bg\").onclick=()=>{const o=objs.find(v=>v.id===sel&&v.type===\"image\");if(!o)return alert(\"select image\");const col=hex2rgb(bgRemoveColor.value),tol=+bgRemoveTol.value;\nconst t=document.createElement(\"canvas\");t.width=o._.width;t.height=o._.height;const tc=t.getContext(\"2d\");tc.drawImage(o._,0,0);const d=tc.getImageData(0,0,t.width,t.height);for(let i=0;i<d.data.length;i+=4){const[r,g,b]=[d.data[i],d.data[i+1],d.data[i+2]];if(cDist(r,g,b,col.r,col.g,col.b)<tol)d.data[i+3]=0;}tc.putImageData(d,0,0);const n=new Image();n.onload=()=>{u();o._=n;r();st(\"BG removed\");};n.src=t.toDataURL();};\ndocument.getElementById(\"bg-color\").oninput=e=>{bg.color=e.target.value;r();};\ndocument.getElementById(\"btn-set-bg\").onclick=()=>{const f=bgImageFile.files[0];if(!f)return;const r2=new FileReader();r2.onload=e=>{const i=new Image();i.onload=()=>{u();bg.image=i;r();};i.src=e.target.result;};r2.readAsDataURL(f);};\ndocument.getElementById(\"btn-clear-bg\").onclick=()=>{u();bg.image=null;r();};\ndocument.getElementById(\"btn-add-text\").onclick=()=>{const t=textInput.value;if(!t)return;u();objs.push({id:Date.now(),type:\"text\",x:c.width\/2,y:c.height\/2,w:200,h:60,t,font:\"Arial\",fs:+propFontSize.value,fill:propFontColor.value,a:0,opacity:1,z:objs.length+1});sel=objs.at(-1).id;r();};\ndocument.getElementById(\"btn-edit-text\").onclick=()=>{const o=objs.find(v=>v.id===sel&&v.type===\"text\");if(!o)return;u();o.t=textInput.value;o.fs=+propFontSize.value;o.fill=propFontColor.value;r();};\ndocument.getElementById(\"btn-undo\").onclick=()=>{p();};\ndocument.getElementById(\"btn-clear\").onclick=()=>{if(confirm(\"Clear all?\")){u();objs=[];bg.image=null;r();}};\ndocument.getElementById(\"btn-download\").onclick=()=>{const a=document.createElement(\"a\");a.download=\"canvas.png\";a.href=c.toDataURL();a.click();};\ndocument.getElementById(\"prop-opacity\").oninput=e=>{const o=objs.find(v=>v.id===sel);if(!o)return;u();o.opacity=+e.target.value;r();};\ndocument.getElementById(\"prop-fontsize\").oninput=e=>{const o=objs.find(v=>v.id===sel&&v.type===\"text\");if(!o)return;u();o.fs=+e.target.value;r();};\ndocument.getElementById(\"prop-fontcolor\").oninput=e=>{const o=objs.find(v=>v.id===sel&&v.type===\"text\");if(!o)return;u();o.fill=e.target.value;r();};\ndocument.getElementById(\"btn-bring\").onclick=()=>{const i=objs.findIndex(v=>v.id===sel);if(i<0)return;u();objs.push(objs.splice(i,1)[0]);r();};\ndocument.getElementById(\"btn-send\").onclick=()=>{const i=objs.findIndex(v=>v.id===sel);if(i<0)return;u();objs.unshift(objs.splice(i,1)[0]);r();};\ndocument.getElementById(\"btn-delete\").onclick=()=>{const i=objs.findIndex(v=>v.id===sel);if(i<0)return;u();objs.splice(i,1);sel=null;r();};\ndocument.getElementById(\"btn-resize-canvas\").onclick=()=>{const w=+canvasW.value,h=+canvasH.value;if(w>0&&h>0){u();c.width=w;c.height=h;r();}};\ndocument.addEventListener(\"keydown\",e=>{if([\"Delete\",\"Backspace\"].includes(e.key)){const i=objs.findIndex(v=>v.id===sel);if(i>=0){u();objs.splice(i,1);sel=null;r();}}else if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()===\"z\")p();});\nr();\n})();\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Tools Select Brush Eraser Image Add Image Remove BG BG Color Tolerance Background Color Image Set BG Clear BG Text Add Edit Brush Size Color Actions Undo Clear Download Properties Selected: None Opacity Font Size Font Color Bring Send Delete Canvas Size Resize<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-64","page","type-page","status-publish","hentry"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/stickermonkey.nl\/index.php?rest_route=\/wp\/v2\/pages\/64","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/stickermonkey.nl\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/stickermonkey.nl\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/stickermonkey.nl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/stickermonkey.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=64"}],"version-history":[{"count":10,"href":"https:\/\/stickermonkey.nl\/index.php?rest_route=\/wp\/v2\/pages\/64\/revisions"}],"predecessor-version":[{"id":241,"href":"https:\/\/stickermonkey.nl\/index.php?rest_route=\/wp\/v2\/pages\/64\/revisions\/241"}],"wp:attachment":[{"href":"https:\/\/stickermonkey.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=64"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}