我可以将图像分割成几块,并控制每张图像的不透明度,必须有一定数量的块才能使整个动画流畅且吸引人.我想的另一种方法是使用画布,您可以在其中按像素操作图像,例如此页面建议,我可以做到// get the image data objectvar image = ctx.getImageData(0, 0, 500, 200);// get the image data values var imageData = image.data,length = imageData.length;// set every fourth value to 50for(var i=3; i < length; i+=4){ imageData[i] = 50;}// after the manipulation, reset the dataimage.data = imageData;// and put the imagedata back to the canvasctx.putImageData(image, 0, 0);但是,该页面仅显示静态图像,而不显示动画.我想知道如果使用这种方法是否会降低性能.而且,这种方法涉及很多丑陋的计算.我认为我想要实现的目标不是很奇怪,所以有没有任何JavaScript插件可以实现这一目标?解决方案 我要制作的动画可以通过视频编辑器轻松完成, 图像根本没有动.我希望它从一边到另一边出现在视频行业中,我们称其为软擦(又称软边擦),制作起来并不复杂.您所需要的只是一个可以使用线性渐变制作的Alpha蒙版.然后将翻译属性与上下文结合使用异或复合模式对其进行动画处理.异或模式的作用是根据绘制到其上的Alpha通道反转Alpha通道.这样做的好处是canvas元素也变得透明,因此任何背景都可以显示出来.您可以保留默认伴奏.模式也将使背景变黑.像这样进行渐变(颜色值与异或"模式无关,只是alpha通道值):var g = ctx.createLinearGradient(0, 0, ctx.canvas.width, 0);g.addColorStop(0, "rgba(0,0,0,0)");g.addColorStop(1, "rgba(0,0,0,1)");ctx.fillStyle = g;(请参阅 此答案 ,了解如何通过创建平滑渐变).现在创建一个基于位置t绘制完整框架的函数,该位置是与画布宽度结合的归一化值-请记住,我们需要使用双倍宽度:渐变+渐变退出的空间-function render(t) { var w = t * ctx.canvas.width; // width based on t ctx.drawImage(img, 0, 0); // render bg. image ctx.translate(-ctx.canvas.width + w, 0); // translate on x-axis ctx.fillRect(0, 0, ctx.canvas.width * 2, ctx.canvas.height); // render gradient mask}在动画循环中调用它直到t=2,但可以选择将globalCompositeOperation设置为xor,我们很好.动画循环本身将为我们重置转换:演示 var ctx = c.getContext("2d"), img = new Image, t = 0, step = 0.02// alpha maskvar g = ctx.createLinearGradient(0, 0, ctx.canvas.width, 0);g.addColorStop(0, "rgba(0,0,0,0)");g.addColorStop(1, "rgba(0,0,0,1)");ctx.fillStyle = g;ctx.globalCompositeOperation = "xor";// load bg imageimg.onload = animate;img.src = "http://i.imgur.com/d0tZU7n.png";function animate() { ctx.setTransform(1,0,0,1,0,0); // reset any transformations ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); render(t); t += step; if (t <= 2) requestAnimationFrame(animate); // 2 since we need double width else {t=0; setTimeout(animate, 2000)}; // just to repeat anim. for demo}function render(t) { var w = t * ctx.canvas.width; // width based on t ctx.drawImage(img, 0, 0); ctx.translate(-ctx.canvas.width + w, 0); // translate on x-axis ctx.fillRect(0, 0, ctx.canvas.width*2, ctx.canvas.height);} body {background:url(http://i.imgur.com/OT99vSA.jpg) repeat} <canvas width=658 height=325 id=c></canvas> Sorry if the title is confusing. I've tried my best to compose it, if you are going to understand what I am asking, feel free to suggest better title in comment.The animation I am trying to make can easily be done by video editors, but looks to me not so easy with CSS/JS: First of all, I am not talking about sliding in the image, the image is not moving at all. I want it to appear from side to side, but in a gradient transparent manner. Imagine there is a gradient opacity mask on the image, making the opacity of its left end to be 1, and that of its right end to be 0. When this mask moves from left right, it is the animation I wanna achieve.I can split the image to several pieces, and manipulate the opacity of each one, there has to be a certain amount pieces to make the whole animation smooth and appeal.The other way I am thinking is to use canvas, where you can manipulate the image by pixel, as this page suggests, I can do // get the image data objectvar image = ctx.getImageData(0, 0, 500, 200);// get the image data values var imageData = image.data,length = imageData.length;// set every fourth value to 50for(var i=3; i < length; i+=4){ imageData[i] = 50;}// after the manipulation, reset the dataimage.data = imageData;// and put the imagedata back to the canvasctx.putImageData(image, 0, 0);However the page is only taking about a static image but not animation. I am wondering whether it would undermine performance if I use this approach. Also, this approach involve a lot of ugly calculations.I think what I want to achieve is not very strange, so is there any javascript plugin to achieve this? 解决方案 The animation I am trying to make can easily be done by video editors, [...] the image is not moving at all. I want it to appear from side to sideIn the video industry we call this a soft-wipe (AKA soft edged wipe) and it's not too complicated to make.All you need is an alpha mask that you can make using a linear gradient. Then use translate properties with the context combined with xor composite mode to animate it.What xor mode does is to invert the alpha channel based on the alpha channel drawn to it. The advantage of this is that the canvas element get transparent as well, so any background can show through. You can keep the default comp. mode as well which will make the background black instead.The gradient is made like this (the color values does not matter with xor mode, just the alpha channel values):var g = ctx.createLinearGradient(0, 0, ctx.canvas.width, 0);g.addColorStop(0, "rgba(0,0,0,0)");g.addColorStop(1, "rgba(0,0,0,1)");ctx.fillStyle = g;(see this answer for how to avoid "bright line" artifacts by creating a smoothed gradient).Now create a function that draws a complete frame based on position t which is a normalized value combined with canvas width - have in mind we need the double width to work with: gradient + room for the gradient to exit -function render(t) { var w = t * ctx.canvas.width; // width based on t ctx.drawImage(img, 0, 0); // render bg. image ctx.translate(-ctx.canvas.width + w, 0); // translate on x-axis ctx.fillRect(0, 0, ctx.canvas.width * 2, ctx.canvas.height); // render gradient mask}Call this in an animation loop until t=2, but optionally set globalCompositeOperation to xor and we're good to go. The animation loop itself will reset transformation for us:Demovar ctx = c.getContext("2d"), img = new Image, t = 0, step = 0.02// alpha maskvar g = ctx.createLinearGradient(0, 0, ctx.canvas.width, 0);g.addColorStop(0, "rgba(0,0,0,0)");g.addColorStop(1, "rgba(0,0,0,1)");ctx.fillStyle = g;ctx.globalCompositeOperation = "xor";// load bg imageimg.onload = animate;img.src = "http://i.imgur.com/d0tZU7n.png";function animate() { ctx.setTransform(1,0,0,1,0,0); // reset any transformations ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); render(t); t += step; if (t <= 2) requestAnimationFrame(animate); // 2 since we need double width else {t=0; setTimeout(animate, 2000)}; // just to repeat anim. for demo}function render(t) { var w = t * ctx.canvas.width; // width based on t ctx.drawImage(img, 0, 0); ctx.translate(-ctx.canvas.width + w, 0); // translate on x-axis ctx.fillRect(0, 0, ctx.canvas.width*2, ctx.canvas.height);}body {background:url(http://i.imgur.com/OT99vSA.jpg) repeat}<canvas width=658 height=325 id=c></canvas> 这篇关于动画:使图像从一侧到另一侧(不透明)渐变出现(所谓的“软擦"效果)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-15 00:24