加入3.5 修复水印
This commit is contained in:
1 parent
ef01cdd6ee
commit
e82a62a9ad
19 files changed
+5894
-38
No files matched your search
@@ -45,12 +45,12 @@ function createRasterizer(context) {
|
||||
const position = gl.getAttribLocation(program, 'position'), uv = gl.getAttribLocation(program, 'uv');
|
||||
const resolution = gl.getUniformLocation(program, 'resolution'), opacity = gl.getUniformLocation(program, 'opacity');
|
||||
const textures = new Map();
|
||||
let coordinates = [], currentImage = null, currentAlpha = 1, transform;
|
||||
let coordinates = [], currentImage = null, currentAlpha = 1, currentMode = 'source-over', transform;
|
||||
let disposed = false, lost = false;
|
||||
canvas.addEventListener('webglcontextlost', event => { event.preventDefault(); lost = true; });
|
||||
function texture(image) {
|
||||
if (textures.has(image)) return textures.get(image);
|
||||
const t = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, t);
|
||||
if (textures.has(image) && image !== context.canvas) return textures.get(image);
|
||||
const t = textures.get(image) || gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, t);
|
||||
// Premultiply before interpolation so translucent edges do not darken.
|
||||
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
||||
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
||||
@@ -65,6 +65,12 @@ function createRasterizer(context) {
|
||||
if (!coordinates.length) return;
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture(currentImage));
|
||||
gl.uniform1f(opacity, currentAlpha);
|
||||
// Premultiplied RGB factors; keep source-over alpha independently.
|
||||
const factors = currentMode === 'lighter' ? [gl.ONE, gl.ONE]
|
||||
: currentMode === 'multiply' ? [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA]
|
||||
: currentMode === 'screen' ? [gl.ONE, gl.ONE_MINUS_SRC_COLOR]
|
||||
: [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
|
||||
gl.blendFuncSeparate(factors[0], factors[1], gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(coordinates), gl.STREAM_DRAW);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, coordinates.length / 4);
|
||||
coordinates.length = 0;
|
||||
@@ -84,11 +90,18 @@ function createRasterizer(context) {
|
||||
gl.uniform2f(resolution, canvas.width, canvas.height);
|
||||
gl.activeTexture(gl.TEXTURE0); gl.uniform1i(gl.getUniformLocation(program, 'image'), 0);
|
||||
gl.enable(gl.BLEND); gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
||||
// Seed the same framebuffer with the actual Canvas pixels (solid or
|
||||
// checkerboard background). CSS backgrounds cannot participate in blending.
|
||||
currentImage = target; currentAlpha = 1; currentMode = 'source-over';
|
||||
const w = canvas.width, h = canvas.height;
|
||||
coordinates.push(0,0,0,0, w,0,1,0, w,h,1,1, 0,0,0,0, w,h,1,1, 0,h,0,1);
|
||||
flush(); currentImage = null;
|
||||
return true;
|
||||
},
|
||||
triangle(image, x0, y0, u0, v0, x1, y1, u1, v1, x2, y2, u2, v2) {
|
||||
const alpha = context.globalAlpha;
|
||||
if (image !== currentImage || alpha !== currentAlpha) { flush(); currentImage = image; currentAlpha = alpha; }
|
||||
const mode = context.globalCompositeOperation || 'source-over';
|
||||
if (image !== currentImage || alpha !== currentAlpha || mode !== currentMode) { flush(); currentImage = image; currentAlpha = alpha; currentMode = mode; }
|
||||
const t = transform;
|
||||
coordinates.push(
|
||||
t.a * x0 + t.c * y0 + t.e, t.b * x0 + t.d * y0 + t.f, u0, v0,
|
||||
@@ -98,7 +111,7 @@ function createRasterizer(context) {
|
||||
end() {
|
||||
flush();
|
||||
context.save();
|
||||
try { context.setTransform(1, 0, 0, 1, 0, 0); context.globalAlpha = 1; context.drawImage(canvas, 0, 0); }
|
||||
try { context.setTransform(1, 0, 0, 1, 0, 0); context.globalAlpha = 1; context.globalCompositeOperation = 'copy'; context.drawImage(canvas, 0, 0); }
|
||||
finally { context.restore(); }
|
||||
},
|
||||
dispose() {
|
||||
|
||||
Reference in new issue
Block a user