html画布图片不显示_使用HTML5画布从头开始显示

html画布图片不显示

I’ve previously demonstrated several “sliding” before-and-after comparators for images and video that track mouse movement from side to side. More precise “scratch-off” interfaces can be useful for comparing particular kinds of images, such as photos taken at different times in history, or comparing a sketch against a final product.

之前,我已经演示了几个“滑动式”前后比较器,用于图像和视频跟踪鼠标左右移动。 更精确的“刮擦”界面可用于比较特定种类的图像,例如历史上不同时间拍摄的照片,或将草图与最终产品进行比较。

Other examples I’ve found of this technique are rather complicated and over-coded, or have framework dependencies; by comparison, the code for this technique is relatively straightforward, and written in pure JavaScript.

我发现的其他有关此技术的示例相当复杂且编码过度,或者具有框架依赖性。 相比之下,该技术的代码相对简单,是用纯JavaScript编写的

In effect, the result is the same as my “scribble” SVG reveal technique, but interactive, rather than playing automatically. For this example, I’ve used Calgary’s Center Street bridge, which recently celebrated its 100th anniversary, with photographs taken 70 years apart, in 1943 and 2013. The code also demonstrates Retina background images, display density detection with JavaScript, and mouse / touch / button detection.

实际上,结果与我的“涂鸦” SVG显示技术相同 ,但是具有交互性,而不是自动播放。 在此示例中,我使用了卡尔加里的中央大街桥,该桥最近庆祝了其成立100周年,分别在1943年和2013年拍摄了70年的照片。该代码还演示了Retina背景图像,使用JavaScript进行显示密度检测以及鼠标/触摸/按钮检测。

图片和标记 (Images and Markup)

The comparison images must be the same size, or at least the same aspect ratio. The only markup is the <canvas>, with the pixel dimensions of the image(s).

比较图像必须具有相同的大小,或者至少具有相同的纵横比。 唯一的标记是<canvas> ,其中包含图像的像素尺寸。

<canvas id="bridge" width="750" height="465"></canvas>

To work well, the comparison images should be as close to each other as possible in perspective and size.

为使效果更好,比较图像的角度和大小应尽可能接近。

The “base” image - the one that will be revealed - is placed as the background of the <canvas> element:

“基本”图像-将要显示的图像-被放置为<canvas>元素背景

#bridge {
    display: block;
    margin: 0 auto;
    background-image: url('calgary-bridge-1943.jpg');
    background-image: -webkit-image-set(url('/calgary-bridge-1943.jpg') 1x, 
	url('calgary-bridge-1943-2x.jpg') 2x );
    background-size: cover;
    width: 100%;
    max-width: 750px;
    height: auto;
    cursor:  crosshair;
    cursor: url(circular-cursor.png) 53 53, crosshair;
}

The background uses image-set() to use the correct image for the display density on Webkit-derived browsers, and a custom cursor the size of the “brush” that will be used on the comparator.

后台使用image-set()为在Webkit衍生的浏览器上的显示密度使用正确的图像,并使用自定义cursorcursor的大小将在比较器上使用。

剧本 (The Script)

Placed at the bottom of the page, the script consists of several functions. It starts by setting the variables to be used:

该脚本位于页面底部,由几个功能组成。 首先设置要使用的变量

var bridge = document.getElementById("bridge"),
bridgeCanvas = bridge.getContext('2d'),
brushRadius = (bridge.width / 100) * 5,
img = new Image();
if (brushRadius < 50) { brushRadius = 50 }

The default brush radius is 5% of the width of the canvas, but we never want the radius to be less than 50px (approximately the size of the fingertip, on most displays).

默认的笔刷半径是画布宽度的5%,但是我们绝不希望半径小于50像素(在大多数显示器上,指尖的大小大约)。

img.onload = function(){  
    bridgeCanvas.drawImage(img, 0, 0, bridge.width, bridge.height);
}
img.loc = '';
img.filename = 'calgary-bridge-2013.jpg';
if (window.devicePixelRatio >= 2) {
    var nameParts = img.filename.split('.');
    img.src = img.loc + nameParts[0]+"-2x"+"."+nameParts[1];
} else {
    img.src = img.loc + img.filename;
}

The “cover” image is drawn on the canvas, over the background image. The image is determined from combining image.loc and the base filename; -2x is appended to the filename if the screen of the device is a Retina display.

“封面”图像绘制在画布上的背景图像上。 通过结合image.loc和基本文件名确定图像; 如果设备的屏幕是Retina显示屏,则将-2x附加到文件名中。

Detecting mousemove and touch on the <canvas> is achieved in two event listeners:

通过两个事件侦听器可以检测到mousemove和<canvas>上的触摸:

bridge.addEventListener("mousemove", function(e) {
    var brushPos = getBrushPos(e.clientX, e.clientY);
    var leftBut = detectLeftButton(e);
    if (leftBut == 1) {
        drawDot(brushPos.x, brushPos.y);
    }
}, false);

bridge.addEventListener("touchmove", function(e) {
    e.preventDefault();
    var touch = e.targetTouches[0];
    if (touch) {
        var brushPos = getBrushPos(touch.pageX, touch.pageY);
        drawDot(brushPos.x, brushPos.y);
    }
}, false);

Since the locations of touch and mouse movement are measured separately, the getBrushPos function is fed two different kinds of x and y position, rendering a result for the drawDot function.

由于触摸和鼠标移动的位置是分别测量的,因此getBrushPos函数被馈getBrushPos x和y两种不同位置,从而为drawDot函数提供了结果。

I wanted the “painting” action to be active, meaning that the left button on a mouse (or the equivalent on a trackpad) needs to be held down during the draw. Detecting the left mouse button is notoriously tricky, so I used this function to resolve it:

我希望“绘画”动作处于活动状态 ,这意味着在绘制过程中需要按住鼠标左键(或触控板上的等效键)。 众所周知,检测鼠标左键比较棘手,因此我使用此功能来解决它​​:

function detectLeftButton(event) {
    if ('buttons' in event) {
        return event.buttons === 1;
    } else if ('which' in event) {
        return event.which === 1;
    } else {
        return event.button === 1;
    }
}

Getting the touch location is also a little tricky, since the <canvas> is responsive:

获取触摸位置也有些棘手,因为<canvas>响应式的

function getBrushPos(xRef, yRef) {
    var bridgeRect = bridge.getBoundingClientRect();
    return {
      x: Math.floor((xRef - bridgeRect.left) / (bridgeRect.right - bridgeRect.left) * bridge.width),
      y: Math.floor((yRef - bridgeRect.top) / (bridgeRect.bottom - bridgeRect.top) * bridge.height)
    };
}

To expose the photograph underneath, a circular “dot” is drawn on the canvas with a globalCompositeOperation. Because of that, it’s not important what color the dot is filled with, only that it has a fill:

为了露出下面的照片,在画布上使用globalCompositeOperation绘制了一个圆形“点”。 因此,填充圆点的颜色并不重要,只需要填充即可:

function drawDot(mouseX,mouseY){
    bridgeCanvas.beginPath();
    bridgeCanvas.arc(mouseX, mouseY, brushRadius, 0, 2*Math.PI, true);
    bridgeCanvas.fillStyle = '#000';
    bridgeCanvas.globalCompositeOperation = "destination-out";
    bridgeCanvas.fill();
}

兼容性 (Compatibility)

This comparator works well in all modern browsers I’ve tested in. IE10 has an issue with scaling the <canvas> that needs further investigation, but it works very well in IE 11 and Edge.

该比较器在我测试过的所有现代浏览器中均能很好地工作。IE10在缩放<canvas> ,需要进一步研究,但在IE 11和Edge中却能很好地工作。

翻译自: https://thenewcode.com/1120/Scratch-Off-Reveal-with-HTML5-Canvas

html画布图片不显示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值