Skip to content

Commit

Permalink
feat: initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
nousantx committed Nov 14, 2024
0 parents commit 19d3d8b
Show file tree
Hide file tree
Showing 3 changed files with 242 additions and 0 deletions.
143 changes: 143 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<!doctype html>
<html
lang="en"
child="
(body): family-sans-serif w-mx-800px mx-auto p-20px;
(textarea): w-100% h-200px mb-10px;
(.btn): [all]-unset mr-10px h-40px d-inline-flex ai-center px-12px [cursor]-pointer bg-#1c1c1c text-white br-8px fs-14px fw-500;
(canvas): [border]-[2px_solid_#ccc] mt-1rem;
(#error): text-red mt-10px;
(select, input): h-40px px-12px br-8px border-[1px_solid_#ccc] mr-10px;
(.config-row): d-flex ai-center mb-10px;
"
>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HTML to Image Generator</title>
<script src="https://cdn.jsdelivr.net/npm/@tenoxui/[email protected]/dist/tenoxui-full.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tenoxui/[email protected]"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>
</head>
<body>
<h1>HTML to Image Generator</h1>
<textarea class="my-2rem" id="htmlInput">
<div class="family-sans-serif w-1000px h-1000px d-flex ai-center jc-center">
<div class="bg-blue box-300px text-white p-2rem fs-15rem br-1rem">
Hello <span class="bg-yellow text-black [filter]-[blur(10px)]">Tenox!</span>
</div>
</div>
</textarea>
<br />
<div class="config-row">
<select id="outputFormat">
<option value="png">PNG</option>
<option value="jpeg">JPEG</option>
<option value="webp">WebP</option>
<option value="svg">SVG</option>
</select>
<input type="number" id="scale" min="1" max="4" step="0.1" value="1" />
<label for="scale">Scale Factor</label>
</div>
<button class="btn" onclick="generateImage()">Generate Image</button>
<button class="btn" onclick="downloadImage()">Download Image</button>
<div id="error"></div>
<canvas id="canvas" width="1000" height="1000"></canvas>
<script>
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
const errorDiv = document.getElementById('error')
const outputFormatSelect = document.getElementById('outputFormat')
const scaleInput = document.getElementById('scale')

const tenoxuiConfig = {
property: TENOXUI_PROPERTY.property,
values: { full: '100%' },
attributify: true
}

const selector = '*'
document.querySelectorAll(selector).forEach(element => {
new __tenoxui_core.MakeTenoxUI({ element, ...tenoxuiConfig }).useDOM()
})

function generateSVG() {
const temp = document.createElement('div')
temp.innerHTML = document.getElementById('htmlInput').value
temp.querySelectorAll('*').forEach(element => {
new __tenoxui_core.MakeTenoxUI({ element, ...tenoxuiConfig }).useDOM()
})

const scale = parseFloat(scaleInput.value)
const scaledWidth = canvas.width * scale
const scaledHeight = canvas.height * scale

return `
<!-- Generated by NOuSantx -->
<svg xmlns="http://www.w3.org/2000/svg" width="${scaledWidth}" height="${scaledHeight}">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml">
${temp.innerHTML}
</div>
</foreignObject>
</svg>`
}

function generateImage() {
const scale = parseFloat(scaleInput.value)
const scaledWidth = canvas.width * scale
const scaledHeight = canvas.height * scale

errorDiv.textContent = ''
canvas.width = scaledWidth
canvas.height = scaledHeight
ctx.clearRect(0, 0, canvas.width, canvas.height)

const svgData = generateSVG()
const img = new Image()
img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgData)
img.onload = () => {
ctx.scale(scale, scale)
ctx.drawImage(img, 0, 0)
}
img.onerror = () => {
errorDiv.textContent = 'Failed to generate image. Please check your HTML.'
}
}

function downloadImage() {
try {
const outputFormat = outputFormatSelect.value
const link = document.createElement('a')
link.download = `generated-image.${outputFormat}`

if (outputFormat === 'svg') {
const svgData = generateSVG()
const blob = new Blob([svgData], { type: 'image/svg+xml' })
console.log(blob)
link.href = URL.createObjectURL(blob)
} else {
link.href = canvas.toDataURL(`image/${outputFormat}`)
}

link.click()

// Clean up the URL object if SVG was generated
if (outputFormat === 'svg') {
URL.revokeObjectURL(link.href)
}
} catch (error) {
errorDiv.textContent = 'Failed to download image: ' + error.message
}
}

generateImage()
</script>
</body>
</html>
67 changes: 67 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
const errorDiv = document.getElementById('error')
const outputFormatSelect = document.getElementById('outputFormat')
const scaleInput = document.getElementById('scale')

const tenoxuiConfig = {
property: TENOXUI_PROPERTY.property,
values: { full: '100%' },
attributify: true
}

const selector = '*'
document.querySelectorAll(selector).forEach(element => {
new __tenoxui_core.MakeTenoxUI({ element, ...tenoxuiConfig }).useDOM()
})

function generateImage() {
const temp = document.createElement('div')
temp.innerHTML = document.getElementById('htmlInput').value
temp.querySelectorAll('*').forEach(element => {
new __tenoxui_core.MakeTenoxUI({ element, ...tenoxuiConfig }).useDOM()
})

const scale = parseFloat(scaleInput.value)
const scaledWidth = canvas.width * scale
const scaledHeight = canvas.height * scale

const data = `
<svg xmlns="http://www.w3.org/2000/svg" width="${scaledWidth}" height="${scaledHeight}">
<foreignObject width="100%" height="100%">
<div xmlns="http://www.w3.org/1999/xhtml">
${temp.innerHTML}
</div>
<!-- NOuSantx was here! -->
</foreignObject>
</svg>`

errorDiv.textContent = ''
canvas.width = scaledWidth
canvas.height = scaledHeight
ctx.clearRect(0, 0, canvas.width, canvas.height)

const img = new Image()
img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(data)
img.onload = () => {
ctx.scale(scale, scale)
ctx.drawImage(img, 0, 0)
}
img.onerror = () => {
errorDiv.textContent = 'Failed to generate image. Please check your HTML.'
}
}

function downloadImage() {
try {
const outputFormat = outputFormatSelect.value
const link = document.createElement('a')
link.download = `generated-image.${outputFormat}`
link.href = canvas.toDataURL(`image/${outputFormat}`)
link.click()
} catch (error) {
errorDiv.textContent = 'Failed to download image: ' + error.message
}
}

generateImage()
32 changes: 32 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "@nousantx/tenoxui-image-tool",
"version": "0.1.0",
"description": "Image generation library with built-in tenoxui as default styling",
"author": "NOuSantx <[email protected]>",
"license": "MIT",
"homepage": "https://github.com/nousantx/tui-image-generator#readme",
"keywords": [
"keywords"
],
"repository": {
"type": "git",
"url": "git+https://github.com/nousantx/tui-image-generator.git"
},
"bugs": {
"url": "https://github.com/nousantx/tui-image-generator/issues"
},
"files": [
"dist",
"package.json",
"README.md",
"LICENSE"
],
"type": "module",
"types": "index.d.ts",
"main": "index.js",
"module": "index.esm.js",
"style": "index.css",
"scripts": {
"start": "echo 'hello world'"
}
}

0 comments on commit 19d3d8b

Please sign in to comment.