Comparing version 0.3.1 to 0.4.0
{ | ||
"name": "karas", | ||
"version": "0.3.1", | ||
"version": "0.4.0", | ||
"description": "鸦", | ||
@@ -22,7 +22,8 @@ "maintainers": [ | ||
"dependencies": { | ||
"yurine": "~0.3.0", | ||
"selenite": "~0.3.2" | ||
"selenite": "~0.3.2", | ||
"yurine": "~0.3.0" | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "^7.4.3", | ||
"@babel/plugin-proposal-class-properties": "^7.5.5", | ||
"@babel/preset-env": "^7.4.3", | ||
@@ -29,0 +30,0 @@ "chromedriver": "^77.0.0", |
# karas(鸦) | ||
[![NPM version](https://badge.fury.io/js/karas.png)](https://npmjs.org/package/karas) | ||
[![Build Status](https://travis-ci.org/karasjs/karas.svg?branch=master)](https://travis-ci.org/karasjs/karas) | ||
## INSTALL | ||
``` | ||
npm install karas | ||
``` | ||
## 文档 | ||
https://github.com/karasjs/karas/wiki/%E6%96%87%E6%A1%A3 | ||
## API | ||
https://github.com/karasjs/karas/wiki/API | ||
## Demo | ||
* demo目录下是一个web端的演示教程示例,可直接本地预览 | ||
* 依赖的`csx`翻译工具来自于`yurine`:https://github.com/karasjs/yurine [![NPM version](https://badge.fury.io/js/yurine.png)](https://npmjs.org/package/yurine) | ||
* 依赖的`cssx`翻译工具来自于`selenite`:https://github.com/karasjs/selenite [![NPM version](https://badge.fury.io/js/selenite.png)](https://npmjs.org/package/selenite) | ||
* 在线预览:http://army8735.me/karasjs/karas/demo/ | ||
# License | ||
[MIT License] |
@@ -52,4 +52,3 @@ import Event from '../util/Event'; | ||
this.__init(true); | ||
this.root.refresh(); | ||
cb && cb(); | ||
this.root.refreshTask(cb); | ||
} | ||
@@ -73,3 +72,3 @@ | ||
sr.__renderMode = renderMode; | ||
sr.__measure(); | ||
sr.__style = this.props.style || {}; | ||
this.__shadowRoot = sr; | ||
@@ -101,2 +100,3 @@ return; | ||
css.normalize(sr.style); | ||
sr.__measure(); | ||
} | ||
@@ -103,0 +103,0 @@ else { |
@@ -33,2 +33,4 @@ import css from '../style/css'; | ||
['font-family', style.fontFamily], | ||
['font-weight', style.fontWeight], | ||
['font-style', style.fontStyle], | ||
['font-size', `${style.fontSize}px`] | ||
@@ -35,0 +37,0 @@ ], |
@@ -7,2 +7,4 @@ import Dom from '../node/Dom'; | ||
import unit from '../style/unit'; | ||
import inject from '../util/inject'; | ||
import Event from '../util/Event'; | ||
@@ -45,4 +47,6 @@ function getDom(dom) { | ||
this.__node = null; // 真实DOM引用 | ||
this.__mw = 0; | ||
this.__mw = 0; // 记录最大宽高,防止尺寸变化清除不完全 | ||
this.__mh = 0; | ||
this.__task = []; | ||
Event.mix(this); | ||
} | ||
@@ -166,3 +170,4 @@ | ||
} | ||
this.__traverse(this.__ctx, this.__defs, this.__renderMode); | ||
let { renderMode, ctx } = this; | ||
this.__traverse(ctx, this.__defs, renderMode); | ||
this.__traverseCss(this, this.props.css); | ||
@@ -179,3 +184,3 @@ this.__init(); | ||
refresh() { | ||
refresh(cb) { | ||
let { renderMode, style } = this; | ||
@@ -190,28 +195,48 @@ style.width = { | ||
}; | ||
this.__layout({ | ||
x: 0, | ||
y: 0, | ||
w: this.width, | ||
h: this.height, | ||
inject.measureText(() => { | ||
this.__layout({ | ||
x: 0, | ||
y: 0, | ||
w: this.width, | ||
h: this.height, | ||
}); | ||
this.__layoutAbs(this); | ||
if(renderMode === mode.CANVAS) { | ||
// 可能会调整宽高,所以每次清除用最大值 | ||
this.__mw = Math.max(this.__mw, this.width); | ||
this.__mh = Math.max(this.__mh, this.height); | ||
this.__ctx.clearRect(0, 0, this.__mw, this.__mh); | ||
} | ||
this.render(renderMode); | ||
if(renderMode === mode.SVG) { | ||
let nvd = this.virtualDom; | ||
let nd = this.__defs; | ||
nvd.defs = nd.value; | ||
nvd = util.clone(nvd); | ||
if(this.node.__karasInit) { | ||
diff(this.node, this.node.__ovd, nvd); | ||
} | ||
else { | ||
this.node.innerHTML = util.joinVirtualDom(nvd); | ||
} | ||
this.node.__ovd = nvd; | ||
} | ||
cb && cb(); | ||
this.emit('refresh'); | ||
}); | ||
this.__layoutAbs(this); | ||
if(renderMode === mode.CANVAS) { | ||
// 可能会调整宽高,所以每次清除用最大值 | ||
this.__mw = Math.max(this.__mw, this.width); | ||
this.__mh = Math.max(this.__mh, this.height); | ||
this.__ctx.clearRect(0, 0, this.__mw, this.__mh); | ||
} | ||
refreshTask(cb) { | ||
let { task } = this; | ||
if(!task.length) { | ||
setTimeout(() => { | ||
this.refresh(() => { | ||
task.forEach(cb => { | ||
cb && cb(); | ||
}); | ||
task.splice(0); | ||
}); | ||
}, 1); | ||
} | ||
this.render(renderMode); | ||
if(renderMode === mode.SVG) { | ||
let nvd = this.virtualDom; | ||
let nd = this.__defs; | ||
nvd.defs = nd.value; | ||
nvd = util.clone(nvd); | ||
if(this.node.__karasInit) { | ||
diff(this.node, this.node.__ovd, nvd); | ||
} else { | ||
this.node.innerHTML = util.joinVirtualDom(nvd); | ||
} | ||
this.node.__ovd = nvd; | ||
} | ||
task.push(cb); | ||
} | ||
@@ -237,4 +262,7 @@ | ||
} | ||
get task() { | ||
return this.__task; | ||
} | ||
} | ||
export default Root; |
@@ -18,5 +18,10 @@ import Node from './Node'; | ||
static CHAR_WIDTH_CACHE = {}; | ||
static MEASURE_TEXT = { | ||
list: [], | ||
data: {}, | ||
}; | ||
// 预先计算每个字的宽度 | ||
__measure() { | ||
this.__charWidthList = []; | ||
let { ctx, content, style, charWidthList, renderMode } = this; | ||
@@ -26,6 +31,13 @@ if(renderMode === mode.CANVAS) { | ||
} | ||
let cache = CHAR_WIDTH_CACHE[style.fontSize] = CHAR_WIDTH_CACHE[style.fontSize] || {}; | ||
let length = content.length; | ||
let key = style.fontSize + ',' + style.fontFamily; | ||
let wait = Text.MEASURE_TEXT.data[key] = Text.MEASURE_TEXT.data[key] || { | ||
key, | ||
style, | ||
hash: {}, | ||
s: [], | ||
}; | ||
let cache = Text.CHAR_WIDTH_CACHE[key] = Text.CHAR_WIDTH_CACHE[key] || {}; | ||
let sum = 0; | ||
for(let i = 0; i < length; i++) { | ||
let needMeasure = false; | ||
for(let i = 0, length = content.length; i < length; i++) { | ||
let char = content.charAt(i); | ||
@@ -35,16 +47,42 @@ let mw; | ||
mw = cache[char]; | ||
charWidthList.push(mw); | ||
sum += mw; | ||
this.__charWidth = Math.max(this.charWidth, mw); | ||
} | ||
else if(renderMode === mode.CANVAS) { | ||
mw = cache[char] = ctx.measureText(char).width; | ||
charWidthList.push(mw); | ||
sum += mw; | ||
this.__charWidth = Math.max(this.charWidth, mw); | ||
} | ||
else if(renderMode === mode.SVG) { | ||
mw = cache[char] = mode.measure(char, style); | ||
else { | ||
if(!wait.hash.hasOwnProperty(char)) { | ||
wait.s += char; | ||
} | ||
// 先预存标识位-1,测量完后替换它 | ||
charWidthList.push(-1); | ||
needMeasure = true; | ||
} | ||
charWidthList.push(mw); | ||
sum += mw; | ||
this.__charWidth = Math.max(this.charWidth, mw); | ||
} | ||
this.__textWidth = sum; | ||
if(needMeasure) { | ||
Text.MEASURE_TEXT.list.push(this); | ||
} | ||
} | ||
__measureCb() { | ||
let { content, style, charWidthList } = this; | ||
let key = style.fontSize + ',' + style.fontFamily; | ||
let cache = Text.CHAR_WIDTH_CACHE[key]; | ||
let sum = 0; | ||
for(let i = 0, len = charWidthList.length; i < len; i++) { | ||
if(charWidthList[i] < 0) { | ||
let mw = charWidthList[i] = cache[content.charAt(i)]; | ||
sum += mw; | ||
this.__charWidth = Math.max(this.charWidth, mw); | ||
} | ||
} | ||
this.__textWidth += sum; | ||
} | ||
__layout(data, isVirtual) { | ||
@@ -101,2 +139,3 @@ let { x, y, w, h } = data; | ||
this.__height = y - data.y; | ||
// flex前置计算无需真正布局 | ||
if(isVirtual) { | ||
@@ -103,0 +142,0 @@ this.__lineBoxes = []; |
@@ -339,3 +339,2 @@ import unit from './unit'; | ||
let { fontStyle, fontWeight, fontSize, fontFamily } = style; | ||
fontFamily = 'arial'; | ||
return `${fontStyle} ${fontWeight} ${fontSize}px/${fontSize}px ${fontFamily}`; | ||
@@ -342,0 +341,0 @@ } |
const CANVAS = 0; | ||
const SVG = 1; | ||
let div; | ||
export default { | ||
CANVAS, | ||
SVG, | ||
measure(s, style) { | ||
if(!div) { | ||
div = document.createElement('div'); | ||
div.style.position = 'absolute'; | ||
div.style.left = '99999px'; | ||
div.style.top = '-99999px'; | ||
div.style.visibility = 'hidden'; | ||
document.body.appendChild(div); | ||
} | ||
div.style.fontSize = style.fontSize + 'px'; | ||
div.style.fontFamily = style.fontFamily; | ||
div.innerText = s; | ||
let css = window.getComputedStyle(div, null); | ||
return parseFloat(css.width); | ||
} | ||
}; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
760775
38
12364
25
14