尋找熱愛表達的你#
"一鍵將網頁截圖制作成HTML網頁"是指一種技術,它允許用戶通過簡單的操作,將網頁的截圖轉換成HTML代碼的網頁。這通常涉及到自動布局、樣式提取和代碼生成。以下是實現這一功能的相關技術和步驟:
1. 截圖捕捉:首先,需要有一個方法來捕捉網頁的截圖,這可以通過瀏覽器插件、屏幕捕獲工具或專門的應用程序來完成。
2. 圖像處理:捕捉到的截圖可能需要進行預處理,比如裁剪、壓縮或調整分辨率,以確保圖像的質量。
3. 元素識別:使用圖像識別技術來分析截圖,識別網頁中的元素,比如文本、按鈕、圖片等。
4. 布局分析:基于識別出的元素,分析頁面的布局信息,包括元素的大小、位置和層級。
5. 樣式解析:提取頁面的樣式信息,包括顏色、字體、間距等,并將它們轉換為CSS代碼。
6. HTML生成:根據布局和樣式信息,生成HTML結構代碼,將截圖中的元素轉換為HTML標簽。
7. 代碼優化:對生成的HTML代碼進行優化,確保代碼的可讀性、維護性和性能。
8. 響應式設計:確保生成的網頁代碼能夠適應不同的屏幕尺寸和設備,實現響應式布局。
9. 交互性實現:如果截圖中的頁面包含交互元素,需要添加相應的JavaScript代碼來實現這些交互。
10. 一鍵操作:提供一個簡單的用戶界面,用戶只需點擊一個按鈕,就可以完成截圖到HTML的轉換。
11. 預覽功能:在轉換過程中提供實時預覽,讓用戶可以實時看到轉換效果。
12. 自定義選項:允許用戶對生成的HTML代碼進行自定義,比如修改布局、添加額外的樣式或功能。
13. 保存和導出:用戶可以保存或導出生成的HTML代碼,以便進一步使用或分享。
14. 錯誤處理:在轉換過程中識別和處理潛在的錯誤,比如布局沖突或樣式問題。
15. 兼容性測試:確保生成的網頁在不同的瀏覽器和設備上都能正常顯示和工作。
16. 安全性考慮:生成的代碼應遵循安全最佳實踐,避免潛在的安全風險。
17. 用戶反饋:收集用戶反饋,不斷改進轉換算法和用戶體驗。
18. 開源和社區支持:作為開源項目,鼓勵社區參與貢獻代碼和改進功能。
這種一鍵轉換技術可以大大提高網頁開發的效率,尤其是對于快速原型設計和演示目的。然而,需要注意的是,自動生成的代碼可能需要進一步的人工審查和調整,以確保最終產品的質量和性能。此外,一些復雜的網頁效果和動態交互可能需要手動編寫代碼來實現。
一篇:這么多USB接口你都認識嗎?帶你了解現在最常用的USB type-c接口
在日常生活中二維碼幾乎隨處可見,小到微信支付,大到核酸檢測,我們幾乎天天在用。
有時候需要將一個網址、一個圖片、一篇文字、一個文件發給別人,或在微群里進行線上傳播,如果直接發網址或文本會很不方便,但是如果發一個二維碼過去,就非常方便了。
或者想在宣傳單頁、海報上印刷一個活動宣傳頁面,如果印一個網址上去,那客戶感知就太差了,誰有耐心在手機上輸入一長串的網址呀,如果印一個二維碼上去,客戶用手機掃碼就可以直接跳轉到活動面面。
下面給大家分享一下怎么生成二維碼,我在工作中使用最多的就是草料二維碼,這個工具使用了很多年了,自認為使用起來比較順手,所以推薦大家試用。
1、首先打開草料二維碼的WEB網站,或者直接用草料二維碼的微信小程序也可以。
2、注冊登錄不必多說,用手機號注冊、或直接用微信掃碼登錄即可。一般個人用戶類型基本可以滿足大部分需求,我使用的是個人免費版。
3、登錄后進入首頁,即可進入二維碼生成頁面,非常直觀,一看即會。
4、試驗一下將一篇文字生成二維碼,將文字直接粘貼到文本框內,點擊生成二維碼即可。
5、就是這么簡單,右側生成了一個二維碼,下載二維碼圖片就完了,用你的微信掃一掃這個二維碼看能不能識別。你學會了嗎?
特別注意:超長內容的二維碼圖案會非常復雜,需要足夠清晰的大圖才能完整展示,所以文本字數越多,生成的二維碼越復雜,用手機掃描會不好識別。建議文本內容不要超過150個字,以保證二維碼能快速掃描識別。
6、將一個網址生成二維碼方法一樣,選上面的網址標簽,將網址粘貼到文本框內,如法炮制,一個二維碼就生成了,用微信掃碼試試看。
你學廢了嗎?
工具不宜太多,有一個趁手的即可,類似的工具有很多,大家也可自已在網上搜索,體驗各種不同的二維碼生成工具,挑選一個自已喜歡的,用著順手的工具,方便在日常工作中使用,達到事半功倍的效果。
者開源了一個Web思維導圖,在做導出為圖片的功能時走了挺多彎路,所以通過本文來記錄一下。
思維導圖的節點和連線都是通過 svg渲染的,作為一個純 js 庫,我們不考慮通過后端來實現,所以只能思考如何通過純前端的方式來實現將svg或html轉換為圖片。
我們都知道 img 標簽可以顯示 svg,然后 canvas 又可以渲染 img,那么是不是只要將svg渲染到img標簽里,再通過canvas導出為圖片就可以呢,答案是肯定的。
const svgToPng = async (svgStr) => {
// 轉換成blob數據
let blob = new Blob([svgStr], {
type: 'image/svg+xml'
})
// 轉換成data:url數據
let svgUrl = await blobToUrl(blob)
// 繪制到canvas上
let imgData = await drawToCanvas(svgUrl)
// 下載
downloadFile(imgData, '圖片.png')
}
svgStr是要導出的svg字符串,比如:
然后通過Blob構造函數創建一個類型為image/svg+xml的blob數據,接下來將blob數據轉換成data:URL:
const blobToUrl = (blob) => {
return new Promise((resolve, reject) => {
let reader = new FileReader()
reader.onload = evt => {
resolve(evt.target.result)
}
reader.onerror = err => {
reject(err)
}
reader.readAsDataURL(blob)
})
}
其實就是base64格式的字符串。
接下來就可以通過img來加載,并渲染到canvas里進行導出:
const drawToCanvas = (svgUrl) => {
return new Promise((resolve, reject) => {
const img = new Image()
// 跨域圖片需要添加這個屬性,否則畫布被污染了無法導出圖片
img.setAttribute('crossOrigin', 'anonymous')
img.onload = async () => {
try {
let canvas = document.createElement('canvas')
canvas.width = img.width
canvas.height = img.height
let ctx = canvas.getContext('2d')
ctx.drawImage(img, 0, 0, img.width, img.height)
resolve(canvas.toDataURL())
} catch (error) {
reject(error)
}
}
img.onerror = e => {
reject(e)
}
img.src = svgUrl
})
}
canvas.toDataURL()方法返回的也是一個base64格式的data:URL字符串:
最后就可以通過a標簽來下載:
const downloadFile = (file, fileName) => {
let a = document.createElement('a')
a.href = file
a.download = fileName
a.click()
}
實現很簡單,效果也不錯,不過這樣就沒問題了嗎,接下來我們插入兩張圖片試試。
第一張圖片是使用base64的data:URL方式插入的,第二張圖片是使用普通url插入的:
導出結果如下:
可以看到,第一張圖片沒有問題,第二張圖片裂開了,可能你覺得同源策略的問題,但實際上換成同源的圖片,同樣也是裂開的,解決方法很簡單,遍歷svg節點樹,將圖片都轉換成data:URL的形式即可:
// 操作svg使用了@svgdotjs/svg.js庫
const transfromImg = (svgNode) => {
let imageList = svgNode.find('image')
let task = imageList.map(async item => {
// 獲取圖片url
let imgUlr = item.attr('href') || item.attr('xlink:href')
// 已經是data:URL形式不用轉換
if (/^data:/.test(imgUlr)) {
return
}
// 轉換并替換圖片url
let imgData = await drawToCanvas(imgUlr)
item.attr('href', imgData)
})
await Promise.all(task)
return svgNode.svg()// 返回svg html字符串
}
這里使用了前面的drawToCanvas方法來將圖片轉換成data:URL,這樣導出就正常了:
到這里,將純 svg 轉換為圖片就基本沒啥問題了。
svg提供了一個foreignObject標簽,可以插入html節點,實際上,筆者就是使用它來實現節點的富文本編輯效果的:
接下來使用前面的方式來導出,結果如下:
明明顯示沒有問題,導出時foreignObject內容卻發生了偏移,這是為啥呢,其實是因為默認樣式的問題,頁面全局清除了margin和padding,以及將box-sizing設置成了border-box:
那么當svg存在于文檔樹中時是沒有問題的,但是導出時使用的是svg字符串,是脫離于文檔的,所以沒有這個樣式覆蓋,那么顯示自然會出現問題,知道了原因,解決方法有兩種,一是遍歷所有嵌入的html節點,手動添加內聯樣式,注意一定要給所有的html節點都添加,只給svg、foreignObject或最外層的html節點添加都是不行的;第二種是直接在foreignObject標簽里添加一個style標簽,通過style標簽來加上樣式,并且只要給其中一個foreignObject標簽添加就可以了,兩種方式看你喜歡哪種,筆者使用的是第二種:
const transformForeignObject = (svgNode) => {
let foreignObjectList = svgNode.find('foreignObject')
if (foreignObjectList.length > 0) {
foreignObjectList[0].add(SVG(`<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
</style>`))
}
return svgNode.svg()
}
導出結果如下:
可以看到,一切正常。
關于兼容性的問題,筆者測試了最新的chrome、firefox、opera、safari、360急速瀏覽器,運行都是正常的。
前面介紹的是筆者目前采用的方案,看著實現其實非常簡單,但是過程漫長且坎坷,接下來,開始我的表演。
對于svg的操作筆者使用的是svg.js庫,創建富文本節點的核心代碼大致如下:
import { SVG, ForeignObject } from '@svgdotjs/svg.js'
let html = `<div>節點文本</div>`
let foreignObject = new ForeignObject()
foreignObject.add(SVG(html))
g.add(foreignObject)
SVG方法是用來將一段html字符串轉換為dom節點的。
在chrome瀏覽器和opera瀏覽器上渲染非常正常,但是在firefox瀏覽器上foreignObject標簽的內容完全渲染不出來:
檢查元素也看不出有任何問題,并且神奇的是只要在控制臺元素里編輯一下嵌入的html內容,它就可以顯示了,百度搜索了一圈,也沒找到解決方法,然后因為firefox瀏覽器占有率并不高,于是這個問題就擱淺了。
chrome瀏覽器雖然渲染是正常的:
但是使用前面的方式導出時foreignObject標簽內容卻是跟在firefox瀏覽器里顯示一樣是空的:
firefox能忍這個不能忍,于是嘗試使用一些將html轉換為圖片的庫。
使用html2canvas:
import html2canvas from 'html2canvas'
const useHtml2canvas = async (svgNode) => {
let el = document.createElement('div')
el.style.position = 'absolute'
el.style.left = '-9999999px'
el.appendChild(svgNode)
document.body.appendChild(el)// html2canvas轉換需要被轉換的節點在文檔中
let canvas = await html2canvas(el, {
backgroundColor: null
})
mdocument.body.removeChild(el)
return canvas.toDataURL()
}
html2canvas可以成功導出,但是存在一個問題,就是foreignObject標簽里的文本樣式會丟失:
這應該是html2canvas的一個bug,不過看它這issues數量和提交記錄:
指望html2canvas改是不現實的,于是又嘗試使用dom-to-image:
import domtoimage from 'dom-to-image'
const dataUrl = domtoimage.toPng(el)
發現dom-to-image更不行,導出完全是空白的:
并且它上一次更新時間已經是五六年前,所以沒辦法,只能回頭使用html2canvas。
后來有人建議使用dom-to-image-more,粗略看了一下,它是在dom-to-image庫的基礎上修改的,嘗試了一下,發現確實可以,于是就改為使用這個庫,然后又有人反饋在一些瀏覽器上導出節點內容是空的,包括firefox、360,甚至chrome之前的版本都不行,筆者只能感嘆,太難了,然后又有人建議使用上一個大版本,可以解決在firefox上的導出問題,但是筆者試了一下,在其他一些瀏覽器上依舊存在問題,于是又在考慮要不要換回html2canvas,雖然它存在一定問題,但至少不是完全空的。
用的人多了,這個問題又有人提了出來,于是筆者又嘗試看看能不能解決,之前一直認為是firefox瀏覽器的問題,畢竟在chrome和opera上都是正常的,這一次就想會不會是svgjs庫的問題,于是就去搜它的issue,沒想到,還真的搜出來了issue,大意就是因為通過SVG方法轉換的dom節點是在svg的命名空間下,也就是使用document.createElementNS方法創建的,導致部分瀏覽器渲染不出來,歸根結底,這還是不同瀏覽器對于規范的不同實現導致的:
你說chrome很強吧,確實,但是無形中它阻止了問題的暴露。
知道了原因,那么修改也很簡單了,只要將SVG方法第二個參數設為true即可,或者自己來創建節點也可以:
foreignObject.add(document.createElemnt('div'))
果然,在firefox瀏覽器上正常渲染了。
解決了在firefox瀏覽器上foreignObject標簽為空的問題后,自然會懷疑之前使用img結合canvas導出圖片時foreignObject標簽為空會不會也是因為這個問題,同時了解了一下dom-to-image庫的實現原理,發現它也是通過將dom節點添加到svg的foreignObject標簽中實現將html轉換成圖片的,那么就很搞笑了,我本身要轉換的內容就是一個嵌入了foreignObject標簽的svg,使用dom-to-image轉換,它會再次把傳給它的svg添加到一個foreignObject標簽中,這不是套娃嗎,既然dom-to-image-more能通過foreignObject標簽成功導出,那么不用它必然也可以,到這里基本確信之前不行就是因為命名空間的問題。
果然,在去掉了dom-to-image-more庫后,重新使用之前的方式成功導出了,并且在firefox、chrome、opera、360等瀏覽器中都不存在問題,兼容性反而比dom-to-image-more庫好。
雖然筆者的實現很簡單,但是dom-to-image-more這個庫實際上有一千多行代碼,那么它到底多做了些什么呢,點個關注,我們下一篇文章再見。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。