Skip to content

Commit

Permalink
feat: #1 代码块样式优化-图片背景自动透明
Browse files Browse the repository at this point in the history
  • Loading branch information
terwer committed Mar 2, 2023
1 parent ebc668f commit cf377a8
Show file tree
Hide file tree
Showing 10 changed files with 373 additions and 23 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

- 字体样式美化,以 `落霞孤鹜``Times New Roman` 为主
- 代码块美化,类似 `Mac` 窗口风格
- 文档图片背景自动透明

- 整合热门挂件以及其他小工具,提供统一的入口
- 天生支持插件系统,插件系统由社区开发者提供支持
Expand Down Expand Up @@ -62,6 +63,12 @@ npm publish --dry-run
# 发布到仓库
npm publish
```
## 挂载的window对象

```bash
# translucify
window.translucify($('img'));
```

## 项目结构

Expand Down
36 changes: 36 additions & 0 deletions public/lib/vendor/translucify/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2023, Terwer . All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Terwer designates this
* particular file as subject to the "Classpath" exception as provided
* by Terwer in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Terwer, Shenzhen, Guangdong, China, youweics@163.com
* or visit www.terwer.space if you need additional information or have any
* questions.
*/

const initTranslucify = () => {
return [
"/appearance/themes/zhi/dist-cjs/lib/vendor/translucify/translucify.js",
]
}

const translucify = {
initTranslucify,
}

module.exports = translucify
250 changes: 250 additions & 0 deletions public/lib/vendor/translucify/translucify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
/*
* Copyright (c) 2023, Terwer . All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Terwer designates this
* particular file as subject to the "Classpath" exception as provided
* by Terwer in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Terwer, Shenzhen, Guangdong, China, youweics@163.com
* or visit www.terwer.space if you need additional information or have any
* questions.
*/

/**
* Translucify
* jim.yang@thisplace.com
* 20/4/2015
*/

;(function () {
var DEFAULT_TOLERANCE_VALUE = 0.05

// Tolerance threshold for flood fill.
var _toleranceValue = DEFAULT_TOLERANCE_VALUE

/**
* @param {HTMLImageElement} image
* @returns {boolean}
*/
function isImageLoaded(image) {
if (
image.nodeType === 1 &&
image.tagName.toLowerCase() === "img" &&
image.src !== ""
) {
return (
image.complete ||
image.readyState === 4 ||
image.naturalWidth + image.naturalHeight > 0
)
} else {
return false
}
}

/**
* Generates a set of <canvas>, <img> which is untainted by Cross-Origin image data.
* @param {HTMLImageElement} image
* @returns {{canvas: HTMLCanvasElement, imageCORS: HTMLImageElement}}
*/
function getCanvasAndCORSImage(image) {
/*
Get CORS image without triggering security exceptions
which occur when accessing pixel data even on an image
with response header 'Access-Control-Allow-Origin: *'
*/
var imageCORS = new Image()
imageCORS.crossOrigin = "use-credentials"

var canvas = document.createElement("canvas")

var w = image.naturalWidth
var h = image.naturalHeight

canvas.width = w
canvas.height = h

return {
canvas: canvas,
imageCORS: imageCORS,
}
}

/**
* @param {HTMLImageElement} image
*/
function modifyImagePixels(image) {
var created = getCanvasAndCORSImage(image)
created.imageCORS.onload = function () {
applyFloodFill(image, created.imageCORS, created.canvas)
}
created.imageCORS.src = image.src

// Apply filter immediately if imageCORS is loaded from cache
// and doesn't fire the load event.
if (isImageLoaded(created.imageCORS)) {
applyFloodFill(image, created.imageCORS, created.canvas)
}
}

/**
* @param {number} x
* @param {number} y
* @param {CanvasRenderingContext2D} context
* @param {number} tolerance
*/
function floodFill(x, y, context, tolerance) {
var pixelStack = [[x, y]]
var width = context.canvas.width
var height = context.canvas.height
var pixelPos = (y * width + x) * 4
var imageData = context.getImageData(0, 0, width, height)

var rMax = imageData.data[pixelPos] * (1 + tolerance)
var gMax = imageData.data[pixelPos + 1] * (1 + tolerance)
var bMax = imageData.data[pixelPos + 2] * (1 + tolerance)

var rMin = imageData.data[pixelPos] * (1 - tolerance)
var gMin = imageData.data[pixelPos + 1] * (1 - tolerance)
var bMin = imageData.data[pixelPos + 2] * (1 - tolerance)

/**
* Returns true if within tolerance bounds of flood-fill origin.
* @param pixelIndex
* @returns {boolean}
*/
function matchTolerance(pixelIndex) {
var r = imageData.data[pixelIndex]
var g = imageData.data[pixelIndex + 1]
var b = imageData.data[pixelIndex + 2]

return (
r >= rMin &&
r <= rMax &&
g >= gMin &&
g <= gMax &&
b >= bMin &&
b <= bMax
)
}

while (pixelStack.length) {
var newPos = pixelStack.pop()
x = newPos[0]
y = newPos[1]
pixelPos = (y * width + x) * 4
while (y-- >= 0 && matchTolerance(pixelPos)) {
pixelPos -= width * 4
}
pixelPos += width * 4
++y
var reachLeft = false
var reachRight = false
while (y++ < height - 1 && matchTolerance(pixelPos)) {
imageData.data[pixelPos] = 0
imageData.data[pixelPos + 1] = 0
imageData.data[pixelPos + 2] = 0
imageData.data[pixelPos + 3] = 0

if (x > 0) {
if (matchTolerance(pixelPos - 4)) {
if (!reachLeft) {
pixelStack.push([x - 1, y])
reachLeft = true
}
} else if (reachLeft) {
reachLeft = false
}
}
if (x < width - 1) {
if (matchTolerance(pixelPos + 4)) {
if (!reachRight) {
pixelStack.push([x + 1, y])
reachRight = true
}
} else if (matchTolerance(pixelPos + 4 - width * 4)) {
if (!reachLeft) {
pixelStack.push([x + 1, y - 1])
reachLeft = true
}
} else if (reachRight) {
reachRight = false
}
}
pixelPos += width * 4
}
}
context.putImageData(imageData, 0, 0)
}

/**
* Flood-fill from (0,0).
* @param {HTMLImageElement} originalImage
* @param {HTMLImageElement} imageCORS
* @param {HTMLCanvasElement} canvas
*/
function applyFloodFill(originalImage, imageCORS, canvas) {
var ctx = canvas.getContext("2d")
ctx.drawImage(imageCORS, 0, 0)
floodFill(0, 0, ctx, _toleranceValue)
if (originalImage.parentNode) {
originalImage.parentNode.insertBefore(canvas, originalImage)
originalImage.parentNode.removeChild(originalImage)
}
}

function translucifyOneFloodFill(image) {
if (isImageLoaded(image)) {
modifyImagePixels(image)
} else {
image.onload = function () {
modifyImagePixels(image)
}
}
}

/**
* Translucifies one HTMLImageElement or a set of them via NodeList.
* Specifies which modifier to use.
* @param {HTMLImageElement | NodeList | jQuery} queryResult
* @param {number} [tolerance]
*/
function translucifyAll(queryResult, tolerance) {
if (typeof tolerance !== "undefined") {
_toleranceValue = tolerance
} else {
_toleranceValue = DEFAULT_TOLERANCE_VALUE
}

if (queryResult instanceof HTMLImageElement) {
// <img> passed in directly
translucifyOneFloodFill(queryResult)
} else if (queryResult instanceof NodeList) {
// document.querySelectorAll support
Array.prototype.slice.call(queryResult).forEach(translucifyOneFloodFill)
} else {
// jQuery object support
if (queryResult && queryResult.toArray) {
queryResult.toArray().forEach(translucifyOneFloodFill)
}
}
}
window.translucify = translucifyAll

setTimeout(function () {
window.translucify(document.querySelectorAll("img"))
}, 1000)
})()
2 changes: 0 additions & 2 deletions script/cjs.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@

scriptutils.rm_folder("./dist-cjs")
os.system("tsc && vite build -c vite.cjs.config.ts --outDir dist-cjs")
scriptutils.rm_folder("./dist-cjs/fonts")
scriptutils.rm_folder("./dist-cjs/lib")
scriptutils.rm_file("./dist-cjs/vite.svg")
print("cjs构建完成.")

2 changes: 2 additions & 0 deletions script/esm.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@

scriptutils.rm_folder("./dist")
os.system("tsc && vite build")
scriptutils.rm_folder("./dist/lib")

print("esm构建完成.")
13 changes: 12 additions & 1 deletion src/apps/zhi/Lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ class Lifecycle {

const pluginSystemImports = this.loadPluginSystem()
const widgetsImports = this.loadWidgets()
const vendorImports = this.loadVendors()

this._dynamicImports = allImports
.concat(pluginSystemImports)
.concat(widgetsImports)
.concat(vendorImports)
}

/**
Expand All @@ -64,7 +66,16 @@ class Lifecycle {
* @private
*/
private loadWidgets(): string[] {
return loadOtherlib.loadPostPublisherScript()
return loadOtherlib.loadWidgetsScript()
}

/**
* 加载第三方库
*
* @private
*/
private loadVendors(): string[] {
return loadOtherlib.loadVendorsScript()
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/apps/zhi/zhi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import strUtil from "~/src/utils/strUtil"
import { version } from "~/package.json"
import ThemeFromEnum from "~/src/utils/enums/themeFromEnum"
import { Bootstrap } from "~/src/apps/zhi/bootstrap"

/**
* 主题入口
Expand All @@ -36,9 +37,8 @@ import ThemeFromEnum from "~/src/utils/enums/themeFromEnum"
class Zhi {
public async main(args: string[], callback: Function) {
this.hello(ThemeFromEnum.ThemeFrom_Siyuan)
// const dynamicImports = await Bootstrap.start()
// callback(dynamicImports)
callback([])
const dynamicImports = await Bootstrap.start()
callback(dynamicImports)
}

public hello(from: string): void {
Expand Down
Loading

0 comments on commit cf377a8

Please sign in to comment.