{"id":4851,"date":"2025-05-27T07:53:05","date_gmt":"2025-05-27T07:53:05","guid":{"rendered":"https:\/\/bruun.studio\/?page_id=4851"},"modified":"2025-05-27T08:26:19","modified_gmt":"2025-05-27T08:26:19","slug":"design-tools","status":"publish","type":"page","link":"https:\/\/bruun.studio\/index.php\/design-tools\/","title":{"rendered":"Design tools"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"4851\" class=\"elementor elementor-4851\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2306abb e-flex e-con-boxed e-con e-parent\" data-id=\"2306abb\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-cd8190f elementor-widget elementor-widget-html\" data-id=\"cd8190f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div id=\"patternWrapper\">\n  <!-- Row 1: Controls -->\n  <div class=\"controls\">\n    <label>Format:\n      <select id=\"formatSelect\">\n        <option value=\"1:1\">1:1<\/option>\n        <option value=\"4:5\">4:5<\/option>\n        <option value=\"9:16\">9:16<\/option>\n      <\/select>\n    <\/label>\n\n    <label>Columns: <input type=\"number\" id=\"cols\" value=\"10\" min=\"1\"><\/label>\n    <label>Rows: <input type=\"number\" id=\"rows\" value=\"10\" min=\"1\"><\/label>\n\n    <label>Min Width (px): <input type=\"number\" id=\"minWidth\" value=\"0\" min=\"0\"><\/label>\n    <label>Max Width (px): <input type=\"number\" id=\"maxWidth\" value=\"10\" min=\"1\"><\/label>\n\n    <label>Min Row Height (px): <input type=\"number\" id=\"minRowHeight\" value=\"40\" min=\"1\"><\/label>\n    <label>Max Row Height (px): <input type=\"number\" id=\"maxRowHeight\" value=\"120\" min=\"1\"><\/label>\n\n    <button id=\"generateBtn\">Generate<\/button>\n    <button id=\"downloadBtn\">Download JPEG<\/button>\n  <\/div>\n\n  <!-- Row 2: Canvas -->\n  <div class=\"canvas-container\">\n    <canvas id=\"canvas\" width=\"600\" height=\"600\"><\/canvas>\n  <\/div>\n<\/div>\n\n<style>\n  #patternWrapper {\n    display: flex;\n    flex-direction: column;\n    gap: 20px;\n    font-family: sans-serif;\n    max-width: 100%;\n  }\n\n  .controls {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 10px;\n    align-items: center;\n  }\n\n  .controls label {\n    display: flex;\n    align-items: center;\n    gap: 5px;\n  }\n\n  .controls input,\n  .controls select {\n    width: 70px;\n  }\n\n  .controls button {\n    padding: 6px 12px;\n  }\n\n  .canvas-container {\n    width: 100%;\n  }\n\n  #canvas {\n    display: block;\n    border: 1px solid #ccc;\n    max-width: 100%;\n    height: auto;\n  }\n<\/style>\n\n<script>\n  const canvas = document.getElementById('canvas');\n  const ctx = canvas.getContext('2d');\n  const generateBtn = document.getElementById('generateBtn');\n  const downloadBtn = document.getElementById('downloadBtn');\n\n  function generatePattern() {\n    const format = document.getElementById('formatSelect').value;\n    let width = 600, height = 600;\n\n    if (format === '4:5') {\n      width = 800;\n      height = 1000;\n    } else if (format === '9:16') {\n      width = 900;\n      height = 1600;\n    }\n\n    canvas.width = width;\n    canvas.height = height;\n\n    const columns = parseInt(document.getElementById('cols').value) || 1;\n    const rows = parseInt(document.getElementById('rows').value) || 1;\n    const minW = Math.max(0, parseInt(document.getElementById('minWidth').value));\n    const maxW = parseInt(document.getElementById('maxWidth').value) || 1;\n    let minRowH = parseInt(document.getElementById('minRowHeight').value) || 10;\n    let maxRowH = parseInt(document.getElementById('maxRowHeight').value) || 10;\n\n    if (minW > maxW) [minW, maxW] = [maxW, minW];\n    if (minRowH > maxRowH) [minRowH, maxRowH] = [maxRowH, minRowH];\n\n    const cellWidth = canvas.width \/ columns;\n\n    \/\/ Generate random row heights\n    const rowHeights = [];\n    for (let i = 0; i < rows; i++) {\n      const rowHeight = Math.floor(Math.random() * (maxRowH - minRowH + 1)) + minRowH;\n      rowHeights.push(rowHeight);\n    }\n\n    const totalHeight = rowHeights.reduce((sum, h) => sum + h, 0);\n    const scaleFactor = canvas.height \/ totalHeight;\n    const scaledHeights = rowHeights.map(h => h * scaleFactor);\n\n    \/\/ Draw background\n    ctx.fillStyle = \"#fff\";\n    ctx.fillRect(0, 0, canvas.width, canvas.height);\n    ctx.fillStyle = \"#000\";\n\n    let yOffset = 0;\n    for (let j = 0; j < rows; j++) {\n      const thisRowHeight = scaledHeights[j];\n\n      for (let i = 0; i < columns; i++) {\n        let w = Math.floor(Math.random() * (maxW - minW + 1)) + minW;\n        if (w > cellWidth) w = cellWidth;\n        if (w < 0) w = 0;\n\n        const x = i * cellWidth + (cellWidth - w) \/ 2;\n        const y = yOffset;\n\n        ctx.fillRect(x, y, w, thisRowHeight);\n      }\n\n      yOffset += thisRowHeight;\n    }\n  }\n\n  function downloadCanvasAsJPEG() {\n    const dataURL = canvas.toDataURL(\"image\/jpeg\");\n    const link = document.createElement('a');\n    link.href = dataURL;\n    link.download = \"pattern.jpg\";\n    document.body.appendChild(link);\n    link.click();\n    document.body.removeChild(link);\n  }\n\n  generateBtn.addEventListener('click', generatePattern);\n  downloadBtn.addEventListener('click', downloadCanvasAsJPEG);\n\n  \/\/ F\u00f8rste load\n  generatePattern();\n<\/script>\n\t\t\t\t<\/div>\n\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>Format: 1:14:59:16 Columns: Rows: Min Width (px): Max Width (px): Min Row Height (px): Max Row Height (px): Generate Download JPEG<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"_angie_page":false,"footnotes":""},"class_list":["post-4851","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/bruun.studio\/index.php\/wp-json\/wp\/v2\/pages\/4851","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bruun.studio\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/bruun.studio\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/bruun.studio\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bruun.studio\/index.php\/wp-json\/wp\/v2\/comments?post=4851"}],"version-history":[{"count":10,"href":"https:\/\/bruun.studio\/index.php\/wp-json\/wp\/v2\/pages\/4851\/revisions"}],"predecessor-version":[{"id":4861,"href":"https:\/\/bruun.studio\/index.php\/wp-json\/wp\/v2\/pages\/4851\/revisions\/4861"}],"wp:attachment":[{"href":"https:\/\/bruun.studio\/index.php\/wp-json\/wp\/v2\/media?parent=4851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}