I've added javascript to my product page to show a birthday card opening effect.
pressing a button to open the card causes the page to refresh.
I've included four files below.
- card.css
- card.js
- ProductTemplateCustom.Simple.cshtml
- _CardProductDetailsPictures.cshtml
--card.css
@import url(https://fonts.googleapis.com/css?family=Nobile:400italic,700italic);
@import url(https://fonts.googleapis.com/css?family=Dancing+Script);
* {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
body {
background: #fff;
//background-image: url("/gray-floral.png");
padding: 50px;
}
#card-front {
//color: #FFDFDF;
}
#card, #card-front, #card-inside {
height: 490px;
}
.wrap {
padding: 1.5em 2.5em;
height: 100%;
}
#card-front, #card-inside {
width: 50%;
-webkit-box-shadow: 2px 2px 30px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .5);
-moz-box-shadow: 2px 2px 30px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .5);
box-shadow: 2px 2px 30px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .5);
position: absolute;
left: 50%;
}
#card-inside .wrap {
background: #FFEFEF;
-webkit-box-shadow: inset 2px 0 1px rgba(0, 0, 0, .05);
-moz-box-shadow: inset 2px 0 1px rgba(0, 0, 0, .05);
box-shadow: inset 2px 0 1px rgba(0, 0, 0, .05);
}
#card {
max-width: 960px;
width: 700px;
margin: 0 auto;
transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
perspective: 5000px;
-moz-perspective: 5000px;
-webkit-perspective: 5000px;
position: relative;
}
#card h1 {
text-align: center;
font-family: 'Nobile', sans-serif;
font-style: italic;
font-size: 70px;
text-shadow: 4px 4px 0px rgba(0, 0, 0, .15), 1px 1px 0 rgba(255, 200, 200, 255), 2px 2px 0 rgba(255, 150, 150, 255), 3px 3px 0 rgba(255, 125, 125, 255);
color: #FFF;
}
#card-inside {
font-size: 1.1em;
line-height: 1.4;
font-family: 'Nobile';
color: #331717;
font-style: italic;
}
p {
margin-top: 1em;
}
p:first-child {
margin-top: 0;
}
p.signed {
margin-top: 1.5em;
text-align: center;
font-family: 'Dancing Script', sans-serif;
font-size: 1.5em;
}
#card-front {
background-color: #FF5555;
//background-image: url("/images/cards/HappyBirthdayGumball.PNG");
background-size: 350px;
background-repeat: no-repeat;
//background-image: linear-gradient(top, #FF5555 0%, #FF7777 100%);
// background-image: -moz-linear-gradient(top, #FF5555 0%, #FF7777 100%);
// background-image: -webkit-linear-gradient(top, #FF5555 0%, #FF7777 100%);
transform-origin: left;
-moz-transform-origin: left;
-webkit-transform-origin: left;
transition: transform 1s linear;
-moz-transition: -moz-transform 1s linear;
-webkit-transition: -webkit-transform 1s linear;
position: relative;
}
#card-front .wrap {
transition: background 1s linear;
-moz-transition: background 1s linear;
-webkit-transition: background 1s linear;
}
#card-front button {
position: absolute;
bottom: 1em;
right: -12px;
background: #F44;
color: #FFF;
font-family: 'Nobile', sans-serif;
font-style: italic;
font-weight: bold;
font-size: 1.5em;
padding: .5em;
border: none;
cursor: pointer;
box-shadow: 2px 2px 3px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .4);
-moz-box-shadow: 2px 2px 3px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .4);
-webkit-box-shadow: 2px 2px 3px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .4);
}
#card-front button:hover,
#card-front button:focus {
background: #F22;
}
#close {
display: none;
}
#card.open-fully #close,
#card-open-half #close {
display: inline;
}
#card.open-fully #open {
display: none;
}
#card.open-half #card-front,
#card.close-half #card-front {
transform: rotateY(-90deg);
-moz-transform: rotateY(-90deg);
-webkit-transform: rotateY(-90deg);
}
#card.open-half #card-front .wrap {
background-color: rgba(0, 0, 0, .5);
}
#card.open-fully #card-front,
#card.close-half #card-front {
background: #FFEFEF;
}
#card.open-fully #card-front {
transform: rotateY(-180deg);
-moz-transform: rotateY(-180deg);
-webkit-transform: rotateY(-180deg);
}
#card.open-fully #card-front .wrap {
background-color: rgba(0, 0, 0, 0);
}
#card.open-fully #card-front .wrap *,
#card.close-half #card-front .wrap * {
display: none;
}
footer {
max-width: 500px;
margin: 40px auto;
font-family: 'Nobile', sans-serif;
font-size: 14px;
line-height: 1.6;
color: #888;
text-align: center;
}
--card.js
(function () {
function $(id) {
return document.getElementById(id);
}
var card = $('card'),
openB = $('open'),
closeB = $('close'),
timer = null;
//console.log('wat', card);
debugger
openB.addEventListener('click', function () {
card.setAttribute('class', 'open-half');
if (timer) clearTimeout(timer);
timer = setTimeout(function () {
card.setAttribute('class', 'open-fully');
timer = null;
}, 1000);
});
closeB.addEventListener('click', function () {
card.setAttribute('class', 'close-half');
if (timer) clearTimerout(timer);
timer = setTimeout(function () {
card.setAttribute('class', '');
timer = null;
}, 1000);
});
}());
--ProductTemplateCustom.Simple.cshtml
@model ProductDetailsModel
@using Nop.Core.Domain.Seo;
@inject Nop.Core.IWebHelper webHelper
@inject SeoSettings seoSettings
@{
Layout = "_ColumnsOne";
//title
Html.AddTitleParts(!string.IsNullOrEmpty(Model.MetaTitle) ? Model.MetaTitle : Model.Name);
//meta
Html.AddMetaDescriptionParts(Model.MetaDescription);
Html.AddMetaKeywordParts(Model.MetaKeywords);
//page class
Html.AppendPageCssClassParts("html-product-details-page");
//canonical URL
if (seoSettings.CanonicalUrlsEnabled)
{
var productUrl = Url.RouteUrl("Product", new { SeName = Model.SeName }, webHelper.CurrentRequestProtocol).ToLowerInvariant();
Html.AddCanonicalUrlParts(productUrl, seoSettings.QueryStringInCanonicalUrlsEnabled);
}
//open graph META tags
if (seoSettings.OpenGraphMetaTags)
{
Html.AddHeadCustomParts("<meta property=\"og:type\" content=\"product\" />");
Html.AddHeadCustomParts("<meta property=\"og:title\" content=\"" + Html.Encode(Model.Name) + "\" />");
Html.AddHeadCustomParts("<meta property=\"og:description\" content=\"" + Html.Encode(Nop.Core.Html.HtmlHelper.StripTags(Model.MetaDescription)) + "\" />");
Html.AddHeadCustomParts("<meta property=\"og:image\" content=\"" + Model.DefaultPictureModel.ImageUrl + "\" />");
Html.AddHeadCustomParts("<meta property=\"og:image:url\" content=\"" + Model.DefaultPictureModel.ImageUrl + "\" />");
Html.AddHeadCustomParts("<meta property=\"og:url\" content=\"" + webHelper.GetThisPageUrl(false) + "\" />");
Html.AddHeadCustomParts("<meta property=\"og:site_name\" content=\"" + Html.Encode(Model.CurrentStoreName) + "\" />");
}
//Twitter META tags
if (seoSettings.TwitterMetaTags)
{
Html.AddHeadCustomParts("<meta property=\"twitter:card\" content=\"summary\" />");
Html.AddHeadCustomParts("<meta property=\"twitter:site\" content=\"" + Html.Encode(Model.CurrentStoreName) + "\" />");
Html.AddHeadCustomParts("<meta property=\"twitter:title\" content=\"" + Html.Encode(Model.Name) + "\" />");
Html.AddHeadCustomParts("<meta property=\"twitter:description\" content=\"" + Html.Encode(Nop.Core.Html.HtmlHelper.StripTags(Model.MetaDescription)) + "\" />");
Html.AddHeadCustomParts("<meta property=\"twitter:image\" content=\"" + Model.DefaultPictureModel.ImageUrl + "\" />");
Html.AddHeadCustomParts("<meta property=\"twitter:url\" content=\"" + webHelper.GetThisPageUrl(false) + "\" />");
}
}
<!--product breadcrumb-->
@section Breadcrumb
{
@await Html.PartialAsync("_ProductBreadcrumb", Model.Breadcrumb)
}
@await Component.InvokeAsync("Widget", new { widgetZone = PublicWidgetZones.ProductDetailsAfterBreadcrumb, additionalData = Model })
<div class="page product-details-page">
<div class="page-body">
<form asp-route="Product" asp-route-sename="@Model.SeName" method="post" id="product-details-form">
@if (seoSettings.MicrodataEnabled)
{
@await Html.PartialAsync("_Microdata", Model)
}
<div data-productid="@Model.Id">
<div class="product-essential">
<!--product pictures-->
@await Html.PartialAsync("_CardProductDetailsPictures", Model)
<div class="overview">
@await Html.PartialAsync("_Discontinued", Model)
<div class=”product-name” style=”background-color:yellow;border: 1px solid red; border-radius: 12px; padding:10px;”>
<h1 itemprop=”name”>
@Model.Name
</h1>
</div>
<!--attributes-->
<!--gift card-->
<!--price & add to cart & estimate shipping-->
<!--wishlist, compare, email a friend-->
<div class="overview-buttons">
</div>
</div>
@if (!string.IsNullOrEmpty(Model.FullDescription))
{
<div class="full-description">
@Html.Raw(Model.FullDescription)
</div>
}
</div>
<div class="product-collateral">xxx
</div>
</div>
</form>
</div>
</div>
-- _CardProductDetailsPictures.cshtml
@model ProductDetailsModel
<div class="gallery" style="height:300px">
@{
Html.AddCssFileParts(ResourceLocation.Head, "~/css/card/card.css");
}
<br />
<br />
<br />
<br />
<div id="card">
<div id="card-inside">
<div class="wrap">
<p>
@Html.Raw(Model.ShortDescription)
</p>
<p>always.</p>
<p><a href="http://pandey47.0fees.us/index4.html">NEXT</a></p>
<p class="signed">ZEF</p>
</div>
</div>
<div id="card-front" style=" background-image: url('@Model.DefaultPictureModel.ImageUrl')">
<div class="wrap">
</div>
<button id="open">></button>
<button id="close"><</button>
</div>
</div>
</div>
@{
Html.AppendScriptParts(ResourceLocation.Footer, "~/js/card.js");
}