首页
Search
1
解决visual studio code (vscode)安装时没有选择安装路径问题
138 阅读
2
Linux 下 Bash 脚本 bad interpreter 报错的解决方法
131 阅读
3
Arch Linux 下解决 KDE Plasma Discover 的 Unable to load applications 错误
107 阅读
4
如何在 Clash for Windows 上配置服务
77 阅读
5
Uniapp如何引入自定义样式文件
75 阅读
clash
服务器
javascript
全部
游戏资讯
登录
Search
加速器之家
累计撰写
1,061
篇文章
累计收到
0
条评论
首页
栏目
clash
服务器
javascript
全部
游戏资讯
页面
搜索到
624
篇与
的结果
2024-08-24
SVG Symbol 和 Sprite 的好处和坑
SVG Symbol用 Symbol 来把 SVG 合并到一个文件几乎是现在最流行的用法。Symbol 好处方便利用 ID 来取图案,所以不用各种计算,可以随便放。反复利用这应该是一个不太容易发现的好处,你可以在文件内部继续用来做图案的各种版本。这样 SVG 的优势更加明显,节省了好多空间。比如这个博客里用到的社交图案,原本的是只有图案本身。例如这是 Codepen 的图案: codepen 现在直接在文章里: 就是这个效果: 在symbol-defs.svg里还有它的另外一个版本,带圆圈的,只需要添加几行就可以: codepen 同样的使用方式,既环保又方便: Symbol 坏处不完全支持这种方式并不完全支持 SVG 的各种特性。比如我开始就踩到了一个坑。我的 LOGO 里使用了clippath,使用这种方式就会失去效果。这个貌似是个陈年老 bug 来的。解决方式就是利用工具合并路径,最好还压缩成一条,方便管理。编辑工具推荐 Boxy SVG,生成的代码非常轻盈,而且尽可能保留原来的样子,不会像 Illustrator 一样源码面目全非。压缩工具推荐 SVGOMG!,号称 SVGO's Missing GUI。奇怪的宽高在宽和高是百分比的情况下,会出现跟或者普通不一样的计算。有时高空出一段,有时宽空出一段。这个我纠结了很久,没有找到原因。我猜是受到原本整个 SVG 的影响。解决方法是用相同宽高比的父来限制;或者不用百分比。慢因为零部件是可以的,所以引擎不能像图片一样直接解析完就一整块到处扔。虽然这个延时非常的小,一般几乎感觉不到,但是如果像这个博客左边的菜单栏一样(电脑上),在每个页面都是同样的元素,那么切换页面的时候就可以肉眼感受到图案的闪动。这种情况就只能放弃使用 Symbol。可以考虑单独一张 SVG 图片或者::point_down:SVG SpriteSVG Sprite 与以前的 PNG Sprite 一样,把图案按一定方式平铺到一张大图片上。Sprite 好处对齐SVG 不受大小限制,所以 Sprite 可以按统一的规格排列。取的时候也不受大小限制,利用百分比来取。比如这个博客左边菜单的图案就是 SVG Sprite,利用 Sass 自动计算百分比。快这种方式与普通图片一样肉眼看不到延时,而且还结合了 SVG 不受大小限制的优势。Sprite 坏处添加麻烦图案受位置影响,当然没有 Symbol 方法来得方便。因为需要快速显示的图案不多,我是利用 Boxy SVG 一个一个添加的。不太用心的查过一下,没注意到有合适的自动化工具。能用 Symbol 的当然优先使用 Symbol 方法,所以 Sprite 用的也不多,手动添加可以满足。有误差使用百分比因为受小数影响,图案会有1px浮动,当然这个1px是根据图案当前大小得出的,所以越小图案浮动的位置越大。解决方法有两个,一是避免产生小数,按倍数来设置图案大小;二是按图案最小的情况计算出血,把图案缩小空出足够位置。
2024年08月24日
2 阅读
0 评论
0 点赞
2024-08-24
在 Hexo 博客上使用 Emoji
(🚨 本博客已换用其它技术栈,Github Emoji 在 Hexo 上的效果见 2018 版)Emoji 都要出电影了,博客怎么能不用。奇怪的是 hexo 上只有一个插件,要在文中添加 tag,还不支持 hexo3 。我不太喜欢在 markdown 里加各种 tag,所以就打算自己再写个插件。Github 对 emoji 的支持就很好,所以去观摩了一下。它在生成网页的时候将关键字替换成 emoji 的 unicode 字符,然后再利用 JavaScript 将字符替换成图片,这样即使图片加载失败还有字符 fallback。于是就参考这种方式写了 hexo-filter-github-emojis :tada:。用法与 Github 一样,效果还不错吧 :smile:。:speedboat::tropical_fish: :octopus::dolphin::fish: "He touched the butt!"
2024年08月24日
4 阅读
0 评论
0 点赞
2024-08-24
Progressive background-image With Ease
Everyone likes smooth loading. Lately I tried to make the background-image of the menu to load progressively(also to the cover if you view the blog on mobile).If you take a look at how Medium does progressive image loading(or check out this article), you'll notice that they use JavaScript and canvas to blur and store thumbnails. It seems a bit overkill to me. And when you need to do it on a background-image with background-position, things become even more complicated.So I needed to figure out a simpler solution. Here's what I came up with:Blur by defaultAs the article above mentioned:By default, when a browser renders a small image scaled up, it applies a light blur effect to smooth the artefacts of the image. The effect can also be turned off for images like QR codes.But the default blur effect still feels blocky.To make it smoother, I applied blur effect to the thumbnails while generating them, using GraphicsMagick for node:const gm = require('gm') gm(coverPath) .resize(30) // or .resize(null, 30) for portrait .blur(5) .noProfile() .write(thumbnailPath, function (err) { if (err) { console.warn(err) } // ... }) // or to base64 gm(coverPath) .resize(30) // or .resize(null, 30) for portrait .blur(5) .noProfile() .toBuffer(function (err, buffer) { if (err) { console.warn(err) } var base64 = 'data:image/' + ext + ';base64,' + buffer.toString('base64') // ... })This looks acceptable to me. No need for a canvas or blur function. Already felt relieved! :smile:LayersThis method divides a component into four layers: container, thumbnail, mask and content. Container holds the full-size background image. Thumbnail holds the blur thumbnail, as background-image. Mask is a translucent black element, to darken the background. Everything else lives in the content layer. Use z-index to separate the layers.Image onloadWhen full-size image is loaded, hide the thumbnail. You can use this technic(with jQuery/Zepto):var $container = $('.container') // Matchs the "url(...)" var bigBgSrc = $container.css('background-image').match(/url\((.+?)\)/i) if (bigBgSrc) { // Removes quotations bigBgSrc = bigBgSrc[1].replace(/'|"/g, '') $('') .on('load', function () { $container.find('.thumbnail') .addClass('thumbnail--hide') // Hides thumbnail }) .prop('src', bigBgSrc) }A live example:No-jsNo-js support is extremely easy. Just hide the thumbnail.html.no-js .thumbnail { display: none !important; }For my blog I also made a Sass Mixin/Extend with this method.
2024年08月24日
5 阅读
0 评论
0 点赞
2024-08-24
新年新博客!
新博客终于写完啦!给心血们搬了个漂漂亮亮的新家。关于这个博客 :point_left:。
2024年08月24日
4 阅读
0 评论
0 点赞
2024-08-24
获取 DOM 里所有图片(包括背景和iframe)
在写浏览器扩展什么的时候可能会用上。获取 DOM 里的图片主要是在这几个地方里面找: 元素, background-image CSS 属性和 。img如果只想获取 的图片,有两种方式:直接获取所有 img 标签:function getImgs (doc) { return Array.from(doc.getElementsByTagName('img')) .map(img => ({ src: img.currentSrc, // 用 img.src 如果要本来的 src width: img.naturalWidth, height: img.naturalHeight })) } getImgs(document)还可以用 document.images:function getImgs (doc) { return Array.from(doc.images) .map(img => ({ src: img.currentSrc, // img.src if you want the origin width: img.naturalWidth, height: img.naturalHeight })) } getImgs(document)background-image获得背景图片需要查看所有 DOM 节点的 background-image 属性:function getBgImgs (doc) { const srcChecker = /url\(\s*?['"]?\s*?(\S+?)\s*?["']?\s*?\)/i return Array.from( Array.from(doc.querySelectorAll('*')) .reduce((collection, node) => { let prop = window.getComputedStyle(node, null) .getPropertyValue('background-image') // match `url(...)` let match = srcChecker.exec(prop) if (match) { collection.add(match[1]) } return collection }, new Set()) ) } getBgImgs(document)背景图片不能直接得到尺寸信息,如果需要的话要加载一遍。因为搜集的图片很有可能已经在浏览器缓存里,所以加载过程应该很快。function loadImg (src, timeout = 500) { var imgPromise = new Promise((resolve, reject) => { let img = new Image() img.onload = () => { resolve({ src: src, width: img.naturalWidth, height: img.naturalHeight }) } img.onerror = reject img.src = src }) var timer = new Promise((resolve, reject) => { setTimeout(reject, timeout) }) return Promise.race([imgPromise, timer]) } function loadImgAll (imgList, timeout = 500) { return new Promise((resolve, reject) => { Promise.all( imgList .map(src => loadImg(src, timeout)) .map(p => p.catch(e => false)) ).then(results => resolve(results.filter(r => r))) }) } loadImgAll(getBgImgs(document)).then(imgs => console.log(imgs))iframe只需要递归遍历 iframe 的 documentfunction searchIframes (doc) { var imgList = [] doc.querySelectorAll('iframe') .forEach(iframe => { try { iframeDoc = iframe.contentDocument || iframe.contentWindow.document imgList = imgList.concat(getImgs(iframeDoc) || []) // or getBgImgs(iframeDoc) imgList = imgList.concat(searchIframes(iframeDoc) || []) } catch (e) { // 直接忽略错误的 iframe (e.g. cross-origin) } }) return imgList } searchIframes(document)整合一起直接使用就行。function getImgAll (doc) { return new Promise((resolve, reject) => { loadImgAll(Array.from(searchDOM(doc))) .then(resolve, reject) }) function searchDOM (doc) { const srcChecker = /url\(\s*?['"]?\s*?(\S+?)\s*?["']?\s*?\)/i return Array.from(doc.querySelectorAll('*')) .reduce((collection, node) => { // bg src let prop = window.getComputedStyle(node, null) .getPropertyValue('background-image') // match `url(...)` let match = srcChecker.exec(prop) if (match) { collection.add(match[1]) } if (/^img$/i.test(node.tagName)) { // src from img tag collection.add(node.src) } else if (/^frame$/i.test(node.tagName)) { // iframe try { searchDOM(node.contentDocument || node.contentWindow.document) .forEach(img => { if (img) { collection.add(img) } }) } catch (e) {} } return collection }, new Set()) } function loadImg (src, timeout = 500) { var imgPromise = new Promise((resolve, reject) => { let img = new Image() img.onload = () => { resolve({ src: src, width: img.naturalWidth, height: img.naturalHeight }) } img.onerror = reject img.src = src }) var timer = new Promise((resolve, reject) => { setTimeout(reject, timeout) }) return Promise.race([imgPromise, timer]) } function loadImgAll (imgList, timeout = 500) { return new Promise((resolve, reject) => { Promise.all( imgList .map(src => loadImg(src, timeout)) .map(p => p.catch(e => false)) ).then(results => resolve(results.filter(r => r))) }) } } getImgAll(document).then(list => console.log(list))如果是开发 Chrome 插件则不受跨域影响,可以直接使用 probe-image-size,它支持 timeout 参数,就不需要自己写 timer 了。我在写一个 Chrome 扩展时用上了,很方便。
2024年08月24日
4 阅读
0 评论
0 点赞
1
...
59
60
61
...
125