<!DOCTYPE html> <html> <head> <script src="https://unpkg.com/[email protected]/konva.min.js"></script> <meta charset="utf-8" /> <title>Konva Border Image Demo</title> <style> body { margin: 0; padding: 0; overflow: hidden; background-color: #f0f0f0; } </style> </head>
<body> <div id="container"></div> <script> var stage = new Konva.Stage({ container: 'container', width: window.innerWidth, height: window.innerHeight, });
var layer = new Konva.Layer(); stage.add(layer);
Konva.Image.fromURL('/assets/lion.png', function (image) { layer.add(image); image.setAttrs({ x: 80, y: 30, borderSize: 5, borderColor: 'red', });
image.filters([Border]); image.cache(); });
var canvas = document.createElement('canvas'); var tempCanvas = document.createElement('canvas');
function removeTransparency(canvas) { var ctx = canvas.getContext('2d');
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); var nPixels = imageData.data.length; for (var i = 3; i < nPixels; i += 4) { if (imageData.data[i] > 0) { imageData.data[i] = 255; } } ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.putImageData(imageData, 0, 0); return canvas; }
function Border(imageData) { var nPixels = imageData.data.length;
var size = this.getAttr('borderSize') || 0;
canvas.width = imageData.width; canvas.height = imageData.height;
tempCanvas.width = imageData.width; tempCanvas.height = imageData.height;
tempCanvas.getContext('2d').putImageData(imageData, 0, 0);
removeTransparency(tempCanvas);
var ctx = canvas.getContext('2d'); var color = this.getAttr('borderColor') || 'black';
ctx.save(); ctx.shadowColor = color; ctx.shadowBlur = size; ctx.drawImage(tempCanvas, 0, 0); ctx.restore();
var tempImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var SMOOTH_MIN_THRESHOLD = 3; var SMOOTH_MAX_THRESHOLD = 10;
let val, hasValue;
var offset = 3;
for (var i = 3; i < nPixels; i += 4) { if (imageData.data[i] === 255) { continue; }
val = tempImageData.data[i]; hasValue = val !== 0; if (!hasValue) { continue; } if (val > SMOOTH_MAX_THRESHOLD) { val = 255; } else if (val < SMOOTH_MIN_THRESHOLD) { val = 0; } else { val = ((val - SMOOTH_MIN_THRESHOLD) / (SMOOTH_MAX_THRESHOLD - SMOOTH_MIN_THRESHOLD)) * 255; } tempImageData.data[i] = val; }
ctx.putImageData(tempImageData, 0, 0);
ctx.save(); ctx.globalCompositeOperation = 'source-in'; ctx.fillStyle = color; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.restore();
var newImageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var indexesToProcess = []; for (var i = 3; i < nPixels; i += 4) { var hasTransparentOnTop = imageData.data[i - imageData.width * 4 * offset] === 0; var hasTransparentOnTopRight = imageData.data[i - (imageData.width * 4 + 4) * offset] === 0; var hasTransparentOnTopLeft = imageData.data[i - (imageData.width * 4 - 4) * offset] === 0; var hasTransparentOnRight = imageData.data[i + 4 * offset] === 0; var hasTransparentOnLeft = imageData.data[i - 4 * offset] === 0; var hasTransparentOnBottom = imageData.data[i + imageData.width * 4 * offset] === 0; var hasTransparentOnBottomRight = imageData.data[i + (imageData.width * 4 + 4) * offset] === 0; var hasTransparentOnBottomLeft = imageData.data[i + (imageData.width * 4 - 4) * offset] === 0; var hasTransparentAround = hasTransparentOnTop || hasTransparentOnRight || hasTransparentOnLeft || hasTransparentOnBottom || hasTransparentOnTopRight || hasTransparentOnTopLeft || hasTransparentOnBottomRight || hasTransparentOnBottomLeft;
if ( imageData.data[i] === 255 || (imageData.data[i] && !hasTransparentAround) ) { continue; } if (!newImageData.data[i]) { continue; } indexesToProcess.push(i); }
for (var index = 0; index < indexesToProcess.length; index += 1) { var i = indexesToProcess[index];
var alpha = imageData.data[i] / 255;
if (alpha > 0 && alpha < 1) { var aa = 1 + 1; } imageData.data[i] = newImageData.data[i]; imageData.data[i - 1] = newImageData.data[i - 1] * (1 - alpha) + imageData.data[i - 1] * alpha; imageData.data[i - 2] = newImageData.data[i - 2] * (1 - alpha) + imageData.data[i - 2] * alpha; imageData.data[i - 3] = newImageData.data[i - 3] * (1 - alpha) + imageData.data[i - 3] * alpha;
if (newImageData.data[i] < 255 && alpha > 0) { var bb = 1 + 1; } } } </script> </body> </html>
|